refactor: Remove app_main.cc as the application entry point
- Deleted app_main.cc to streamline the project structure, as it is no longer needed. - Updated CMakeLists.txt to remove references to the deleted app_main.cc file, ensuring a clean build configuration.
This commit is contained in:
@@ -483,11 +483,6 @@ if (YAZE_BUILD_LIB)
|
|||||||
cli/service/gui/gui_automation_client.cc
|
cli/service/gui/gui_automation_client.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
# Application main entry point (uses controller and full dependencies)
|
|
||||||
set(YAZE_APP_MAIN_SOURCES
|
|
||||||
./app_main.cc
|
|
||||||
)
|
|
||||||
|
|
||||||
if(YAZE_USE_MODULAR_BUILD)
|
if(YAZE_USE_MODULAR_BUILD)
|
||||||
# Aggregate modular libraries into an interface target for backward compatibility
|
# Aggregate modular libraries into an interface target for backward compatibility
|
||||||
if(NOT TARGET yaze_core)
|
if(NOT TARGET yaze_core)
|
||||||
|
|||||||
@@ -810,7 +810,7 @@ void AgentChatWidget::Draw() {
|
|||||||
// Connection status bar at top (taller for better visibility)
|
// Connection status bar at top (taller for better visibility)
|
||||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||||
ImVec2 bar_start = ImGui::GetCursorScreenPos();
|
ImVec2 bar_start = ImGui::GetCursorScreenPos();
|
||||||
ImVec2 bar_size(ImGui::GetContentRegionAvail().x, 90); // Increased from 55
|
ImVec2 bar_size(ImGui::GetContentRegionAvail().x, 60); // Increased from 55
|
||||||
|
|
||||||
// Gradient background
|
// Gradient background
|
||||||
ImU32 color_top = ImGui::GetColorU32(ImVec4(0.18f, 0.22f, 0.28f, 1.0f));
|
ImU32 color_top = ImGui::GetColorU32(ImVec4(0.18f, 0.22f, 0.28f, 1.0f));
|
||||||
@@ -1046,8 +1046,17 @@ void AgentChatWidget::Draw() {
|
|||||||
ImVec2(4, 3)); // Compact padding
|
ImVec2(4, 3)); // Compact padding
|
||||||
|
|
||||||
// Removed RenderAgentConfigPanel - duplicates connection header
|
// Removed RenderAgentConfigPanel - duplicates connection header
|
||||||
|
if (ImGui::BeginTable("##commands_and_multimodal", 2, ImGuiTableFlags_BordersInnerV)) {
|
||||||
|
ImGui::TableSetupColumn("Commands", ImGuiTableColumnFlags_WidthFixed, 180);
|
||||||
|
ImGui::TableSetupColumn("Multimodal", ImGuiTableColumnFlags_WidthFixed, ImGui::GetContentRegionAvail().x - 180);
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
RenderZ3EDCommandPanel();
|
RenderZ3EDCommandPanel();
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
RenderMultimodalPanel();
|
RenderMultimodalPanel();
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
RenderCollaborationPanel();
|
RenderCollaborationPanel();
|
||||||
RenderRomSyncPanel();
|
RenderRomSyncPanel();
|
||||||
RenderProposalManagerPanel();
|
RenderProposalManagerPanel();
|
||||||
@@ -1068,6 +1077,10 @@ void AgentChatWidget::Draw() {
|
|||||||
void AgentChatWidget::RenderCollaborationPanel() {
|
void AgentChatWidget::RenderCollaborationPanel() {
|
||||||
ImGui::PushID("CollabPanel");
|
ImGui::PushID("CollabPanel");
|
||||||
|
|
||||||
|
// Tighter style for more content
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 3));
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3, 2));
|
||||||
|
|
||||||
// Update reactive status color
|
// Update reactive status color
|
||||||
const bool connected = collaboration_state_.active;
|
const bool connected = collaboration_state_.active;
|
||||||
collaboration_status_color_ = connected ? ImVec4(0.133f, 0.545f, 0.133f, 1.0f)
|
collaboration_status_color_ = connected ? ImVec4(0.133f, 0.545f, 0.133f, 1.0f)
|
||||||
@@ -1075,13 +1088,10 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
|
|
||||||
// Always visible (no collapsing header)
|
// Always visible (no collapsing header)
|
||||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.12f, 0.14f, 0.18f, 0.95f));
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.12f, 0.14f, 0.18f, 0.95f));
|
||||||
ImGui::BeginChild("CollabPanel", ImVec2(0, 200), true);
|
ImGui::BeginChild("CollabPanel", ImVec2(0, 140), true); // reduced height
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_PEOPLE " Collaboration");
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_PEOPLE " Collaboration");
|
||||||
ImGui::Separator();
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_SETTINGS_ETHERNET " Mode:");
|
||||||
// Mode selector (compact inline)
|
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
|
||||||
ICON_MD_SETTINGS_ETHERNET " Mode:");
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton(ICON_MD_FOLDER " Local##collab_mode_local",
|
ImGui::RadioButton(ICON_MD_FOLDER " Local##collab_mode_local",
|
||||||
reinterpret_cast<int*>(&collaboration_state_.mode),
|
reinterpret_cast<int*>(&collaboration_state_.mode),
|
||||||
@@ -1091,13 +1101,11 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
reinterpret_cast<int*>(&collaboration_state_.mode),
|
reinterpret_cast<int*>(&collaboration_state_.mode),
|
||||||
static_cast<int>(CollaborationMode::kNetwork));
|
static_cast<int>(CollaborationMode::kNetwork));
|
||||||
|
|
||||||
ImGui::Spacing();
|
|
||||||
|
|
||||||
// Main content in table layout (fixed size to prevent auto-resize)
|
// Main content in table layout (fixed size to prevent auto-resize)
|
||||||
if (ImGui::BeginTable("Collab_MainTable", 2, ImGuiTableFlags_BordersInnerV)) {
|
if (ImGui::BeginTable("Collab_MainTable", 2, ImGuiTableFlags_BordersInnerV)) {
|
||||||
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed, 180);
|
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthFixed, 150);
|
||||||
ImGui::TableSetupColumn("Controls", ImGuiTableColumnFlags_WidthFixed,
|
ImGui::TableSetupColumn("Controls", ImGuiTableColumnFlags_WidthFixed,
|
||||||
ImGui::GetContentRegionAvail().x - 180);
|
ImGui::GetContentRegionAvail().x - 150);
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
|
|
||||||
// LEFT COLUMN: Session Details
|
// LEFT COLUMN: Session Details
|
||||||
@@ -1106,10 +1114,9 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
ImGui::PushID("StatusColumn");
|
ImGui::PushID("StatusColumn");
|
||||||
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.15f, 0.2f, 0.18f, 0.4f));
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.15f, 0.2f, 0.18f, 0.4f));
|
||||||
ImGui::BeginChild("Collab_SessionDetails", ImVec2(0, 80), true);
|
ImGui::BeginChild("Collab_SessionDetails", ImVec2(0, 60), true); // reduced height
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
||||||
ICON_MD_INFO " Session Status:");
|
ICON_MD_INFO " Session:");
|
||||||
ImGui::Spacing();
|
|
||||||
if (connected) {
|
if (connected) {
|
||||||
ImGui::TextColored(collaboration_status_color_,
|
ImGui::TextColored(collaboration_status_color_,
|
||||||
ICON_MD_CHECK_CIRCLE " Connected");
|
ICON_MD_CHECK_CIRCLE " Connected");
|
||||||
@@ -1118,72 +1125,55 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (collaboration_state_.mode == CollaborationMode::kNetwork) {
|
if (collaboration_state_.mode == CollaborationMode::kNetwork) {
|
||||||
ImGui::Spacing();
|
|
||||||
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
|
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
|
||||||
ICON_MD_CLOUD " Server:");
|
ICON_MD_CLOUD " Server:");
|
||||||
ImGui::TextWrapped("%s", collaboration_state_.server_url.c_str());
|
ImGui::TextUnformatted(collaboration_state_.server_url.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!collaboration_state_.session_name.empty()) {
|
if (!collaboration_state_.session_name.empty()) {
|
||||||
ImGui::Spacing();
|
|
||||||
ImGui::TextColored(collaboration_status_color_,
|
ImGui::TextColored(collaboration_status_color_,
|
||||||
ICON_MD_LABEL " Session:");
|
ICON_MD_LABEL " %s", collaboration_state_.session_name.c_str());
|
||||||
ImGui::TextWrapped("%s", collaboration_state_.session_name.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!collaboration_state_.session_id.empty()) {
|
if (!collaboration_state_.session_id.empty()) {
|
||||||
ImGui::Spacing();
|
|
||||||
ImGui::TextColored(collaboration_status_color_,
|
ImGui::TextColored(collaboration_status_color_,
|
||||||
ICON_MD_KEY " Session Code:");
|
ICON_MD_KEY " %s", collaboration_state_.session_id.c_str());
|
||||||
ImGui::TextWrapped("%s", collaboration_state_.session_id.c_str());
|
ImGui::SameLine();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.4f, 0.4f, 0.6f, 0.6f));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.4f, 0.4f, 0.6f, 0.6f));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
|
||||||
ImVec4(0.416f, 0.353f, 0.804f, 1.0f));
|
ImVec4(0.416f, 0.353f, 0.804f, 1.0f));
|
||||||
if (ImGui::Button(ICON_MD_CONTENT_COPY " Copy##copy_session_id")) {
|
if (ImGui::SmallButton(ICON_MD_CONTENT_COPY "##copy_session_id")) {
|
||||||
ImGui::SetClipboardText(collaboration_state_.session_id.c_str());
|
ImGui::SetClipboardText(collaboration_state_.session_id.c_str());
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Session code copied!", ToastType::kSuccess,
|
toast_manager_->Show("Session code copied!", ToastType::kSuccess, 2.0f);
|
||||||
2.0f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collaboration_state_.last_synced != absl::InfinitePast()) {
|
if (collaboration_state_.last_synced != absl::InfinitePast()) {
|
||||||
ImGui::Spacing();
|
|
||||||
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f),
|
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f),
|
||||||
ICON_MD_ACCESS_TIME " Last sync:");
|
ICON_MD_ACCESS_TIME " %s",
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored(
|
|
||||||
ImVec4(0.5f, 0.5f, 0.5f, 1.0f), "%s",
|
|
||||||
absl::FormatTime("%H:%M:%S", collaboration_state_.last_synced,
|
absl::FormatTime("%H:%M:%S", collaboration_state_.last_synced,
|
||||||
absl::LocalTimeZone())
|
absl::LocalTimeZone()).c_str());
|
||||||
.c_str());
|
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
ImGui::Spacing();
|
|
||||||
|
|
||||||
// Participants list below session details
|
// Participants list below session details
|
||||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.12f, 0.16f, 0.14f, 0.4f));
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.12f, 0.16f, 0.14f, 0.4f));
|
||||||
ImGui::BeginChild("Collab_ParticipantsList", ImVec2(0, 0), true);
|
ImGui::BeginChild("Collab_ParticipantsList", ImVec2(0, 0), true);
|
||||||
{
|
|
||||||
if (collaboration_state_.participants.empty()) {
|
if (collaboration_state_.participants.empty()) {
|
||||||
ImGui::TextDisabled(ICON_MD_PEOPLE " No participants yet");
|
ImGui::TextDisabled(ICON_MD_PEOPLE " No participants");
|
||||||
} else {
|
} else {
|
||||||
ImGui::TextColored(collaboration_status_color_,
|
ImGui::TextColored(collaboration_status_color_,
|
||||||
ICON_MD_PEOPLE " Participants (%zu):",
|
ICON_MD_PEOPLE " %zu", collaboration_state_.participants.size());
|
||||||
collaboration_state_.participants.size());
|
|
||||||
ImGui::Separator();
|
|
||||||
for (size_t i = 0; i < collaboration_state_.participants.size(); ++i) {
|
for (size_t i = 0; i < collaboration_state_.participants.size(); ++i) {
|
||||||
ImGui::PushID(static_cast<int>(i));
|
ImGui::PushID(static_cast<int>(i));
|
||||||
ImGui::BulletText(ICON_MD_PERSON " %s",
|
ImGui::BulletText("%s", collaboration_state_.participants[i].c_str());
|
||||||
collaboration_state_.participants[i].c_str());
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
@@ -1196,8 +1186,6 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
ImGui::PushID("ControlsColumn");
|
ImGui::PushID("ControlsColumn");
|
||||||
ImGui::BeginChild("Collab_Controls", ImVec2(0, 0), false);
|
ImGui::BeginChild("Collab_Controls", ImVec2(0, 0), false);
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
const bool can_host =
|
const bool can_host =
|
||||||
static_cast<bool>(collaboration_callbacks_.host_session);
|
static_cast<bool>(collaboration_callbacks_.host_session);
|
||||||
const bool can_join =
|
const bool can_join =
|
||||||
@@ -1209,67 +1197,52 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
|
|
||||||
// Network mode: Show server URL input with styling
|
// Network mode: Show server URL input with styling
|
||||||
if (collaboration_state_.mode == CollaborationMode::kNetwork) {
|
if (collaboration_state_.mode == CollaborationMode::kNetwork) {
|
||||||
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
|
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f), ICON_MD_CLOUD);
|
||||||
ICON_MD_CLOUD " Server URL:");
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(-80);
|
ImGui::SetNextItemWidth(100);
|
||||||
ImGui::InputText("##collab_server_url", server_url_buffer_,
|
ImGui::InputText("##collab_server_url", server_url_buffer_, IM_ARRAYSIZE(server_url_buffer_));
|
||||||
IM_ARRAYSIZE(server_url_buffer_));
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.15f, 0.5f, 0.7f, 0.8f));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.15f, 0.5f, 0.7f, 0.8f));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.196f, 0.6f, 0.8f, 1.0f));
|
||||||
ImVec4(0.196f, 0.6f, 0.8f, 1.0f));
|
if (ImGui::SmallButton(ICON_MD_LINK "##connect_server_btn")) {
|
||||||
if (ImGui::Button(ICON_MD_LINK "##connect_server_btn")) {
|
|
||||||
collaboration_state_.server_url = server_url_buffer_;
|
collaboration_state_.server_url = server_url_buffer_;
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Connecting to server...", ToastType::kInfo,
|
toast_manager_->Show("Connecting to server...", ToastType::kInfo, 3.0f);
|
||||||
3.0f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("Connect to collaboration server");
|
ImGui::SetTooltip("Connect to collaboration server");
|
||||||
}
|
}
|
||||||
ImGui::Separator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
// Host session
|
||||||
ICON_MD_ADD_CIRCLE " Host New Session:");
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_ADD_CIRCLE);
|
||||||
ImGui::SetNextItemWidth(-70);
|
|
||||||
ImGui::InputTextWithHint("##collab_session_name", "Enter session name...",
|
|
||||||
session_name_buffer_,
|
|
||||||
IM_ARRAYSIZE(session_name_buffer_));
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (!can_host)
|
ImGui::SetNextItemWidth(100);
|
||||||
ImGui::BeginDisabled();
|
ImGui::InputTextWithHint("##collab_session_name", "Session name...", session_name_buffer_, IM_ARRAYSIZE(session_name_buffer_));
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (!can_host) ImGui::BeginDisabled();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.6f, 0.5f, 0.0f, 0.8f));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.6f, 0.5f, 0.0f, 0.8f));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0.843f, 0.0f, 1.0f));
|
||||||
ImVec4(1.0f, 0.843f, 0.0f, 1.0f));
|
if (ImGui::SmallButton(ICON_MD_ROCKET_LAUNCH "##host_session_btn")) {
|
||||||
if (ImGui::Button(ICON_MD_ROCKET_LAUNCH "##host_session_btn")) {
|
|
||||||
std::string name = session_name_buffer_;
|
std::string name = session_name_buffer_;
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Enter a session name first",
|
toast_manager_->Show("Enter a session name first", ToastType::kWarning, 3.0f);
|
||||||
ToastType::kWarning, 3.0f);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto session_or = collaboration_callbacks_.host_session(name);
|
auto session_or = collaboration_callbacks_.host_session(name);
|
||||||
if (session_or.ok()) {
|
if (session_or.ok()) {
|
||||||
ApplyCollaborationSession(session_or.value(),
|
ApplyCollaborationSession(session_or.value(), /*update_action_timestamp=*/true);
|
||||||
/*update_action_timestamp=*/true);
|
std::snprintf(join_code_buffer_, sizeof(join_code_buffer_), "%s", collaboration_state_.session_id.c_str());
|
||||||
std::snprintf(join_code_buffer_, sizeof(join_code_buffer_), "%s",
|
|
||||||
collaboration_state_.session_id.c_str());
|
|
||||||
session_name_buffer_[0] = '\0';
|
session_name_buffer_[0] = '\0';
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show(
|
toast_manager_->Show(absl::StrFormat("Hosting session %s", collaboration_state_.session_id.c_str()), ToastType::kSuccess, 3.5f);
|
||||||
absl::StrFormat("Hosting session %s",
|
|
||||||
collaboration_state_.session_id.c_str()),
|
|
||||||
ToastType::kSuccess, 3.5f);
|
|
||||||
}
|
}
|
||||||
MarkHistoryDirty();
|
MarkHistoryDirty();
|
||||||
} else if (toast_manager_) {
|
} else if (toast_manager_) {
|
||||||
toast_manager_->Show(absl::StrFormat("Failed to host: %s",
|
toast_manager_->Show(absl::StrFormat("Failed to host: %s", session_or.status().message()), ToastType::kError, 5.0f);
|
||||||
session_or.status().message()),
|
|
||||||
ToastType::kError, 5.0f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1283,44 +1256,32 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
ImGui::SetTooltip("Host a new collaboration session");
|
ImGui::SetTooltip("Host a new collaboration session");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
// Join session
|
||||||
ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f),
|
ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_LOGIN);
|
||||||
ICON_MD_LOGIN " Join Existing Session:");
|
|
||||||
ImGui::SetNextItemWidth(-70);
|
|
||||||
ImGui::InputTextWithHint("##collab_join_code", "Enter session code...",
|
|
||||||
join_code_buffer_,
|
|
||||||
IM_ARRAYSIZE(join_code_buffer_));
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (!can_join)
|
ImGui::SetNextItemWidth(100);
|
||||||
ImGui::BeginDisabled();
|
ImGui::InputTextWithHint("##collab_join_code", "Session code...", join_code_buffer_, IM_ARRAYSIZE(join_code_buffer_));
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (!can_join) ImGui::BeginDisabled();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.4f, 0.1f, 0.8f));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.1f, 0.4f, 0.1f, 0.8f));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.133f, 0.545f, 0.133f, 1.0f));
|
||||||
ImVec4(0.133f, 0.545f, 0.133f, 1.0f));
|
if (ImGui::SmallButton(ICON_MD_MEETING_ROOM "##join_session_btn")) {
|
||||||
if (ImGui::Button(ICON_MD_MEETING_ROOM "##join_session_btn")) {
|
|
||||||
std::string code = join_code_buffer_;
|
std::string code = join_code_buffer_;
|
||||||
if (code.empty()) {
|
if (code.empty()) {
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Enter a session code first",
|
toast_manager_->Show("Enter a session code first", ToastType::kWarning, 3.0f);
|
||||||
ToastType::kWarning, 3.0f);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto session_or = collaboration_callbacks_.join_session(code);
|
auto session_or = collaboration_callbacks_.join_session(code);
|
||||||
if (session_or.ok()) {
|
if (session_or.ok()) {
|
||||||
ApplyCollaborationSession(session_or.value(),
|
ApplyCollaborationSession(session_or.value(), /*update_action_timestamp=*/true);
|
||||||
/*update_action_timestamp=*/true);
|
std::snprintf(join_code_buffer_, sizeof(join_code_buffer_), "%s", collaboration_state_.session_id.c_str());
|
||||||
std::snprintf(join_code_buffer_, sizeof(join_code_buffer_), "%s",
|
|
||||||
collaboration_state_.session_id.c_str());
|
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show(
|
toast_manager_->Show(absl::StrFormat("Joined session %s", collaboration_state_.session_id.c_str()), ToastType::kSuccess, 3.5f);
|
||||||
absl::StrFormat("Joined session %s",
|
|
||||||
collaboration_state_.session_id.c_str()),
|
|
||||||
ToastType::kSuccess, 3.5f);
|
|
||||||
}
|
}
|
||||||
MarkHistoryDirty();
|
MarkHistoryDirty();
|
||||||
} else if (toast_manager_) {
|
} else if (toast_manager_) {
|
||||||
toast_manager_->Show(absl::StrFormat("Failed to join: %s",
|
toast_manager_->Show(absl::StrFormat("Failed to join: %s", session_or.status().message()), ToastType::kError, 5.0f);
|
||||||
session_or.status().message()),
|
|
||||||
ToastType::kError, 5.0f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1334,17 +1295,12 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
ImGui::SetTooltip("Join an existing collaboration session");
|
ImGui::SetTooltip("Join an existing collaboration session");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Leave/Refresh
|
||||||
if (collaboration_state_.active) {
|
if (collaboration_state_.active) {
|
||||||
ImGui::Separator();
|
if (!can_leave) ImGui::BeginDisabled();
|
||||||
ImGui::Spacing();
|
|
||||||
|
|
||||||
if (!can_leave)
|
|
||||||
ImGui::BeginDisabled();
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.7f, 0.2f, 0.2f, 0.8f));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.7f, 0.2f, 0.2f, 0.8f));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.863f, 0.078f, 0.235f, 1.0f));
|
||||||
ImVec4(0.863f, 0.078f, 0.235f, 1.0f));
|
if (ImGui::SmallButton(ICON_MD_LOGOUT "##leave_session_btn")) {
|
||||||
if (ImGui::Button(ICON_MD_LOGOUT " Leave Session##leave_session_btn",
|
|
||||||
ImVec2(-1, 0))) {
|
|
||||||
absl::Status status = collaboration_callbacks_.leave_session
|
absl::Status status = collaboration_callbacks_.leave_session
|
||||||
? collaboration_callbacks_.leave_session()
|
? collaboration_callbacks_.leave_session()
|
||||||
: absl::OkStatus();
|
: absl::OkStatus();
|
||||||
@@ -1352,42 +1308,30 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
collaboration_state_ = CollaborationState{};
|
collaboration_state_ = CollaborationState{};
|
||||||
join_code_buffer_[0] = '\0';
|
join_code_buffer_[0] = '\0';
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Left collaborative session", ToastType::kInfo,
|
toast_manager_->Show("Left collaborative session", ToastType::kInfo, 3.0f);
|
||||||
3.0f);
|
|
||||||
}
|
}
|
||||||
MarkHistoryDirty();
|
MarkHistoryDirty();
|
||||||
} else if (toast_manager_) {
|
} else if (toast_manager_) {
|
||||||
toast_manager_->Show(
|
toast_manager_->Show(absl::StrFormat("Failed to leave: %s", status.message()), ToastType::kError, 5.0f);
|
||||||
absl::StrFormat("Failed to leave: %s", status.message()),
|
|
||||||
ToastType::kError, 5.0f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
if (!can_leave)
|
if (!can_leave) ImGui::EndDisabled();
|
||||||
ImGui::EndDisabled();
|
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::SameLine();
|
||||||
ImGui::Separator();
|
if (!can_refresh) ImGui::BeginDisabled();
|
||||||
if (!can_refresh)
|
|
||||||
ImGui::BeginDisabled();
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.4f, 0.4f, 0.6f, 0.8f));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.4f, 0.4f, 0.6f, 0.8f));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.416f, 0.353f, 0.804f, 1.0f));
|
||||||
ImVec4(0.416f, 0.353f, 0.804f, 1.0f));
|
if (ImGui::SmallButton(ICON_MD_REFRESH "##refresh_collab_btn")) {
|
||||||
if (ImGui::Button(ICON_MD_REFRESH " Refresh Session##refresh_collab_btn",
|
|
||||||
ImVec2(-1, 0))) {
|
|
||||||
RefreshCollaboration();
|
RefreshCollaboration();
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
if (!can_refresh &&
|
if (!can_refresh && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||||
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
|
||||||
ImGui::SetTooltip("Provide refresh_session callback to enable");
|
ImGui::SetTooltip("Provide refresh_session callback to enable");
|
||||||
}
|
}
|
||||||
if (!can_refresh)
|
if (!can_refresh) ImGui::EndDisabled();
|
||||||
ImGui::EndDisabled();
|
|
||||||
} else {
|
} else {
|
||||||
ImGui::Spacing();
|
ImGui::TextDisabled(ICON_MD_INFO " Start or join a session to collaborate.");
|
||||||
ImGui::TextDisabled(ICON_MD_INFO
|
|
||||||
" Start or join a session to collaborate.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndChild(); // Collab_Controls
|
ImGui::EndChild(); // Collab_Controls
|
||||||
@@ -1398,6 +1342,7 @@ void AgentChatWidget::RenderCollaborationPanel() {
|
|||||||
|
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
ImGui::PopID(); // CollabPanel
|
ImGui::PopID(); // CollabPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1810,7 +1755,7 @@ void AgentChatWidget::RenderZ3EDCommandPanel() {
|
|||||||
|
|
||||||
void AgentChatWidget::RenderRomSyncPanel() {
|
void AgentChatWidget::RenderRomSyncPanel() {
|
||||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.18f, 0.14f, 0.12f, 1.0f));
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.18f, 0.14f, 0.12f, 1.0f));
|
||||||
ImGui::BeginChild("RomSync", ImVec2(0, 200), true);
|
ImGui::BeginChild("RomSync", ImVec2(0, 100), true);
|
||||||
|
|
||||||
ImGui::Text(ICON_MD_STORAGE " ROM State");
|
ImGui::Text(ICON_MD_STORAGE " ROM State");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "absl/strings/str_format.h"
|
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
|
#include "absl/strings/str_format.h"
|
||||||
#include "absl/time/clock.h"
|
#include "absl/time/clock.h"
|
||||||
|
#include "app/core/platform/asset_loader.h"
|
||||||
#include "app/editor/agent/agent_chat_widget.h"
|
#include "app/editor/agent/agent_chat_widget.h"
|
||||||
#include "app/editor/agent/agent_collaboration_coordinator.h"
|
#include "app/editor/agent/agent_collaboration_coordinator.h"
|
||||||
#include "app/editor/system/proposal_drawer.h"
|
#include "app/editor/system/proposal_drawer.h"
|
||||||
#include "app/editor/system/toast_manager.h"
|
#include "app/editor/system/toast_manager.h"
|
||||||
#include "app/rom.h"
|
|
||||||
#include "app/gui/icons.h"
|
#include "app/gui/icons.h"
|
||||||
#include "app/core/platform/asset_loader.h"
|
#include "app/rom.h"
|
||||||
#include "util/file_util.h"
|
#include "util/file_util.h"
|
||||||
|
|
||||||
#ifdef YAZE_WITH_GRPC
|
#ifdef YAZE_WITH_GRPC
|
||||||
@@ -49,11 +49,13 @@ AgentEditor::AgentEditor() {
|
|||||||
current_profile_.tags = {"default", "z3ed"};
|
current_profile_.tags = {"default", "z3ed"};
|
||||||
|
|
||||||
// Setup text editors
|
// Setup text editors
|
||||||
prompt_editor_->SetLanguageDefinition(TextEditor::LanguageDefinition::CPlusPlus());
|
prompt_editor_->SetLanguageDefinition(
|
||||||
|
TextEditor::LanguageDefinition::CPlusPlus());
|
||||||
prompt_editor_->SetReadOnly(false);
|
prompt_editor_->SetReadOnly(false);
|
||||||
prompt_editor_->SetShowWhitespaces(false);
|
prompt_editor_->SetShowWhitespaces(false);
|
||||||
|
|
||||||
common_tiles_editor_->SetLanguageDefinition(TextEditor::LanguageDefinition::CPlusPlus());
|
common_tiles_editor_->SetLanguageDefinition(
|
||||||
|
TextEditor::LanguageDefinition::CPlusPlus());
|
||||||
common_tiles_editor_->SetReadOnly(false);
|
common_tiles_editor_->SetReadOnly(false);
|
||||||
common_tiles_editor_->SetShowWhitespaces(false);
|
common_tiles_editor_->SetShowWhitespaces(false);
|
||||||
|
|
||||||
@@ -73,7 +75,8 @@ absl::Status AgentEditor::Load() {
|
|||||||
// Try to load all bot profiles
|
// Try to load all bot profiles
|
||||||
auto profiles_dir = GetProfilesDirectory();
|
auto profiles_dir = GetProfilesDirectory();
|
||||||
if (std::filesystem::exists(profiles_dir)) {
|
if (std::filesystem::exists(profiles_dir)) {
|
||||||
for (const auto& entry : std::filesystem::directory_iterator(profiles_dir)) {
|
for (const auto& entry :
|
||||||
|
std::filesystem::directory_iterator(profiles_dir)) {
|
||||||
if (entry.path().extension() == ".json") {
|
if (entry.path().extension() == ".json") {
|
||||||
std::ifstream file(entry.path());
|
std::ifstream file(entry.path());
|
||||||
if (file.is_open()) {
|
if (file.is_open()) {
|
||||||
@@ -96,7 +99,8 @@ absl::Status AgentEditor::Save() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
absl::Status AgentEditor::Update() {
|
absl::Status AgentEditor::Update() {
|
||||||
if (!active_) return absl::OkStatus();
|
if (!active_)
|
||||||
|
return absl::OkStatus();
|
||||||
|
|
||||||
// Draw configuration dashboard
|
// Draw configuration dashboard
|
||||||
DrawDashboard();
|
DrawDashboard();
|
||||||
@@ -133,10 +137,12 @@ void AgentEditor::SetRomContext(Rom* rom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawDashboard() {
|
void AgentEditor::DrawDashboard() {
|
||||||
if (!active_) return;
|
if (!active_)
|
||||||
|
return;
|
||||||
|
|
||||||
ImGui::SetNextWindowSize(ImVec2(1200, 800), ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2(1200, 800), ImGuiCond_FirstUseEver);
|
||||||
ImGui::Begin(ICON_MD_SMART_TOY " AI Agent Platform & Bot Creator", &active_, ImGuiWindowFlags_MenuBar);
|
ImGui::Begin(ICON_MD_SMART_TOY " AI Agent Platform & Bot Creator", &active_,
|
||||||
|
ImGuiWindowFlags_MenuBar);
|
||||||
|
|
||||||
// Menu bar
|
// Menu bar
|
||||||
if (ImGui::BeginMenuBar()) {
|
if (ImGui::BeginMenuBar()) {
|
||||||
@@ -150,13 +156,15 @@ void AgentEditor::DrawDashboard() {
|
|||||||
if (ImGui::MenuItem(ICON_MD_FILE_UPLOAD " Export Profile...")) {
|
if (ImGui::MenuItem(ICON_MD_FILE_UPLOAD " Export Profile...")) {
|
||||||
// TODO: Open file dialog for export
|
// TODO: Open file dialog for export
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Export functionality coming soon", ToastType::kInfo);
|
toast_manager_->Show("Export functionality coming soon",
|
||||||
|
ToastType::kInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem(ICON_MD_FILE_DOWNLOAD " Import Profile...")) {
|
if (ImGui::MenuItem(ICON_MD_FILE_DOWNLOAD " Import Profile...")) {
|
||||||
// TODO: Open file dialog for import
|
// TODO: Open file dialog for import
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Import functionality coming soon", ToastType::kInfo);
|
toast_manager_->Show("Import functionality coming soon",
|
||||||
|
ToastType::kInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
@@ -167,10 +175,14 @@ void AgentEditor::DrawDashboard() {
|
|||||||
OpenChatWindow();
|
OpenChatWindow();
|
||||||
}
|
}
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::MenuItem(ICON_MD_EDIT " Show Prompt Editor", nullptr, &show_prompt_editor_);
|
ImGui::MenuItem(ICON_MD_EDIT " Show Prompt Editor", nullptr,
|
||||||
ImGui::MenuItem(ICON_MD_FOLDER " Show Bot Profiles", nullptr, &show_bot_profiles_);
|
&show_prompt_editor_);
|
||||||
ImGui::MenuItem(ICON_MD_HISTORY " Show Chat History", nullptr, &show_chat_history_);
|
ImGui::MenuItem(ICON_MD_FOLDER " Show Bot Profiles", nullptr,
|
||||||
ImGui::MenuItem(ICON_MD_ANALYTICS " Show Metrics Dashboard", nullptr, &show_metrics_dashboard_);
|
&show_bot_profiles_);
|
||||||
|
ImGui::MenuItem(ICON_MD_HISTORY " Show Chat History", nullptr,
|
||||||
|
&show_chat_history_);
|
||||||
|
ImGui::MenuItem(ICON_MD_ANALYTICS " Show Metrics Dashboard", nullptr,
|
||||||
|
&show_metrics_dashboard_);
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,9 +201,11 @@ void AgentEditor::DrawDashboard() {
|
|||||||
ImGuiTableFlags_SizingStretchProp;
|
ImGuiTableFlags_SizingStretchProp;
|
||||||
|
|
||||||
if (ImGui::BeginTable("BotStudioLayout", 3, table_flags)) {
|
if (ImGui::BeginTable("BotStudioLayout", 3, table_flags)) {
|
||||||
ImGui::TableSetupColumn("Settings", ImGuiTableColumnFlags_WidthFixed, 320.0f);
|
ImGui::TableSetupColumn("Settings", ImGuiTableColumnFlags_WidthFixed,
|
||||||
|
320.0f);
|
||||||
ImGui::TableSetupColumn("Editors", ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("Editors", ImGuiTableColumnFlags_WidthStretch);
|
||||||
ImGui::TableSetupColumn("Profiles", ImGuiTableColumnFlags_WidthFixed, 280.0f);
|
ImGui::TableSetupColumn("Profiles", ImGuiTableColumnFlags_WidthFixed,
|
||||||
|
280.0f);
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
|
|
||||||
// Column 1: AI Provider, Behavior, ROM, Tips, Metrics (merged!)
|
// Column 1: AI Provider, Behavior, ROM, Tips, Metrics (merged!)
|
||||||
@@ -249,9 +263,13 @@ void AgentEditor::DrawDashboard() {
|
|||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
// Two-column layout
|
// Two-column layout
|
||||||
if (ImGui::BeginTable("SessionLayout", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInnerV)) {
|
if (ImGui::BeginTable(
|
||||||
ImGui::TableSetupColumn("History", ImGuiTableColumnFlags_WidthStretch, 0.6f);
|
"SessionLayout", 2,
|
||||||
ImGui::TableSetupColumn("Metrics", ImGuiTableColumnFlags_WidthStretch, 0.4f);
|
ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInnerV)) {
|
||||||
|
ImGui::TableSetupColumn("History", ImGuiTableColumnFlags_WidthStretch,
|
||||||
|
0.6f);
|
||||||
|
ImGui::TableSetupColumn("Metrics", ImGuiTableColumnFlags_WidthStretch,
|
||||||
|
0.4f);
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
|
|
||||||
// LEFT: Chat History
|
// LEFT: Chat History
|
||||||
@@ -275,18 +293,12 @@ void AgentEditor::DrawDashboard() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawConfigurationPanel() {
|
void AgentEditor::DrawConfigurationPanel() {
|
||||||
// Two-column layout
|
|
||||||
if (ImGui::BeginTable("ConfigLayout", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInnerV)) {
|
|
||||||
ImGui::TableSetupColumn("Settings", ImGuiTableColumnFlags_WidthStretch, 0.6f);
|
|
||||||
ImGui::TableSetupColumn("Status", ImGuiTableColumnFlags_WidthStretch, 0.4f);
|
|
||||||
ImGui::TableNextRow();
|
|
||||||
|
|
||||||
// LEFT: Configuration
|
|
||||||
ImGui::TableSetColumnIndex(0);
|
|
||||||
|
|
||||||
// AI Provider Configuration
|
// AI Provider Configuration
|
||||||
if (ImGui::CollapsingHeader(ICON_MD_SETTINGS " AI Provider", ImGuiTreeNodeFlags_DefaultOpen)) {
|
if (ImGui::CollapsingHeader(ICON_MD_SETTINGS " AI Provider",
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_SMART_TOY " Provider Selection");
|
ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
||||||
|
ICON_MD_SMART_TOY " Provider Selection");
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
// Provider buttons (large, visual)
|
// Provider buttons (large, visual)
|
||||||
@@ -296,51 +308,63 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
bool is_ollama = (current_profile_.provider == "ollama");
|
bool is_ollama = (current_profile_.provider == "ollama");
|
||||||
bool is_gemini = (current_profile_.provider == "gemini");
|
bool is_gemini = (current_profile_.provider == "gemini");
|
||||||
|
|
||||||
if (is_mock) ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.6f, 0.6f, 0.6f, 0.8f));
|
if (is_mock)
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.6f, 0.6f, 0.6f, 0.8f));
|
||||||
if (ImGui::Button(ICON_MD_SETTINGS " Mock", button_size)) {
|
if (ImGui::Button(ICON_MD_SETTINGS " Mock", button_size)) {
|
||||||
current_profile_.provider = "mock";
|
current_profile_.provider = "mock";
|
||||||
}
|
}
|
||||||
if (is_mock) ImGui::PopStyleColor();
|
if (is_mock)
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (is_ollama) ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.8f, 0.4f, 0.8f));
|
if (is_ollama)
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.8f, 0.4f, 0.8f));
|
||||||
if (ImGui::Button(ICON_MD_CLOUD " Ollama", button_size)) {
|
if (ImGui::Button(ICON_MD_CLOUD " Ollama", button_size)) {
|
||||||
current_profile_.provider = "ollama";
|
current_profile_.provider = "ollama";
|
||||||
}
|
}
|
||||||
if (is_ollama) ImGui::PopStyleColor();
|
if (is_ollama)
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (is_gemini) ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.196f, 0.6f, 0.8f, 0.8f));
|
if (is_gemini)
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.196f, 0.6f, 0.8f, 0.8f));
|
||||||
if (ImGui::Button(ICON_MD_SMART_TOY " Gemini", button_size)) {
|
if (ImGui::Button(ICON_MD_SMART_TOY " Gemini", button_size)) {
|
||||||
current_profile_.provider = "gemini";
|
current_profile_.provider = "gemini";
|
||||||
}
|
}
|
||||||
if (is_gemini) ImGui::PopStyleColor();
|
if (is_gemini)
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
// Provider-specific settings
|
// Provider-specific settings
|
||||||
if (current_profile_.provider == "ollama") {
|
if (current_profile_.provider == "ollama") {
|
||||||
ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.4f, 1.0f), ICON_MD_SETTINGS " Ollama Settings");
|
ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.4f, 1.0f),
|
||||||
|
ICON_MD_SETTINGS " Ollama Settings");
|
||||||
ImGui::Text("Model:");
|
ImGui::Text("Model:");
|
||||||
ImGui::SetNextItemWidth(-1);
|
ImGui::SetNextItemWidth(-1);
|
||||||
static char model_buf[128] = "qwen2.5-coder:7b";
|
static char model_buf[128] = "qwen2.5-coder:7b";
|
||||||
if (!current_profile_.model.empty()) {
|
if (!current_profile_.model.empty()) {
|
||||||
strncpy(model_buf, current_profile_.model.c_str(), sizeof(model_buf) - 1);
|
strncpy(model_buf, current_profile_.model.c_str(),
|
||||||
|
sizeof(model_buf) - 1);
|
||||||
}
|
}
|
||||||
if (ImGui::InputTextWithHint("##ollama_model", "e.g., qwen2.5-coder:7b, llama3.2", model_buf, sizeof(model_buf))) {
|
if (ImGui::InputTextWithHint("##ollama_model",
|
||||||
|
"e.g., qwen2.5-coder:7b, llama3.2",
|
||||||
|
model_buf, sizeof(model_buf))) {
|
||||||
current_profile_.model = model_buf;
|
current_profile_.model = model_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Text("Host URL:");
|
ImGui::Text("Host URL:");
|
||||||
ImGui::SetNextItemWidth(-1);
|
ImGui::SetNextItemWidth(-1);
|
||||||
static char host_buf[256] = "http://localhost:11434";
|
static char host_buf[256] = "http://localhost:11434";
|
||||||
strncpy(host_buf, current_profile_.ollama_host.c_str(), sizeof(host_buf) - 1);
|
strncpy(host_buf, current_profile_.ollama_host.c_str(),
|
||||||
|
sizeof(host_buf) - 1);
|
||||||
if (ImGui::InputText("##ollama_host", host_buf, sizeof(host_buf))) {
|
if (ImGui::InputText("##ollama_host", host_buf, sizeof(host_buf))) {
|
||||||
current_profile_.ollama_host = host_buf;
|
current_profile_.ollama_host = host_buf;
|
||||||
}
|
}
|
||||||
} else if (current_profile_.provider == "gemini") {
|
} else if (current_profile_.provider == "gemini") {
|
||||||
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f), ICON_MD_SMART_TOY " Gemini Settings");
|
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
|
||||||
|
ICON_MD_SMART_TOY " Gemini Settings");
|
||||||
|
|
||||||
// Load from environment button
|
// Load from environment button
|
||||||
if (ImGui::Button(ICON_MD_REFRESH " Load from Environment")) {
|
if (ImGui::Button(ICON_MD_REFRESH " Load from Environment")) {
|
||||||
@@ -353,7 +377,8 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("GEMINI_API_KEY not found", ToastType::kWarning);
|
toast_manager_->Show("GEMINI_API_KEY not found",
|
||||||
|
ToastType::kWarning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,9 +389,11 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
ImGui::SetNextItemWidth(-1);
|
ImGui::SetNextItemWidth(-1);
|
||||||
static char model_buf[128] = "gemini-1.5-flash";
|
static char model_buf[128] = "gemini-1.5-flash";
|
||||||
if (!current_profile_.model.empty()) {
|
if (!current_profile_.model.empty()) {
|
||||||
strncpy(model_buf, current_profile_.model.c_str(), sizeof(model_buf) - 1);
|
strncpy(model_buf, current_profile_.model.c_str(),
|
||||||
|
sizeof(model_buf) - 1);
|
||||||
}
|
}
|
||||||
if (ImGui::InputTextWithHint("##gemini_model", "e.g., gemini-1.5-flash", model_buf, sizeof(model_buf))) {
|
if (ImGui::InputTextWithHint("##gemini_model", "e.g., gemini-1.5-flash",
|
||||||
|
model_buf, sizeof(model_buf))) {
|
||||||
current_profile_.model = model_buf;
|
current_profile_.model = model_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,13 +401,16 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
ImGui::SetNextItemWidth(-1);
|
ImGui::SetNextItemWidth(-1);
|
||||||
static char key_buf[256] = "";
|
static char key_buf[256] = "";
|
||||||
if (!current_profile_.gemini_api_key.empty() && key_buf[0] == '\0') {
|
if (!current_profile_.gemini_api_key.empty() && key_buf[0] == '\0') {
|
||||||
strncpy(key_buf, current_profile_.gemini_api_key.c_str(), sizeof(key_buf) - 1);
|
strncpy(key_buf, current_profile_.gemini_api_key.c_str(),
|
||||||
|
sizeof(key_buf) - 1);
|
||||||
}
|
}
|
||||||
if (ImGui::InputText("##gemini_key", key_buf, sizeof(key_buf), ImGuiInputTextFlags_Password)) {
|
if (ImGui::InputText("##gemini_key", key_buf, sizeof(key_buf),
|
||||||
|
ImGuiInputTextFlags_Password)) {
|
||||||
current_profile_.gemini_api_key = key_buf;
|
current_profile_.gemini_api_key = key_buf;
|
||||||
}
|
}
|
||||||
if (!current_profile_.gemini_api_key.empty()) {
|
if (!current_profile_.gemini_api_key.empty()) {
|
||||||
ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_CHECK_CIRCLE " API key configured");
|
ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f),
|
||||||
|
ICON_MD_CHECK_CIRCLE " API key configured");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ImGui::TextDisabled(ICON_MD_INFO " Mock mode - no configuration needed");
|
ImGui::TextDisabled(ICON_MD_INFO " Mock mode - no configuration needed");
|
||||||
@@ -388,11 +418,16 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Behavior Settings
|
// Behavior Settings
|
||||||
if (ImGui::CollapsingHeader(ICON_MD_TUNE " Behavior", ImGuiTreeNodeFlags_DefaultOpen)) {
|
if (ImGui::CollapsingHeader(ICON_MD_TUNE " Behavior",
|
||||||
ImGui::Checkbox(ICON_MD_VISIBILITY " Show Reasoning", ¤t_profile_.show_reasoning);
|
ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
ImGui::Checkbox(ICON_MD_ANALYTICS " Verbose Output", ¤t_profile_.verbose);
|
ImGui::Checkbox(ICON_MD_VISIBILITY " Show Reasoning",
|
||||||
ImGui::SliderInt(ICON_MD_LOOP " Max Tool Iterations", ¤t_profile_.max_tool_iterations, 1, 10);
|
¤t_profile_.show_reasoning);
|
||||||
ImGui::SliderInt(ICON_MD_REFRESH " Max Retry Attempts", ¤t_profile_.max_retry_attempts, 1, 10);
|
ImGui::Checkbox(ICON_MD_ANALYTICS " Verbose Output",
|
||||||
|
¤t_profile_.verbose);
|
||||||
|
ImGui::SliderInt(ICON_MD_LOOP " Max Tool Iterations",
|
||||||
|
¤t_profile_.max_tool_iterations, 1, 10);
|
||||||
|
ImGui::SliderInt(ICON_MD_REFRESH " Max Retry Attempts",
|
||||||
|
¤t_profile_.max_retry_attempts, 1, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Profile Metadata
|
// Profile Metadata
|
||||||
@@ -406,8 +441,10 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
|
|
||||||
ImGui::Text("Description:");
|
ImGui::Text("Description:");
|
||||||
static char desc_buf[256];
|
static char desc_buf[256];
|
||||||
strncpy(desc_buf, current_profile_.description.c_str(), sizeof(desc_buf) - 1);
|
strncpy(desc_buf, current_profile_.description.c_str(),
|
||||||
if (ImGui::InputTextMultiline("##profile_desc", desc_buf, sizeof(desc_buf), ImVec2(-1, 60))) {
|
sizeof(desc_buf) - 1);
|
||||||
|
if (ImGui::InputTextMultiline("##profile_desc", desc_buf, sizeof(desc_buf),
|
||||||
|
ImVec2(-1, 60))) {
|
||||||
current_profile_.description = desc_buf;
|
current_profile_.description = desc_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,7 +453,8 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
if (tags_buf[0] == '\0' && !current_profile_.tags.empty()) {
|
if (tags_buf[0] == '\0' && !current_profile_.tags.empty()) {
|
||||||
std::string tags_str;
|
std::string tags_str;
|
||||||
for (size_t i = 0; i < current_profile_.tags.size(); ++i) {
|
for (size_t i = 0; i < current_profile_.tags.size(); ++i) {
|
||||||
if (i > 0) tags_str += ", ";
|
if (i > 0)
|
||||||
|
tags_str += ", ";
|
||||||
tags_str += current_profile_.tags[i];
|
tags_str += current_profile_.tags[i];
|
||||||
}
|
}
|
||||||
strncpy(tags_buf, tags_str.c_str(), sizeof(tags_buf) - 1);
|
strncpy(tags_buf, tags_str.c_str(), sizeof(tags_buf) - 1);
|
||||||
@@ -449,8 +487,10 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
// Apply button
|
// Apply button
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.133f, 0.545f, 0.133f, 0.8f));
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.133f, 0.545f, 0.133f, 0.8f));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.133f, 0.545f, 0.133f, 1.0f));
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
|
||||||
if (ImGui::Button(ICON_MD_CHECK " Apply & Save Configuration", ImVec2(-1, 40))) {
|
ImVec4(0.133f, 0.545f, 0.133f, 1.0f));
|
||||||
|
if (ImGui::Button(ICON_MD_CHECK " Apply & Save Configuration",
|
||||||
|
ImVec2(-1, 40))) {
|
||||||
// Update legacy config
|
// Update legacy config
|
||||||
current_config_.provider = current_profile_.provider;
|
current_config_.provider = current_profile_.provider;
|
||||||
current_config_.model = current_profile_.model;
|
current_config_.model = current_profile_.model;
|
||||||
@@ -464,19 +504,13 @@ void AgentEditor::DrawConfigurationPanel() {
|
|||||||
Save();
|
Save();
|
||||||
|
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Configuration applied and saved", ToastType::kSuccess);
|
toast_manager_->Show("Configuration applied and saved",
|
||||||
|
ToastType::kSuccess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(2);
|
ImGui::PopStyleColor(2);
|
||||||
|
|
||||||
// RIGHT: Status & Quick Info
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
|
||||||
|
|
||||||
DrawStatusPanel();
|
|
||||||
DrawMetricsPanel();
|
DrawMetricsPanel();
|
||||||
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawStatusPanel() {
|
void AgentEditor::DrawStatusPanel() {
|
||||||
@@ -488,7 +522,8 @@ void AgentEditor::DrawStatusPanel() {
|
|||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (chat_widget_ && chat_widget_->is_active()) {
|
if (chat_widget_ && chat_widget_->is_active()) {
|
||||||
ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_CHECK_CIRCLE " Active");
|
ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f),
|
||||||
|
ICON_MD_CHECK_CIRCLE " Active");
|
||||||
} else {
|
} else {
|
||||||
ImGui::TextDisabled(ICON_MD_CANCEL " Inactive");
|
ImGui::TextDisabled(ICON_MD_CANCEL " Inactive");
|
||||||
}
|
}
|
||||||
@@ -507,11 +542,13 @@ void AgentEditor::DrawStatusPanel() {
|
|||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (rom_ && rom_->is_loaded()) {
|
if (rom_ && rom_->is_loaded()) {
|
||||||
ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f), ICON_MD_CHECK_CIRCLE " Loaded");
|
ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f),
|
||||||
|
ICON_MD_CHECK_CIRCLE " Loaded");
|
||||||
ImGui::TextDisabled("Title: %s", rom_->title().c_str());
|
ImGui::TextDisabled("Title: %s", rom_->title().c_str());
|
||||||
ImGui::TextDisabled("Tools: Ready");
|
ImGui::TextDisabled("Tools: Ready");
|
||||||
} else {
|
} else {
|
||||||
ImGui::TextColored(ImVec4(0.8f, 0.2f, 0.2f, 1.0f), ICON_MD_WARNING " Not Loaded");
|
ImGui::TextColored(ImVec4(0.8f, 0.2f, 0.2f, 1.0f),
|
||||||
|
ICON_MD_WARNING " Not Loaded");
|
||||||
ImGui::TextDisabled("Load ROM for AI tools");
|
ImGui::TextDisabled("Load ROM for AI tools");
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
@@ -520,7 +557,8 @@ void AgentEditor::DrawStatusPanel() {
|
|||||||
|
|
||||||
// Quick Tips Card
|
// Quick Tips Card
|
||||||
ImGui::BeginChild("QuickTipsCard", ImVec2(0, 150), true);
|
ImGui::BeginChild("QuickTipsCard", ImVec2(0, 150), true);
|
||||||
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f), ICON_MD_TIPS_AND_UPDATES " Quick Tips");
|
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
|
||||||
|
ICON_MD_TIPS_AND_UPDATES " Quick Tips");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
@@ -545,7 +583,8 @@ void AgentEditor::DrawMetricsPanel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawPromptEditorPanel() {
|
void AgentEditor::DrawPromptEditorPanel() {
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_EDIT " Prompt Editor");
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
||||||
|
ICON_MD_EDIT " Prompt Editor");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
@@ -553,15 +592,18 @@ void AgentEditor::DrawPromptEditorPanel() {
|
|||||||
ImGui::Text("File:");
|
ImGui::Text("File:");
|
||||||
ImGui::SetNextItemWidth(-45);
|
ImGui::SetNextItemWidth(-45);
|
||||||
if (ImGui::BeginCombo("##prompt_file", active_prompt_file_.c_str())) {
|
if (ImGui::BeginCombo("##prompt_file", active_prompt_file_.c_str())) {
|
||||||
if (ImGui::Selectable("system_prompt.txt", active_prompt_file_ == "system_prompt.txt")) {
|
if (ImGui::Selectable("system_prompt.txt",
|
||||||
|
active_prompt_file_ == "system_prompt.txt")) {
|
||||||
active_prompt_file_ = "system_prompt.txt";
|
active_prompt_file_ = "system_prompt.txt";
|
||||||
prompt_editor_initialized_ = false;
|
prompt_editor_initialized_ = false;
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("system_prompt_v2.txt", active_prompt_file_ == "system_prompt_v2.txt")) {
|
if (ImGui::Selectable("system_prompt_v2.txt",
|
||||||
|
active_prompt_file_ == "system_prompt_v2.txt")) {
|
||||||
active_prompt_file_ = "system_prompt_v2.txt";
|
active_prompt_file_ = "system_prompt_v2.txt";
|
||||||
prompt_editor_initialized_ = false;
|
prompt_editor_initialized_ = false;
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("system_prompt_v3.txt", active_prompt_file_ == "system_prompt_v3.txt")) {
|
if (ImGui::Selectable("system_prompt_v3.txt",
|
||||||
|
active_prompt_file_ == "system_prompt_v3.txt")) {
|
||||||
active_prompt_file_ = "system_prompt_v3.txt";
|
active_prompt_file_ = "system_prompt_v3.txt";
|
||||||
prompt_editor_initialized_ = false;
|
prompt_editor_initialized_ = false;
|
||||||
}
|
}
|
||||||
@@ -587,8 +629,8 @@ void AgentEditor::DrawPromptEditorPanel() {
|
|||||||
prompt_editor_initialized_ = true;
|
prompt_editor_initialized_ = true;
|
||||||
|
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show(
|
toast_manager_->Show(absl::StrFormat(ICON_MD_CHECK_CIRCLE " Loaded %s",
|
||||||
absl::StrFormat(ICON_MD_CHECK_CIRCLE " Loaded %s", active_prompt_file_),
|
active_prompt_file_),
|
||||||
ToastType::kSuccess, 2.0f);
|
ToastType::kSuccess, 2.0f);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -603,11 +645,10 @@ void AgentEditor::DrawPromptEditorPanel() {
|
|||||||
"# Please ensure the file exists in:\n"
|
"# Please ensure the file exists in:\n"
|
||||||
"# - assets/agent/%s\n"
|
"# - assets/agent/%s\n"
|
||||||
"# - Or Contents/Resources/agent/%s (macOS bundle)\n\n"
|
"# - Or Contents/Resources/agent/%s (macOS bundle)\n\n"
|
||||||
"# You can create a custom prompt here and save it to your bot profile.",
|
"# You can create a custom prompt here and save it to your bot "
|
||||||
active_prompt_file_,
|
"profile.",
|
||||||
content_result.status().message(),
|
active_prompt_file_, content_result.status().message(),
|
||||||
active_prompt_file_,
|
active_prompt_file_, active_prompt_file_);
|
||||||
active_prompt_file_);
|
|
||||||
|
|
||||||
prompt_editor_->SetText(placeholder);
|
prompt_editor_->SetText(placeholder);
|
||||||
prompt_editor_initialized_ = true;
|
prompt_editor_initialized_ = true;
|
||||||
@@ -627,23 +668,28 @@ void AgentEditor::DrawPromptEditorPanel() {
|
|||||||
if (ImGui::Button(ICON_MD_SAVE " Save Prompt to Profile", ImVec2(-1, 0))) {
|
if (ImGui::Button(ICON_MD_SAVE " Save Prompt to Profile", ImVec2(-1, 0))) {
|
||||||
current_profile_.system_prompt = prompt_editor_->GetText();
|
current_profile_.system_prompt = prompt_editor_->GetText();
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("System prompt saved to profile", ToastType::kSuccess);
|
toast_manager_->Show("System prompt saved to profile",
|
||||||
|
ToastType::kSuccess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::TextWrapped("Edit the system prompt that guides the AI agent's behavior. Changes are saved to the current bot profile.");
|
ImGui::TextWrapped(
|
||||||
|
"Edit the system prompt that guides the AI agent's behavior. Changes are "
|
||||||
|
"saved to the current bot profile.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawBotProfilesPanel() {
|
void AgentEditor::DrawBotProfilesPanel() {
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_FOLDER " Bot Profile Manager");
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
||||||
|
ICON_MD_FOLDER " Bot Profile Manager");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
// Current profile display
|
// Current profile display
|
||||||
ImGui::BeginChild("CurrentProfile", ImVec2(0, 150), true);
|
ImGui::BeginChild("CurrentProfile", ImVec2(0, 150), true);
|
||||||
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f), ICON_MD_STAR " Current Profile");
|
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
|
||||||
|
ICON_MD_STAR " Current Profile");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Text("Name: %s", current_profile_.name.c_str());
|
ImGui::Text("Name: %s", current_profile_.name.c_str());
|
||||||
ImGui::Text("Provider: %s", current_profile_.provider.c_str());
|
ImGui::Text("Provider: %s", current_profile_.provider.c_str());
|
||||||
@@ -651,7 +697,9 @@ void AgentEditor::DrawBotProfilesPanel() {
|
|||||||
ImGui::Text("Model: %s", current_profile_.model.c_str());
|
ImGui::Text("Model: %s", current_profile_.model.c_str());
|
||||||
}
|
}
|
||||||
ImGui::TextWrapped("Description: %s",
|
ImGui::TextWrapped("Description: %s",
|
||||||
current_profile_.description.empty() ? "No description" : current_profile_.description.c_str());
|
current_profile_.description.empty()
|
||||||
|
? "No description"
|
||||||
|
: current_profile_.description.c_str());
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
@@ -665,20 +713,23 @@ void AgentEditor::DrawBotProfilesPanel() {
|
|||||||
new_profile.modified_at = absl::Now();
|
new_profile.modified_at = absl::Now();
|
||||||
current_profile_ = new_profile;
|
current_profile_ = new_profile;
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("New profile created. Configure and save it.", ToastType::kInfo);
|
toast_manager_->Show("New profile created. Configure and save it.",
|
||||||
|
ToastType::kInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
// Saved profiles list
|
// Saved profiles list
|
||||||
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f), ICON_MD_LIST " Saved Profiles");
|
ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
|
||||||
|
ICON_MD_LIST " Saved Profiles");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
ImGui::BeginChild("ProfilesList", ImVec2(0, 0), true);
|
ImGui::BeginChild("ProfilesList", ImVec2(0, 0), true);
|
||||||
|
|
||||||
if (loaded_profiles_.empty()) {
|
if (loaded_profiles_.empty()) {
|
||||||
ImGui::TextDisabled("No saved profiles. Create and save a profile to see it here.");
|
ImGui::TextDisabled(
|
||||||
|
"No saved profiles. Create and save a profile to see it here.");
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < loaded_profiles_.size(); ++i) {
|
for (size_t i = 0; i < loaded_profiles_.size(); ++i) {
|
||||||
const auto& profile = loaded_profiles_[i];
|
const auto& profile = loaded_profiles_[i];
|
||||||
@@ -686,13 +737,17 @@ void AgentEditor::DrawBotProfilesPanel() {
|
|||||||
|
|
||||||
bool is_current = (profile.name == current_profile_.name);
|
bool is_current = (profile.name == current_profile_.name);
|
||||||
if (is_current) {
|
if (is_current) {
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.196f, 0.6f, 0.8f, 0.6f));
|
ImGui::PushStyleColor(ImGuiCol_Button,
|
||||||
|
ImVec4(0.196f, 0.6f, 0.8f, 0.6f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Button(profile.name.c_str(), ImVec2(ImGui::GetContentRegionAvail().x - 80, 0))) {
|
if (ImGui::Button(profile.name.c_str(),
|
||||||
|
ImVec2(ImGui::GetContentRegionAvail().x - 80, 0))) {
|
||||||
LoadBotProfile(profile.name);
|
LoadBotProfile(profile.name);
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show(absl::StrFormat("Loaded profile: %s", profile.name), ToastType::kSuccess);
|
toast_manager_->Show(
|
||||||
|
absl::StrFormat("Loaded profile: %s", profile.name),
|
||||||
|
ToastType::kSuccess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -705,13 +760,17 @@ void AgentEditor::DrawBotProfilesPanel() {
|
|||||||
if (ImGui::SmallButton(ICON_MD_DELETE)) {
|
if (ImGui::SmallButton(ICON_MD_DELETE)) {
|
||||||
DeleteBotProfile(profile.name);
|
DeleteBotProfile(profile.name);
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show(absl::StrFormat("Deleted profile: %s", profile.name), ToastType::kInfo);
|
toast_manager_->Show(
|
||||||
|
absl::StrFormat("Deleted profile: %s", profile.name),
|
||||||
|
ToastType::kInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
ImGui::TextDisabled(" %s | %s", profile.provider.c_str(),
|
ImGui::TextDisabled(" %s | %s", profile.provider.c_str(),
|
||||||
profile.description.empty() ? "No description" : profile.description.c_str());
|
profile.description.empty()
|
||||||
|
? "No description"
|
||||||
|
: profile.description.c_str());
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
@@ -722,7 +781,8 @@ void AgentEditor::DrawBotProfilesPanel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawChatHistoryViewer() {
|
void AgentEditor::DrawChatHistoryViewer() {
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_HISTORY " Chat History Viewer");
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
||||||
|
ICON_MD_HISTORY " Chat History Viewer");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
@@ -753,18 +813,22 @@ void AgentEditor::DrawChatHistoryViewer() {
|
|||||||
ImGui::BeginChild("HistoryList", ImVec2(0, 0), true);
|
ImGui::BeginChild("HistoryList", ImVec2(0, 0), true);
|
||||||
|
|
||||||
if (cached_history_.empty()) {
|
if (cached_history_.empty()) {
|
||||||
ImGui::TextDisabled("No chat history. Start a conversation in the chat window.");
|
ImGui::TextDisabled(
|
||||||
|
"No chat history. Start a conversation in the chat window.");
|
||||||
} else {
|
} else {
|
||||||
for (const auto& msg : cached_history_) {
|
for (const auto& msg : cached_history_) {
|
||||||
bool from_user = (msg.sender == cli::agent::ChatMessage::Sender::kUser);
|
bool from_user = (msg.sender == cli::agent::ChatMessage::Sender::kUser);
|
||||||
ImVec4 color = from_user ? ImVec4(0.6f, 0.8f, 1.0f, 1.0f) : ImVec4(0.4f, 0.8f, 0.4f, 1.0f);
|
ImVec4 color = from_user ? ImVec4(0.6f, 0.8f, 1.0f, 1.0f)
|
||||||
|
: ImVec4(0.4f, 0.8f, 0.4f, 1.0f);
|
||||||
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||||
ImGui::Text("%s:", from_user ? "User" : "Agent");
|
ImGui::Text("%s:", from_user ? "User" : "Agent");
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::TextDisabled("%s", absl::FormatTime("%H:%M:%S", msg.timestamp, absl::LocalTimeZone()).c_str());
|
ImGui::TextDisabled("%s", absl::FormatTime("%H:%M:%S", msg.timestamp,
|
||||||
|
absl::LocalTimeZone())
|
||||||
|
.c_str());
|
||||||
|
|
||||||
ImGui::TextWrapped("%s", msg.message.c_str());
|
ImGui::TextWrapped("%s", msg.message.c_str());
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
@@ -776,15 +840,18 @@ void AgentEditor::DrawChatHistoryViewer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawAdvancedMetricsPanel() {
|
void AgentEditor::DrawAdvancedMetricsPanel() {
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_ANALYTICS " Session Metrics & Analytics");
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
||||||
|
ICON_MD_ANALYTICS " Session Metrics & Analytics");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
// Get metrics from chat widget service
|
// Get metrics from chat widget service
|
||||||
if (chat_widget_) {
|
if (chat_widget_) {
|
||||||
// For now show placeholder metrics structure
|
// For now show placeholder metrics structure
|
||||||
if (ImGui::BeginTable("MetricsTable", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
|
if (ImGui::BeginTable("MetricsTable", 2,
|
||||||
ImGui::TableSetupColumn("Metric", ImGuiTableColumnFlags_WidthFixed, 200.0f);
|
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
|
||||||
|
ImGui::TableSetupColumn("Metric", ImGuiTableColumnFlags_WidthFixed,
|
||||||
|
200.0f);
|
||||||
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
@@ -816,18 +883,23 @@ void AgentEditor::DrawAdvancedMetricsPanel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::TextWrapped("Detailed session metrics are available during active chat sessions. Open the chat window to see live statistics.");
|
ImGui::TextWrapped(
|
||||||
|
"Detailed session metrics are available during active chat sessions. "
|
||||||
|
"Open the chat window to see live statistics.");
|
||||||
} else {
|
} else {
|
||||||
ImGui::TextDisabled("No metrics available. Initialize the chat system first.");
|
ImGui::TextDisabled(
|
||||||
|
"No metrics available. Initialize the chat system first.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawCommonTilesEditor() {
|
void AgentEditor::DrawCommonTilesEditor() {
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_GRID_ON " Common Tiles Reference");
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
||||||
|
ICON_MD_GRID_ON " Common Tiles Reference");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
ImGui::TextWrapped("Customize the tile reference file that AI uses for tile placement. "
|
ImGui::TextWrapped(
|
||||||
|
"Customize the tile reference file that AI uses for tile placement. "
|
||||||
"Organize tiles by category and provide hex IDs with descriptions.");
|
"Organize tiles by category and provide hex IDs with descriptions.");
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
@@ -839,7 +911,8 @@ void AgentEditor::DrawCommonTilesEditor() {
|
|||||||
common_tiles_editor_->SetText(*content);
|
common_tiles_editor_->SetText(*content);
|
||||||
common_tiles_initialized_ = true;
|
common_tiles_initialized_ = true;
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show(ICON_MD_CHECK_CIRCLE " Common tiles loaded", ToastType::kSuccess, 2.0f);
|
toast_manager_->Show(ICON_MD_CHECK_CIRCLE " Common tiles loaded",
|
||||||
|
ToastType::kSuccess, 2.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -848,7 +921,9 @@ void AgentEditor::DrawCommonTilesEditor() {
|
|||||||
if (ImGui::Button(ICON_MD_SAVE " Save", ImVec2(100, 0))) {
|
if (ImGui::Button(ICON_MD_SAVE " Save", ImVec2(100, 0))) {
|
||||||
// Save to project or assets directory
|
// Save to project or assets directory
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show(ICON_MD_INFO " Save to project directory (coming soon)", ToastType::kInfo, 2.0f);
|
toast_manager_->Show(ICON_MD_INFO
|
||||||
|
" Save to project directory (coming soon)",
|
||||||
|
ToastType::kInfo, 2.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -888,17 +963,20 @@ void AgentEditor::DrawCommonTilesEditor() {
|
|||||||
|
|
||||||
// Editor
|
// Editor
|
||||||
if (common_tiles_editor_) {
|
if (common_tiles_editor_) {
|
||||||
ImVec2 editor_size(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y);
|
ImVec2 editor_size(ImGui::GetContentRegionAvail().x,
|
||||||
|
ImGui::GetContentRegionAvail().y);
|
||||||
common_tiles_editor_->Render("##tiles_editor", editor_size, true);
|
common_tiles_editor_->Render("##tiles_editor", editor_size, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AgentEditor::DrawNewPromptCreator() {
|
void AgentEditor::DrawNewPromptCreator() {
|
||||||
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f), ICON_MD_ADD " Create New System Prompt");
|
ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
|
||||||
|
ICON_MD_ADD " Create New System Prompt");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
||||||
ImGui::TextWrapped("Create a custom system prompt from scratch or use a template.");
|
ImGui::TextWrapped(
|
||||||
|
"Create a custom system prompt from scratch or use a template.");
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
@@ -925,7 +1003,8 @@ void AgentEditor::DrawNewPromptCreator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Button(ICON_MD_FILE_COPY " v2 (Enhanced)", ImVec2(-1, 0))) {
|
if (ImGui::Button(ICON_MD_FILE_COPY " v2 (Enhanced)", ImVec2(-1, 0))) {
|
||||||
auto content = core::AssetLoader::LoadTextFile("agent/system_prompt_v2.txt");
|
auto content =
|
||||||
|
core::AssetLoader::LoadTextFile("agent/system_prompt_v2.txt");
|
||||||
if (content.ok() && prompt_editor_) {
|
if (content.ok() && prompt_editor_) {
|
||||||
prompt_editor_->SetText(*content);
|
prompt_editor_->SetText(*content);
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
@@ -935,7 +1014,8 @@ void AgentEditor::DrawNewPromptCreator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Button(ICON_MD_FILE_COPY " v3 (Proactive)", ImVec2(-1, 0))) {
|
if (ImGui::Button(ICON_MD_FILE_COPY " v3 (Proactive)", ImVec2(-1, 0))) {
|
||||||
auto content = core::AssetLoader::LoadTextFile("agent/system_prompt_v3.txt");
|
auto content =
|
||||||
|
core::AssetLoader::LoadTextFile("agent/system_prompt_v3.txt");
|
||||||
if (content.ok() && prompt_editor_) {
|
if (content.ok() && prompt_editor_) {
|
||||||
prompt_editor_->SetText(*content);
|
prompt_editor_->SetText(*content);
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
@@ -964,7 +1044,8 @@ void AgentEditor::DrawNewPromptCreator() {
|
|||||||
"3. Explain your reasoning\n";
|
"3. Explain your reasoning\n";
|
||||||
prompt_editor_->SetText(blank_template);
|
prompt_editor_->SetText(blank_template);
|
||||||
if (toast_manager_) {
|
if (toast_manager_) {
|
||||||
toast_manager_->Show("Blank template created", ToastType::kSuccess, 1.5f);
|
toast_manager_->Show("Blank template created", ToastType::kSuccess,
|
||||||
|
1.5f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -992,13 +1073,16 @@ void AgentEditor::DrawNewPromptCreator() {
|
|||||||
// Clear name buffer
|
// Clear name buffer
|
||||||
std::memset(new_prompt_name_, 0, sizeof(new_prompt_name_));
|
std::memset(new_prompt_name_, 0, sizeof(new_prompt_name_));
|
||||||
} else if (toast_manager_) {
|
} else if (toast_manager_) {
|
||||||
toast_manager_->Show(ICON_MD_WARNING " Enter a name for the prompt", ToastType::kWarning, 2.0f);
|
toast_manager_->Show(ICON_MD_WARNING " Enter a name for the prompt",
|
||||||
|
ToastType::kWarning, 2.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::TextWrapped("Note: New prompts are saved to your project. Use 'System Prompt' tab to edit existing prompts.");
|
ImGui::TextWrapped(
|
||||||
|
"Note: New prompts are saved to your project. Use 'System Prompt' tab to "
|
||||||
|
"edit existing prompts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bot Profile Management Implementation
|
// Bot Profile Management Implementation
|
||||||
@@ -1006,7 +1090,8 @@ absl::Status AgentEditor::SaveBotProfile(const BotProfile& profile) {
|
|||||||
#if defined(YAZE_WITH_JSON)
|
#if defined(YAZE_WITH_JSON)
|
||||||
RETURN_IF_ERROR(EnsureProfilesDirectory());
|
RETURN_IF_ERROR(EnsureProfilesDirectory());
|
||||||
|
|
||||||
std::filesystem::path profile_path = GetProfilesDirectory() / (profile.name + ".json");
|
std::filesystem::path profile_path =
|
||||||
|
GetProfilesDirectory() / (profile.name + ".json");
|
||||||
std::ofstream file(profile_path);
|
std::ofstream file(profile_path);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
return absl::InternalError("Failed to open profile file for writing");
|
return absl::InternalError("Failed to open profile file for writing");
|
||||||
@@ -1020,13 +1105,15 @@ absl::Status AgentEditor::SaveBotProfile(const BotProfile& profile) {
|
|||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
#else
|
#else
|
||||||
return absl::UnimplementedError("JSON support required for profile management");
|
return absl::UnimplementedError(
|
||||||
|
"JSON support required for profile management");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status AgentEditor::LoadBotProfile(const std::string& name) {
|
absl::Status AgentEditor::LoadBotProfile(const std::string& name) {
|
||||||
#if defined(YAZE_WITH_JSON)
|
#if defined(YAZE_WITH_JSON)
|
||||||
std::filesystem::path profile_path = GetProfilesDirectory() / (name + ".json");
|
std::filesystem::path profile_path =
|
||||||
|
GetProfilesDirectory() / (name + ".json");
|
||||||
if (!std::filesystem::exists(profile_path)) {
|
if (!std::filesystem::exists(profile_path)) {
|
||||||
return absl::NotFoundError(absl::StrFormat("Profile '%s' not found", name));
|
return absl::NotFoundError(absl::StrFormat("Profile '%s' not found", name));
|
||||||
}
|
}
|
||||||
@@ -1056,12 +1143,14 @@ absl::Status AgentEditor::LoadBotProfile(const std::string& name) {
|
|||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
#else
|
#else
|
||||||
return absl::UnimplementedError("JSON support required for profile management");
|
return absl::UnimplementedError(
|
||||||
|
"JSON support required for profile management");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status AgentEditor::DeleteBotProfile(const std::string& name) {
|
absl::Status AgentEditor::DeleteBotProfile(const std::string& name) {
|
||||||
std::filesystem::path profile_path = GetProfilesDirectory() / (name + ".json");
|
std::filesystem::path profile_path =
|
||||||
|
GetProfilesDirectory() / (name + ".json");
|
||||||
if (!std::filesystem::exists(profile_path)) {
|
if (!std::filesystem::exists(profile_path)) {
|
||||||
return absl::NotFoundError(absl::StrFormat("Profile '%s' not found", name));
|
return absl::NotFoundError(absl::StrFormat("Profile '%s' not found", name));
|
||||||
}
|
}
|
||||||
@@ -1091,7 +1180,8 @@ void AgentEditor::SetCurrentProfile(const BotProfile& profile) {
|
|||||||
current_config_.max_tool_iterations = profile.max_tool_iterations;
|
current_config_.max_tool_iterations = profile.max_tool_iterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status AgentEditor::ExportProfile(const BotProfile& profile, const std::filesystem::path& path) {
|
absl::Status AgentEditor::ExportProfile(const BotProfile& profile,
|
||||||
|
const std::filesystem::path& path) {
|
||||||
#if defined(YAZE_WITH_JSON)
|
#if defined(YAZE_WITH_JSON)
|
||||||
std::ofstream file(path);
|
std::ofstream file(path);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
@@ -1146,7 +1236,8 @@ std::filesystem::path AgentEditor::GetProfilesDirectory() const {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return config_dir / std::filesystem::path("agent") / std::filesystem::path("profiles");
|
return config_dir / std::filesystem::path("agent") /
|
||||||
|
std::filesystem::path("profiles");
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status AgentEditor::EnsureProfilesDirectory() {
|
absl::Status AgentEditor::EnsureProfilesDirectory() {
|
||||||
@@ -1154,7 +1245,8 @@ absl::Status AgentEditor::EnsureProfilesDirectory() {
|
|||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
std::filesystem::create_directories(dir, ec);
|
std::filesystem::create_directories(dir, ec);
|
||||||
if (ec) {
|
if (ec) {
|
||||||
return absl::InternalError(absl::StrFormat("Failed to create profiles directory: %s", ec.message()));
|
return absl::InternalError(absl::StrFormat(
|
||||||
|
"Failed to create profiles directory: %s", ec.message()));
|
||||||
}
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
@@ -1174,8 +1266,10 @@ std::string AgentEditor::ProfileToJson(const BotProfile& profile) const {
|
|||||||
json["max_tool_iterations"] = profile.max_tool_iterations;
|
json["max_tool_iterations"] = profile.max_tool_iterations;
|
||||||
json["max_retry_attempts"] = profile.max_retry_attempts;
|
json["max_retry_attempts"] = profile.max_retry_attempts;
|
||||||
json["tags"] = profile.tags;
|
json["tags"] = profile.tags;
|
||||||
json["created_at"] = absl::FormatTime(absl::RFC3339_full, profile.created_at, absl::UTCTimeZone());
|
json["created_at"] = absl::FormatTime(absl::RFC3339_full, profile.created_at,
|
||||||
json["modified_at"] = absl::FormatTime(absl::RFC3339_full, profile.modified_at, absl::UTCTimeZone());
|
absl::UTCTimeZone());
|
||||||
|
json["modified_at"] = absl::FormatTime(
|
||||||
|
absl::RFC3339_full, profile.modified_at, absl::UTCTimeZone());
|
||||||
|
|
||||||
return json.dump(2);
|
return json.dump(2);
|
||||||
#else
|
#else
|
||||||
@@ -1183,7 +1277,8 @@ std::string AgentEditor::ProfileToJson(const BotProfile& profile) const {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::StatusOr<AgentEditor::BotProfile> AgentEditor::JsonToProfile(const std::string& json_str) const {
|
absl::StatusOr<AgentEditor::BotProfile> AgentEditor::JsonToProfile(
|
||||||
|
const std::string& json_str) const {
|
||||||
#if defined(YAZE_WITH_JSON)
|
#if defined(YAZE_WITH_JSON)
|
||||||
try {
|
try {
|
||||||
nlohmann::json json = nlohmann::json::parse(json_str);
|
nlohmann::json json = nlohmann::json::parse(json_str);
|
||||||
@@ -1209,21 +1304,26 @@ absl::StatusOr<AgentEditor::BotProfile> AgentEditor::JsonToProfile(const std::st
|
|||||||
|
|
||||||
if (json.contains("created_at")) {
|
if (json.contains("created_at")) {
|
||||||
absl::Time created;
|
absl::Time created;
|
||||||
if (absl::ParseTime(absl::RFC3339_full, json["created_at"].get<std::string>(), &created, nullptr)) {
|
if (absl::ParseTime(absl::RFC3339_full,
|
||||||
|
json["created_at"].get<std::string>(), &created,
|
||||||
|
nullptr)) {
|
||||||
profile.created_at = created;
|
profile.created_at = created;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.contains("modified_at")) {
|
if (json.contains("modified_at")) {
|
||||||
absl::Time modified;
|
absl::Time modified;
|
||||||
if (absl::ParseTime(absl::RFC3339_full, json["modified_at"].get<std::string>(), &modified, nullptr)) {
|
if (absl::ParseTime(absl::RFC3339_full,
|
||||||
|
json["modified_at"].get<std::string>(), &modified,
|
||||||
|
nullptr)) {
|
||||||
profile.modified_at = modified;
|
profile.modified_at = modified;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return profile;
|
return profile;
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
return absl::InternalError(absl::StrFormat("Failed to parse profile JSON: %s", e.what()));
|
return absl::InternalError(
|
||||||
|
absl::StrFormat("Failed to parse profile JSON: %s", e.what()));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return absl::UnimplementedError("JSON support required");
|
return absl::UnimplementedError("JSON support required");
|
||||||
@@ -1277,7 +1377,8 @@ absl::StatusOr<AgentEditor::SessionInfo> AgentEditor::HostSession(
|
|||||||
current_mode_ = mode;
|
current_mode_ = mode;
|
||||||
|
|
||||||
if (mode == CollaborationMode::kLocal) {
|
if (mode == CollaborationMode::kLocal) {
|
||||||
ASSIGN_OR_RETURN(auto session, local_coordinator_->HostSession(session_name));
|
ASSIGN_OR_RETURN(auto session,
|
||||||
|
local_coordinator_->HostSession(session_name));
|
||||||
|
|
||||||
SessionInfo info;
|
SessionInfo info;
|
||||||
info.session_id = session.session_id;
|
info.session_id = session.session_id;
|
||||||
@@ -1349,7 +1450,8 @@ absl::StatusOr<AgentEditor::SessionInfo> AgentEditor::JoinSession(
|
|||||||
current_mode_ = mode;
|
current_mode_ = mode;
|
||||||
|
|
||||||
if (mode == CollaborationMode::kLocal) {
|
if (mode == CollaborationMode::kLocal) {
|
||||||
ASSIGN_OR_RETURN(auto session, local_coordinator_->JoinSession(session_code));
|
ASSIGN_OR_RETURN(auto session,
|
||||||
|
local_coordinator_->JoinSession(session_code));
|
||||||
|
|
||||||
SessionInfo info;
|
SessionInfo info;
|
||||||
info.session_id = session.session_id;
|
info.session_id = session.session_id;
|
||||||
@@ -1551,10 +1653,11 @@ void AgentEditor::SetupChatWidgetCallbacks() {
|
|||||||
|
|
||||||
AgentChatWidget::CollaborationCallbacks collab_callbacks;
|
AgentChatWidget::CollaborationCallbacks collab_callbacks;
|
||||||
|
|
||||||
collab_callbacks.host_session =
|
collab_callbacks.host_session = [this](const std::string& session_name)
|
||||||
[this](const std::string& session_name)
|
-> absl::StatusOr<
|
||||||
-> absl::StatusOr<AgentChatWidget::CollaborationCallbacks::SessionContext> {
|
AgentChatWidget::CollaborationCallbacks::SessionContext> {
|
||||||
ASSIGN_OR_RETURN(auto session, this->HostSession(session_name, current_mode_));
|
ASSIGN_OR_RETURN(auto session,
|
||||||
|
this->HostSession(session_name, current_mode_));
|
||||||
|
|
||||||
AgentChatWidget::CollaborationCallbacks::SessionContext context;
|
AgentChatWidget::CollaborationCallbacks::SessionContext context;
|
||||||
context.session_id = session.session_id;
|
context.session_id = session.session_id;
|
||||||
@@ -1563,10 +1666,11 @@ void AgentEditor::SetupChatWidgetCallbacks() {
|
|||||||
return context;
|
return context;
|
||||||
};
|
};
|
||||||
|
|
||||||
collab_callbacks.join_session =
|
collab_callbacks.join_session = [this](const std::string& session_code)
|
||||||
[this](const std::string& session_code)
|
-> absl::StatusOr<
|
||||||
-> absl::StatusOr<AgentChatWidget::CollaborationCallbacks::SessionContext> {
|
AgentChatWidget::CollaborationCallbacks::SessionContext> {
|
||||||
ASSIGN_OR_RETURN(auto session, this->JoinSession(session_code, current_mode_));
|
ASSIGN_OR_RETURN(auto session,
|
||||||
|
this->JoinSession(session_code, current_mode_));
|
||||||
|
|
||||||
AgentChatWidget::CollaborationCallbacks::SessionContext context;
|
AgentChatWidget::CollaborationCallbacks::SessionContext context;
|
||||||
context.session_id = session.session_id;
|
context.session_id = session.session_id;
|
||||||
@@ -1580,7 +1684,8 @@ void AgentEditor::SetupChatWidgetCallbacks() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
collab_callbacks.refresh_session =
|
collab_callbacks.refresh_session =
|
||||||
[this]() -> absl::StatusOr<AgentChatWidget::CollaborationCallbacks::SessionContext> {
|
[this]() -> absl::StatusOr<
|
||||||
|
AgentChatWidget::CollaborationCallbacks::SessionContext> {
|
||||||
ASSIGN_OR_RETURN(auto session, this->RefreshSession());
|
ASSIGN_OR_RETURN(auto session, this->RefreshSession());
|
||||||
|
|
||||||
AgentChatWidget::CollaborationCallbacks::SessionContext context;
|
AgentChatWidget::CollaborationCallbacks::SessionContext context;
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
// Application entry point - separated from C API implementation
|
|
||||||
#include "yaze.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
#include <set>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "app/core/controller.h"
|
|
||||||
#include "app/core/platform/app_delegate.h"
|
|
||||||
#include "util/flag.h"
|
|
||||||
#include "util/log.h"
|
|
||||||
#include "yaze_config.h"
|
|
||||||
|
|
||||||
DEFINE_FLAG(std::string, rom_file, "",
|
|
||||||
"Path to the ROM file to load. "
|
|
||||||
"If not specified, the app will run without a ROM.");
|
|
||||||
|
|
||||||
DEFINE_FLAG(
|
|
||||||
std::string, log_level, "info",
|
|
||||||
"Minimum log level to output (e.g., debug, info, warn, error, fatal).");
|
|
||||||
DEFINE_FLAG(std::string, log_file, "",
|
|
||||||
"Path to the log file. If empty, logs to stderr.");
|
|
||||||
DEFINE_FLAG(std::string, log_categories, "",
|
|
||||||
"Comma-separated list of log categories to enable.");
|
|
||||||
|
|
||||||
int yaze_app_main(int argc, char** argv) {
|
|
||||||
yaze::util::FlagParser parser(yaze::util::global_flag_registry());
|
|
||||||
RETURN_IF_EXCEPTION(parser.Parse(argc, argv));
|
|
||||||
|
|
||||||
// --- Configure Logging System ---
|
|
||||||
auto string_to_log_level = [](const std::string& s) {
|
|
||||||
std::string upper_s;
|
|
||||||
std::transform(s.begin(), s.end(), std::back_inserter(upper_s),
|
|
||||||
::toupper);
|
|
||||||
if (upper_s == "YAZE_DEBUG") return yaze::util::LogLevel::YAZE_DEBUG;
|
|
||||||
if (upper_s == "INFO") return yaze::util::LogLevel::INFO;
|
|
||||||
if (upper_s == "WARN" || upper_s == "WARNING")
|
|
||||||
return yaze::util::LogLevel::WARNING;
|
|
||||||
if (upper_s == "ERROR") return yaze::util::LogLevel::ERROR;
|
|
||||||
if (upper_s == "FATAL") return yaze::util::LogLevel::FATAL;
|
|
||||||
return yaze::util::LogLevel::INFO; // Default
|
|
||||||
};
|
|
||||||
|
|
||||||
auto split_categories = [](const std::string& s) {
|
|
||||||
std::set<std::string> result;
|
|
||||||
std::stringstream ss(s);
|
|
||||||
std::string item;
|
|
||||||
while (std::getline(ss, item, ',')) {
|
|
||||||
if (!item.empty()) {
|
|
||||||
result.insert(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
yaze::util::LogManager::instance().configure(
|
|
||||||
string_to_log_level(FLAGS_log_level->Get()), FLAGS_log_file->Get(),
|
|
||||||
split_categories(FLAGS_log_categories->Get()));
|
|
||||||
|
|
||||||
LOG_INFO("App", "Yaze starting up...");
|
|
||||||
LOG_INFO("App", "Version: %s", YAZE_VERSION_STRING);
|
|
||||||
|
|
||||||
std::string rom_filename = "";
|
|
||||||
if (!FLAGS_rom_file->Get().empty()) {
|
|
||||||
rom_filename = FLAGS_rom_file->Get();
|
|
||||||
LOG_INFO("App", "Loading ROM file: %s", rom_filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
return yaze_run_cocoa_app_delegate(rom_filename.c_str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto controller = std::make_unique<yaze::core::Controller>();
|
|
||||||
EXIT_IF_ERROR(controller->OnEntry(rom_filename))
|
|
||||||
while (controller->IsActive()) {
|
|
||||||
controller->OnInput();
|
|
||||||
if (auto status = controller->OnLoad(); !status.ok()) {
|
|
||||||
LOG_ERROR("App", "Controller OnLoad failed: %s", status.message());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
controller->DoRender();
|
|
||||||
}
|
|
||||||
controller->OnExit();
|
|
||||||
LOG_INFO("App", "Yaze shutting down.");
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -120,11 +120,23 @@ absl::StatusOr<std::string> PromptBuilder::ResolveCataloguePath(
|
|||||||
for (const auto& candidate : search_paths) {
|
for (const auto& candidate : search_paths) {
|
||||||
fs::path resolved = candidate;
|
fs::path resolved = candidate;
|
||||||
if (resolved.is_relative()) {
|
if (resolved.is_relative()) {
|
||||||
|
try {
|
||||||
resolved = fs::absolute(resolved);
|
resolved = fs::absolute(resolved);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
// If we can't resolve the absolute path (e.g., cwd doesn't exist),
|
||||||
|
// just try the relative path as-is
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
if (fs::exists(resolved)) {
|
if (fs::exists(resolved)) {
|
||||||
return resolved.string();
|
return resolved.string();
|
||||||
}
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
// If checking existence fails, just continue to next path
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return absl::NotFoundError(
|
return absl::NotFoundError(
|
||||||
|
|||||||
Reference in New Issue
Block a user