68 ImGuiIO& io = ImGui::GetIO();
69 ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x -
drawer_width_, 0),
71 ImGui::SetNextWindowSize(ImVec2(
drawer_width_, io.DisplaySize.y),
74 ImGuiWindowFlags flags = ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize |
75 ImGuiWindowFlags_NoCollapse;
77 if (ImGui::Begin(
"Agent Proposals", &
visible_, flags)) {
96 float list_height = ImGui::GetContentRegionAvail().y * 0.4f;
98 ImGui::BeginChild(
"ProposalList", ImVec2(0, list_height),
true);
104 ImGui::BeginChild(
"ProposalDetail", ImVec2(0, 0),
true);
113 ImGui::OpenPopup(
"Confirm Action");
117 if (ImGui::BeginPopupModal(
"Confirm Action",
nullptr,
118 ImGuiWindowFlags_AlwaysAutoResize)) {
119 ImGui::Text(tr(
"Are you sure you want to %s this proposal?"),
123 if (ImGui::Button(tr(
"Yes"), ImVec2(120, 0))) {
131 ImGui::CloseCurrentPopup();
135 if (ImGui::Button(tr(
"No"), ImVec2(120, 0))) {
136 ImGui::CloseCurrentPopup();
141#ifdef YAZE_ENABLE_POLICY_FRAMEWORK
144 ImGui::OpenPopup(
"Override Policy");
148 if (ImGui::BeginPopupModal(
"Override Policy",
nullptr,
149 ImGuiWindowFlags_AlwaysAutoResize)) {
153 ImGui::TextWrapped(tr(
"This proposal has policy warnings."));
154 ImGui::TextWrapped(tr(
"Do you want to override and accept anyway?"));
157 tr(
"Note: This action will be logged."));
160 if (ImGui::Button(tr(
"Override and Accept"), ImVec2(150, 0))) {
163 ImGui::CloseCurrentPopup();
166 if (ImGui::Button(tr(
"Cancel"), ImVec2(150, 0))) {
167 ImGui::CloseCurrentPopup();
176 ImGui::TextWrapped(tr(
"No proposals found."));
177 ImGui::TextWrapped(tr(
"Run CLI command: z3ed agent run --prompt \"...\""));
181 ImGuiTableFlags flags =
182 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY;
184 if (ImGui::BeginTable(
"ProposalsTable", 3, flags)) {
185 ImGui::TableSetupColumn(
"ID", ImGuiTableColumnFlags_WidthFixed, 60.0f);
186 ImGui::TableSetupColumn(
"Status", ImGuiTableColumnFlags_WidthFixed, 80.0f);
187 ImGui::TableSetupColumn(
"Prompt", ImGuiTableColumnFlags_WidthStretch);
188 ImGui::TableSetupScrollFreeze(0, 1);
189 ImGui::TableHeadersRow();
192 ImGui::TableNextRow();
195 ImGui::TableSetColumnIndex(0);
197 if (ImGui::Selectable(proposal.id.c_str(), is_selected,
198 ImGuiSelectableFlags_SpanAllColumns)) {
203 ImGui::TableSetColumnIndex(1);
204 switch (proposal.status) {
219 ImGui::TableSetColumnIndex(2);
220 std::string truncated = proposal.prompt;
221 if (truncated.length() > 30) {
222 truncated = truncated.substr(0, 27) +
"...";
224 ImGui::TextWrapped(
"%s", truncated.c_str());
238 if (ImGui::CollapsingHeader(tr(
"Metadata"), ImGuiTreeNodeFlags_DefaultOpen)) {
239 ImGui::Text(tr(
"ID: %s"), p.id.c_str());
240 ImGui::Text(tr(
"Sandbox: %s"), p.sandbox_id.c_str());
241 ImGui::Text(tr(
"Created: %s"), absl::FormatTime(p.created_at).c_str());
242 if (p.reviewed_at.has_value()) {
243 ImGui::Text(tr(
"Reviewed: %s"), absl::FormatTime(*p.reviewed_at).c_str());
245 ImGui::Text(tr(
"Commands: %d"), p.commands_executed);
246 ImGui::Text(tr(
"Bytes Changed: %d"), p.bytes_changed);
248 ImGui::TextWrapped(tr(
"Prompt: %s"), p.prompt.c_str());
249 ImGui::TextWrapped(tr(
"Description: %s"), p.description.c_str());
253 if (ImGui::CollapsingHeader(tr(
"Diff"), ImGuiTreeNodeFlags_DefaultOpen)) {
254 if (
diff_content_.empty() && std::filesystem::exists(p.diff_path)) {
255 std::ifstream diff_file(p.diff_path);
256 if (diff_file.is_open()) {
257 std::stringstream buffer;
258 buffer << diff_file.rdbuf();
264 ImGui::BeginChild(
"DiffContent", ImVec2(0, 150),
true,
265 ImGuiWindowFlags_HorizontalScrollbar);
269 ImGui::TextWrapped(tr(
"No diff available"));
274 if (ImGui::CollapsingHeader(tr(
"Execution Log"))) {
275 if (
log_content_.empty() && std::filesystem::exists(p.log_path)) {
276 std::ifstream log_file(p.log_path);
277 if (log_file.is_open()) {
278 std::stringstream buffer;
281 while (std::getline(log_file, line) &&
283 buffer << line <<
"\n";
287 buffer <<
"... (truncated, see " << p.log_path.string() <<
")\n";
294 ImGui::BeginChild(
"LogContent", ImVec2(0, 150),
true,
295 ImGuiWindowFlags_HorizontalScrollbar);
299 ImGui::TextWrapped(tr(
"No log available"));
304#ifdef YAZE_ENABLE_POLICY_FRAMEWORK
325#ifdef YAZE_ENABLE_POLICY_FRAMEWORK
336 if (ImGui::CollapsingHeader(tr(
"Policy Status"),
337 ImGuiTreeNodeFlags_DefaultOpen)) {
340 if (!policy_eval.IsEnabled()) {
344 tr(
"Create .yaze/policies/agent.yaml to enable policy evaluation"));
349 auto policy_result = policy_eval.EvaluateProposal(p.id);
351 if (!policy_result.ok()) {
354 ImGui::TextWrapped(
"%s", policy_result.status().message().data());
358 const auto& result = policy_result.value();
361 if (result.is_clean()) {
364 }
else if (result.passed) {
375 if (!result.critical_violations.empty()) {
378 for (
const auto& violation : result.critical_violations) {
380 ImGui::TextWrapped(
"%s: %s", violation.policy_name.c_str(),
381 violation.message.c_str());
382 if (!violation.details.empty()) {
385 violation.details.c_str());
393 if (!result.warnings.empty()) {
395 for (
const auto& violation : result.warnings) {
397 ImGui::TextWrapped(
"%s: %s", violation.policy_name.c_str(),
398 violation.message.c_str());
399 if (!violation.details.empty()) {
402 violation.details.c_str());
410 if (!result.info.empty()) {
412 for (
const auto& violation : result.info) {
414 ImGui::TextWrapped(
"%s: %s", violation.policy_name.c_str(),
415 violation.message.c_str());
556 auto proposal_or = registry.GetProposal(proposal_id);
557 if (!proposal_or.ok()) {
558 return proposal_or.status();
561 const auto& proposal = *proposal_or;
565 return absl::FailedPreconditionError(
566 "No ROM loaded. Cannot merge proposal changes.");
571 auto sandboxes = sandbox_mgr.ListSandboxes();
573 std::filesystem::path sandbox_rom_path;
574 for (
const auto& sandbox : sandboxes) {
575 if (sandbox.id == proposal.sandbox_id) {
576 sandbox_rom_path = sandbox.rom_path;
581 if (sandbox_rom_path.empty()) {
582 return absl::NotFoundError(
583 absl::StrFormat(
"Sandbox ROM not found for proposal %s (sandbox: %s)",
584 proposal_id, proposal.sandbox_id));
589 if (!std::filesystem::exists(sandbox_rom_path, ec)) {
590 return absl::NotFoundError(absl::StrFormat(
591 "Sandbox ROM file does not exist: %s", sandbox_rom_path.string()));
596 auto load_status = sandbox_rom.
LoadFromFile(sandbox_rom_path.string());
597 if (!load_status.ok()) {
598 return absl::InternalError(absl::StrFormat(
"Failed to load sandbox ROM: %s",
599 load_status.message()));
604 const auto& sandbox_data = sandbox_rom.
vector();
606 if (!merge_status.ok()) {
607 return absl::InternalError(absl::StrFormat(
608 "Failed to merge sandbox ROM data: %s", merge_status.message()));
612 auto status = registry.UpdateStatus(
624 return absl::UnimplementedError(
"AI features disabled");