7#include "absl/strings/match.h"
8#include "absl/strings/str_format.h"
9#include "absl/time/clock.h"
24#if defined(YAZE_WITH_JSON)
25#include "nlohmann/json.hpp"
78 if (std::filesystem::exists(profiles_dir)) {
79 for (
const auto& entry :
80 std::filesystem::directory_iterator(profiles_dir)) {
81 if (entry.path().extension() ==
".json") {
82 std::ifstream file(entry.path());
84 std::string json_content((std::istreambuf_iterator<char>(file)),
85 std::istreambuf_iterator<char>());
87 if (profile_or.ok()) {
94 return absl::OkStatus();
104 return absl::OkStatus();
111 return absl::OkStatus();
145 ImGuiIO& io = ImGui::GetIO();
154 ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImVec4(
156 0.2f + 0.15f * pulse,
161 ImGui::SetNextWindowSize(ImVec2(1200, 800), ImGuiCond_FirstUseEver);
163 ImGuiWindowFlags_MenuBar);
166 if (ImGui::BeginMenuBar()) {
192 if (ImGui::MenuItem(
ICON_MD_CHAT " Open Chat Window",
"Ctrl+Shift+A")) {
196 ImGui::MenuItem(
ICON_MD_EDIT " Show Prompt Editor",
nullptr,
211 if (ImGui::BeginTabBar(
"AgentEditorTabs", ImGuiTabBarFlags_None)) {
217 ImGuiTableFlags table_flags = ImGuiTableFlags_Resizable |
218 ImGuiTableFlags_BordersInnerV |
219 ImGuiTableFlags_SizingStretchProp;
221 if (ImGui::BeginTable(
"BotStudioLayout", 3, table_flags)) {
222 ImGui::TableSetupColumn(
"Settings", ImGuiTableColumnFlags_WidthFixed,
224 ImGui::TableSetupColumn(
"Editors", ImGuiTableColumnFlags_WidthStretch);
225 ImGui::TableSetupColumn(
"Profiles", ImGuiTableColumnFlags_WidthFixed,
227 ImGui::TableNextRow();
230 ImGui::TableNextColumn();
231 ImGui::PushID(
"SettingsColumn");
243 ImGui::TableNextColumn();
244 ImGui::PushID(
"EditorsColumn");
246 if (ImGui::BeginTabBar(
"EditorTabs", ImGuiTabBarFlags_None)) {
247 if (ImGui::BeginTabItem(
ICON_MD_EDIT " System Prompt")) {
257 if (ImGui::BeginTabItem(
ICON_MD_ADD " New Prompt")) {
268 ImGui::TableNextColumn();
269 ImGui::PushID(
"ProfilesColumn");
284 if (ImGui::BeginTable(
286 ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInnerV)) {
287 ImGui::TableSetupColumn(
"History", ImGuiTableColumnFlags_WidthStretch,
289 ImGui::TableSetupColumn(
"Metrics", ImGuiTableColumnFlags_WidthStretch,
291 ImGui::TableNextRow();
294 ImGui::TableSetColumnIndex(0);
298 ImGui::TableSetColumnIndex(1);
317 ImGuiTreeNodeFlags_DefaultOpen)) {
318 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
323 ImVec2 button_size(ImGui::GetContentRegionAvail().x / 3 - 8, 60);
330 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.6f, 0.6f, 0.6f, 0.8f));
335 ImGui::PopStyleColor();
339 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.8f, 0.4f, 0.8f));
344 ImGui::PopStyleColor();
348 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.196f, 0.6f, 0.8f, 0.8f));
353 ImGui::PopStyleColor();
360 ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.4f, 1.0f),
362 ImGui::Text(
"Model:");
363 ImGui::SetNextItemWidth(-1);
364 static char model_buf[128] =
"qwen2.5-coder:7b";
367 sizeof(model_buf) - 1);
369 if (ImGui::InputTextWithHint(
"##ollama_model",
370 "e.g., qwen2.5-coder:7b, llama3.2",
371 model_buf,
sizeof(model_buf))) {
375 ImGui::Text(
"Host URL:");
376 ImGui::SetNextItemWidth(-1);
377 static char host_buf[256] =
"http://localhost:11434";
379 sizeof(host_buf) - 1);
380 if (ImGui::InputText(
"##ollama_host", host_buf,
sizeof(host_buf))) {
384 ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
389 const char* gemini_key = std::getenv(
"GEMINI_API_KEY");
406 ImGui::Text(
"Model:");
407 ImGui::SetNextItemWidth(-1);
408 static char model_buf[128] =
"gemini-1.5-flash";
411 sizeof(model_buf) - 1);
413 if (ImGui::InputTextWithHint(
"##gemini_model",
"e.g., gemini-1.5-flash",
414 model_buf,
sizeof(model_buf))) {
418 ImGui::Text(
"API Key:");
419 ImGui::SetNextItemWidth(-1);
420 static char key_buf[256] =
"";
423 sizeof(key_buf) - 1);
425 if (ImGui::InputText(
"##gemini_key", key_buf,
sizeof(key_buf),
426 ImGuiInputTextFlags_Password)) {
430 ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f),
434 ImGui::TextDisabled(
ICON_MD_INFO " Mock mode - no configuration needed");
440 ImGuiTreeNodeFlags_DefaultOpen)) {
452 if (ImGui::CollapsingHeader(
ICON_MD_INFO " Profile Info")) {
453 ImGui::Text(
"Name:");
454 static char name_buf[128];
456 if (ImGui::InputText(
"##profile_name", name_buf,
sizeof(name_buf))) {
460 ImGui::Text(
"Description:");
461 static char desc_buf[256];
463 sizeof(desc_buf) - 1);
464 if (ImGui::InputTextMultiline(
"##profile_desc", desc_buf,
sizeof(desc_buf),
469 ImGui::Text(
"Tags (comma-separated):");
470 static char tags_buf[256];
472 std::string tags_str;
478 strncpy(tags_buf, tags_str.c_str(),
sizeof(tags_buf) - 1);
480 if (ImGui::InputText(
"##profile_tags", tags_buf,
sizeof(tags_buf))) {
483 std::string tags_str(tags_buf);
485 while ((pos = tags_str.find(
',')) != std::string::npos) {
486 std::string tag = tags_str.substr(0, pos);
488 tag.erase(0, tag.find_first_not_of(
" \t"));
489 tag.erase(tag.find_last_not_of(
" \t") + 1);
493 tags_str.erase(0, pos + 1);
495 if (!tags_str.empty()) {
496 tags_str.erase(0, tags_str.find_first_not_of(
" \t"));
497 tags_str.erase(tags_str.find_last_not_of(
" \t") + 1);
498 if (!tags_str.empty()) {
507 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.133f, 0.545f, 0.133f, 0.8f));
508 ImGui::PushStyleColor(ImGuiCol_ButtonHovered,
509 ImVec4(0.133f, 0.545f, 0.133f, 1.0f));
510 if (ImGui::Button(
ICON_MD_CHECK " Apply & Save Configuration",
529 ImGui::PopStyleColor(2);
538 ImGui::BeginChild(
"ChatStatusCard", ImVec2(0, 100),
true);
539 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
ICON_MD_CHAT " Chat");
543 ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f),
558 ImGui::BeginChild(
"RomStatusCard", ImVec2(0, 100),
true);
559 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
ICON_MD_GAMEPAD " ROM");
563 ImGui::TextColored(ImVec4(0.133f, 0.545f, 0.133f, 1.0f),
565 ImGui::TextDisabled(
"Title: %s",
rom_->
title().c_str());
566 ImGui::TextDisabled(
"Tools: Ready");
568 ImGui::TextColored(ImVec4(0.8f, 0.2f, 0.2f, 1.0f),
570 ImGui::TextDisabled(
"Load ROM for AI tools");
577 ImGui::BeginChild(
"QuickTipsCard", ImVec2(0, 150),
true);
578 ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
583 ImGui::BulletText(
"Ctrl+H: Toggle chat popup");
584 ImGui::BulletText(
"Ctrl+P: View proposals");
585 ImGui::BulletText(
"Edit prompts in center");
586 ImGui::BulletText(
"Create custom bots");
587 ImGui::BulletText(
"Save/load chat sessions");
596 ImGui::TextDisabled(
"View detailed metrics in the Metrics tab");
598 ImGui::TextDisabled(
"No metrics available");
604 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
610 ImGui::Text(
"File:");
611 ImGui::SetNextItemWidth(-45);
613 if (ImGui::Selectable(
"system_prompt.txt",
618 if (ImGui::Selectable(
"system_prompt_v2.txt",
623 if (ImGui::Selectable(
"system_prompt_v3.txt",
635 if (ImGui::IsItemHovered()) {
636 ImGui::SetTooltip(
"Reload from disk");
644 if (content_result.ok()) {
657 std::cerr <<
" Error: " << content_result.status().message() <<
"\n";
660 std::string placeholder = absl::StrFormat(
661 "# System prompt file not found: %s\n"
663 "# Please ensure the file exists in:\n"
664 "# - assets/agent/%s\n"
665 "# - Or Contents/Resources/agent/%s (macOS bundle)\n\n"
666 "# You can create a custom prompt here and save it to your bot "
680 ImVec2 editor_size = ImVec2(ImGui::GetContentRegionAvail().x,
681 ImGui::GetContentRegionAvail().y - 50);
686 if (ImGui::Button(
ICON_MD_SAVE " Save Prompt to Profile", ImVec2(-1, 0))) {
697 "Edit the system prompt that guides the AI agent's behavior. Changes are "
698 "saved to the current bot profile.");
702 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
708 ImGui::BeginChild(
"CurrentProfile", ImVec2(0, 150),
true);
709 ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
717 ImGui::TextWrapped(
"Description: %s",
726 if (ImGui::Button(
ICON_MD_ADD " Create New Profile", ImVec2(-1, 0))) {
729 new_profile.
name =
"New Profile";
742 ImGui::TextColored(ImVec4(0.196f, 0.6f, 0.8f, 1.0f),
746 ImGui::BeginChild(
"ProfilesList", ImVec2(0, 0),
true);
750 "No saved profiles. Create and save a profile to see it here.");
754 ImGui::PushID(
static_cast<int>(i));
758 ImGui::PushStyleColor(ImGuiCol_Button,
759 ImVec4(0.196f, 0.6f, 0.8f, 0.6f));
762 if (ImGui::Button(profile.name.c_str(),
763 ImVec2(ImGui::GetContentRegionAvail().x - 80, 0))) {
767 absl::StrFormat(
"Loaded profile: %s", profile.name),
773 ImGui::PopStyleColor();
777 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.2f, 0.2f, 0.6f));
782 absl::StrFormat(
"Deleted profile: %s", profile.name),
786 ImGui::PopStyleColor();
788 ImGui::TextDisabled(
" %s | %s", profile.provider.c_str(),
789 profile.description.empty()
791 : profile.description.c_str());
802 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
831 ImGui::BeginChild(
"HistoryList", ImVec2(0, 0),
true);
835 "No chat history. Start a conversation in the chat window.");
839 ImVec4 color = from_user ? ImVec4(0.6f, 0.8f, 1.0f, 1.0f)
840 : ImVec4(0.4f, 0.8f, 0.4f, 1.0f);
842 ImGui::PushStyleColor(ImGuiCol_Text, color);
843 ImGui::Text(
"%s:", from_user ?
"User" :
"Agent");
844 ImGui::PopStyleColor();
847 ImGui::TextDisabled(
"%s", absl::FormatTime(
"%H:%M:%S", msg.timestamp,
848 absl::LocalTimeZone())
851 ImGui::TextWrapped(
"%s", msg.message.c_str());
861 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
869 if (ImGui::BeginTable(
"MetricsTable", 2,
870 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
871 ImGui::TableSetupColumn(
"Metric", ImGuiTableColumnFlags_WidthFixed,
873 ImGui::TableSetupColumn(
"Value", ImGuiTableColumnFlags_WidthStretch);
874 ImGui::TableHeadersRow();
876 ImGui::TableNextRow();
877 ImGui::TableSetColumnIndex(0);
879 ImGui::TableSetColumnIndex(1);
880 ImGui::TextDisabled(
"Available in chat session");
882 ImGui::TableNextRow();
883 ImGui::TableSetColumnIndex(0);
885 ImGui::TableSetColumnIndex(1);
886 ImGui::TextDisabled(
"Available in chat session");
888 ImGui::TableNextRow();
889 ImGui::TableSetColumnIndex(0);
891 ImGui::TableSetColumnIndex(1);
892 ImGui::TextDisabled(
"Available in chat session");
894 ImGui::TableNextRow();
895 ImGui::TableSetColumnIndex(0);
897 ImGui::TableSetColumnIndex(1);
898 ImGui::TextDisabled(
"Available in chat session");
905 "Detailed session metrics are available during active chat sessions. "
906 "Open the chat window to see live statistics.");
909 "No metrics available. Initialize the chat system first.");
914 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
920 "Customize the tile reference file that AI uses for tile placement. "
921 "Organize tiles by category and provide hex IDs with descriptions.");
939 if (ImGui::Button(
ICON_MD_SAVE " Save", ImVec2(100, 0))) {
943 " Save to project directory (coming soon)",
952 if (ImGui::IsItemHovered()) {
953 ImGui::SetTooltip(
"Reload from disk");
963 std::string default_tiles =
964 "# Common Tile16 Reference\n"
965 "# Format: 0xHEX = Description\n\n"
967 "0x020 = Grass (standard)\n\n"
969 "0x02E = Tree (oak)\n"
972 "0x14C = Water (top edge)\n"
973 "0x14D = Water (middle)\n";
984 ImVec2 editor_size(ImGui::GetContentRegionAvail().x,
985 ImGui::GetContentRegionAvail().y);
991 ImGui::TextColored(ImVec4(1.0f, 0.843f, 0.0f, 1.0f),
997 "Create a custom system prompt from scratch or use a template.");
1003 ImGui::Text(
"Prompt Name:");
1004 ImGui::SetNextItemWidth(-1);
1005 ImGui::InputTextWithHint(
"##new_prompt_name",
"e.g., custom_prompt.txt",
1011 ImGui::Text(
"Start from template:");
1047 std::string blank_template =
1048 "# Custom System Prompt\n\n"
1049 "You are an AI assistant for ROM hacking.\n\n"
1051 "- Help users understand ROM data\n"
1052 "- Provide accurate information\n"
1053 "- Use tools when needed\n\n"
1054 "## Available Tools\n"
1055 "- resource-list: List resources by type\n"
1056 "- dungeon-describe-room: Get room details\n"
1057 "- overworld-find-tile: Find tile locations\n"
1058 "- ... (see function schemas for complete list)\n\n"
1060 "1. Always provide text_response after tool calls\n"
1061 "2. Be helpful and accurate\n"
1062 "3. Explain your reasoning\n";
1075 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.133f, 0.545f, 0.133f, 0.8f));
1076 if (ImGui::Button(
ICON_MD_SAVE " Save New Prompt", ImVec2(-1, 40))) {
1080 if (!absl::EndsWith(filename,
".txt")) {
1087 absl::StrFormat(
ICON_MD_SAVE " Prompt saved as %s", filename),
1098 ImGui::PopStyleColor();
1102 "Note: New prompts are saved to your project. Use 'System Prompt' tab to "
1103 "edit existing prompts.");
1108#if defined(YAZE_WITH_JSON)
1111 std::filesystem::path profile_path =
1113 std::ofstream file(profile_path);
1114 if (!file.is_open()) {
1115 return absl::InternalError(
"Failed to open profile file for writing");
1124 return absl::OkStatus();
1126 return absl::UnimplementedError(
1127 "JSON support required for profile management");
1132#if defined(YAZE_WITH_JSON)
1133 std::filesystem::path profile_path =
1135 if (!std::filesystem::exists(profile_path)) {
1136 return absl::NotFoundError(absl::StrFormat(
"Profile '%s' not found", name));
1139 std::ifstream file(profile_path);
1140 if (!file.is_open()) {
1141 return absl::InternalError(
"Failed to open profile file");
1144 std::string json_content((std::istreambuf_iterator<char>(file)),
1145 std::istreambuf_iterator<char>());
1162 return absl::OkStatus();
1164 return absl::UnimplementedError(
1165 "JSON support required for profile management");
1170 std::filesystem::path profile_path =
1172 if (!std::filesystem::exists(profile_path)) {
1173 return absl::NotFoundError(absl::StrFormat(
"Profile '%s' not found", name));
1176 std::filesystem::remove(profile_path);
1181 return absl::OkStatus();
1202 const std::filesystem::path& path) {
1203#if defined(YAZE_WITH_JSON)
1204 std::ofstream file(path);
1205 if (!file.is_open()) {
1206 return absl::InternalError(
"Failed to open export file");
1212 return absl::OkStatus();
1214 return absl::UnimplementedError(
"JSON support required");
1219#if defined(YAZE_WITH_JSON)
1220 if (!std::filesystem::exists(path)) {
1221 return absl::NotFoundError(
"Import file not found");
1224 std::ifstream file(path);
1225 if (!file.is_open()) {
1226 return absl::InternalError(
"Failed to open import file");
1229 std::string json_content((std::istreambuf_iterator<char>(file)),
1230 std::istreambuf_iterator<char>());
1237 return absl::UnimplementedError(
"JSON support required");
1243 if (!config_dir.ok()) {
1245 return std::filesystem::current_path() /
".yaze" /
"agent" /
"profiles";
1247 return *config_dir /
"agent" /
"profiles";
1253 std::filesystem::create_directories(dir, ec);
1255 return absl::InternalError(absl::StrFormat(
1256 "Failed to create profiles directory: %s", ec.message()));
1258 return absl::OkStatus();
1262#if defined(YAZE_WITH_JSON)
1263 nlohmann::json json;
1264 json[
"name"] = profile.
name;
1266 json[
"provider"] = profile.
provider;
1267 json[
"model"] = profile.
model;
1271 json[
"verbose"] = profile.
verbose;
1275 json[
"tags"] = profile.
tags;
1276 json[
"created_at"] = absl::FormatTime(absl::RFC3339_full, profile.
created_at,
1277 absl::UTCTimeZone());
1278 json[
"modified_at"] = absl::FormatTime(
1279 absl::RFC3339_full, profile.
modified_at, absl::UTCTimeZone());
1281 return json.dump(2);
1288 const std::string& json_str)
const {
1289#if defined(YAZE_WITH_JSON)
1291 nlohmann::json json = nlohmann::json::parse(json_str);
1294 profile.
name = json.value(
"name",
"Unnamed Profile");
1295 profile.
description = json.value(
"description",
"");
1296 profile.
provider = json.value(
"provider",
"mock");
1297 profile.
model = json.value(
"model",
"");
1298 profile.
ollama_host = json.value(
"ollama_host",
"http://localhost:11434");
1301 profile.
verbose = json.value(
"verbose",
false);
1306 if (json.contains(
"tags") && json[
"tags"].is_array()) {
1307 for (
const auto& tag : json[
"tags"]) {
1308 profile.
tags.push_back(tag.get<std::string>());
1312 if (json.contains(
"created_at")) {
1314 if (absl::ParseTime(absl::RFC3339_full,
1315 json[
"created_at"].get<std::string>(), &created,
1321 if (json.contains(
"modified_at")) {
1322 absl::Time modified;
1323 if (absl::ParseTime(absl::RFC3339_full,
1324 json[
"modified_at"].get<std::string>(), &modified,
1331 }
catch (
const std::exception& e) {
1332 return absl::InternalError(
1333 absl::StrFormat(
"Failed to parse profile JSON: %s", e.what()));
1336 return absl::UnimplementedError(
"JSON support required");
1407 absl::StrFormat(
"Hosting local session: %s", session_name),
1414#ifdef YAZE_WITH_GRPC
1416 if (!network_coordinator_) {
1417 return absl::FailedPreconditionError(
1418 "Network coordinator not initialized. Connect to a server first.");
1421 const char* username = std::getenv(
"USER");
1423 username = std::getenv(
"USERNAME");
1426 username =
"unknown";
1430 network_coordinator_->HostSession(session_name, username));
1444 absl::StrFormat(
"Hosting network session: %s", session_name),
1452 return absl::InvalidArgumentError(
"Unsupported collaboration mode");
1480 absl::StrFormat(
"Joined local session: %s", session_code),
1487#ifdef YAZE_WITH_GRPC
1489 if (!network_coordinator_) {
1490 return absl::FailedPreconditionError(
1491 "Network coordinator not initialized. Connect to a server first.");
1494 const char* username = std::getenv(
"USER");
1496 username = std::getenv(
"USERNAME");
1499 username =
"unknown";
1503 network_coordinator_->JoinSession(session_code, username));
1517 absl::StrFormat(
"Joined network session: %s", session_code),
1525 return absl::InvalidArgumentError(
"Unsupported collaboration mode");
1530 return absl::FailedPreconditionError(
"Not in a session");
1536#ifdef YAZE_WITH_GRPC
1538 if (network_coordinator_) {
1558 return absl::OkStatus();
1563 return absl::FailedPreconditionError(
"Not in a session");
1588 [[maybe_unused]] std::filesystem::path* output_path,
1590 return absl::UnimplementedError(
1591 "CaptureSnapshot should be called through the chat widget UI");
1595 [[maybe_unused]]
const std::filesystem::path& image_path,
1596 [[maybe_unused]]
const std::string& prompt) {
1597 return absl::UnimplementedError(
1598 "SendToGemini should be called through the chat widget UI");
1601#ifdef YAZE_WITH_GRPC
1602absl::Status AgentEditor::ConnectToServer(
const std::string& server_url) {
1604 network_coordinator_ =
1605 std::make_unique<NetworkCollaborationCoordinator>(server_url);
1609 absl::StrFormat(
"Connected to server: %s", server_url),
1613 return absl::OkStatus();
1614 }
catch (
const std::exception& e) {
1615 return absl::InternalError(
1616 absl::StrFormat(
"Failed to connect to server: %s", e.what()));
1620void AgentEditor::DisconnectFromServer() {
1624 network_coordinator_.reset();
1631bool AgentEditor::IsConnectedToServer()
const {
1632 return network_coordinator_ && network_coordinator_->IsConnected();
1646 return std::nullopt;
1663 collab_callbacks.
host_session = [
this](
const std::string& session_name)
1676 collab_callbacks.
join_session = [
this](
const std::string& session_code)
1694 [
this]() -> absl::StatusOr<
1705 chat_widget_->SetCollaborationCallbacks(collab_callbacks);
static absl::StatusOr< std::string > LoadTextFile(const std::string &relative_path)
The Rom class is used to load, save, and modify Rom data.
std::unique_ptr< AgentChatWidget > chat_widget_
std::string current_session_id_
void SetCurrentProfile(const BotProfile &profile)
void ApplyConfig(const AgentConfig &config)
void InitializeWithDependencies(ToastManager *toast_manager, ProposalDrawer *proposal_drawer, Rom *rom)
void DrawAdvancedMetricsPanel()
absl::StatusOr< SessionInfo > JoinSession(const std::string &session_code, CollaborationMode mode=CollaborationMode::kLocal)
void SetRomContext(Rom *rom)
void SetChatActive(bool active)
absl::StatusOr< BotProfile > JsonToProfile(const std::string &json) const
absl::StatusOr< SessionInfo > RefreshSession()
absl::Status ImportProfile(const std::filesystem::path &path)
bool IsChatActive() const
void SetupMultimodalCallbacks()
bool prompt_editor_initialized_
void Initialize() override
ProposalDrawer * proposal_drawer_
bool show_metrics_dashboard_
std::vector< cli::agent::ChatMessage > cached_history_
AgentConfig current_config_
absl::Status Save() override
bool common_tiles_initialized_
std::string current_session_name_
CollaborationMode GetCurrentMode() const
void DrawPromptEditorPanel()
absl::Status SendToGemini(const std::filesystem::path &image_path, const std::string &prompt)
absl::Status EnsureProfilesDirectory()
bool history_needs_refresh_
absl::Status ExportProfile(const BotProfile &profile, const std::filesystem::path &path)
void DrawNewPromptCreator()
CollaborationMode current_mode_
absl::Status SaveBotProfile(const BotProfile &profile)
std::string active_prompt_file_
absl::Status DeleteBotProfile(const std::string &name)
std::filesystem::path GetProfilesDirectory() const
ToastManager * toast_manager_
AgentConfig GetCurrentConfig() const
std::unique_ptr< TextEditor > common_tiles_editor_
absl::StatusOr< SessionInfo > HostSession(const std::string &session_name, CollaborationMode mode=CollaborationMode::kLocal)
void DrawCommonTilesEditor()
char new_prompt_name_[128]
std::string ProfileToJson(const BotProfile &profile) const
absl::Status LeaveSession()
std::unique_ptr< TextEditor > prompt_editor_
std::unique_ptr< AgentCollaborationCoordinator > local_coordinator_
absl::Status CaptureSnapshot(std::filesystem::path *output_path, const CaptureConfig &config)
absl::Status Load() override
BotProfile current_profile_
absl::Status LoadBotProfile(const std::string &name)
std::vector< BotProfile > GetAllProfiles() const
void DrawChatHistoryViewer()
std::vector< std::string > current_participants_
void DrawBotProfilesPanel()
absl::Status Update() override
void DrawConfigurationPanel()
std::vector< BotProfile > loaded_profiles_
std::optional< SessionInfo > GetCurrentSession() const
void SetupChatWidgetCallbacks()
ImGui drawer for displaying and managing agent proposals.
void Show(const std::string &message, ToastType type=ToastType::kInfo, float ttl_seconds=3.0f)
#define ICON_MD_FOLDER_OPEN
#define ICON_MD_VIEW_LIST
#define ICON_MD_FILE_DOWNLOAD
#define ICON_MD_VISIBILITY
#define ICON_MD_TIPS_AND_UPDATES
#define ICON_MD_FILE_UPLOAD
#define ICON_MD_FILE_COPY
#define ICON_MD_CHECK_CIRCLE
#define ICON_MD_OPEN_IN_NEW
#define ICON_MD_ANALYTICS
#define ICON_MD_SMART_TOY
#define RETURN_IF_ERROR(expression)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Main namespace for the application.
static const LanguageDefinition & CPlusPlus()
std::vector< std::string > participants
std::string gemini_api_key
std::vector< std::string > tags
std::string gemini_api_key
std::string system_prompt
std::vector< std::string > participants