fix(logging): Update GUI and controller to use correct session log paths and fix syntax errors.

This commit is contained in:
2026-03-06 14:22:41 -05:00
parent 0de50e216b
commit 2cfd0806cf
2 changed files with 86 additions and 159 deletions

View File

@@ -84,14 +84,13 @@ class App:
"""The main ImGui interface orchestrator for Manual Slop."""
def __init__(self) -> None:
# Initialize controller and delegate state
# Initialize controller and delegate state
self.controller = app_controller.AppController()
# Restore legacy PROVIDERS to controller if needed (it already has it via delegation if set on class level, but let's be explicit)
if not hasattr(self.controller, 'PROVIDERS'):
self.controller.PROVIDERS = PROVIDERS
self.controller.init_state()
self.controller.start_services(self)
# Aliases for controller-owned locks
self._send_thread_lock = self.controller._send_thread_lock
self._disc_entries_lock = self.controller._disc_entries_lock
@@ -101,7 +100,6 @@ class App:
self._pending_gui_tasks_lock = self.controller._pending_gui_tasks_lock
self._pending_dialog_lock = self.controller._pending_dialog_lock
self._api_event_queue_lock = self.controller._api_event_queue_lock
self._discussion_names_cache: list[str] = []
self._discussion_names_dirty: bool = True
@@ -145,10 +143,8 @@ class App:
@current_model.setter
def current_model(self, value: str) -> None:
self.controller.current_model = value
# ---------------------------------------------------------------- project loading
# ---------------------------------------------------------------- logic
# ---------------------------------------------------------------- project loading
# ---------------------------------------------------------------- logic
def shutdown(self) -> None:
"""Cleanly shuts down the app's background tasks and saves state."""
@@ -160,14 +156,7 @@ class App:
os.makedirs("tests/artifacts", exist_ok=True)
with open("tests/artifacts/temp_callback_output.txt", "w") as f:
f.write(data)
# ---------------------------------------------------------------- helpers
# ---------------------------------------------------------------- helpers
def _render_text_viewer(self, label: str, content: str) -> None:
if imgui.button("[+]##" + str(id(content))):
@@ -239,10 +228,10 @@ class App:
# Process GUI task queue
# DEBUG: Check if tasks exist before processing
if hasattr(self, 'controller') and hasattr(self.controller, '_pending_gui_tasks'):
pending_count = len(self.controller._pending_gui_tasks)
if pending_count > 0:
sys.stderr.write(f"[DEBUG gui_2] _gui_func: found {pending_count} pending tasks\n")
sys.stderr.flush()
pending_count = len(self.controller._pending_gui_tasks)
if pending_count > 0:
sys.stderr.write(f"[DEBUG gui_2] _gui_func: found {pending_count} pending tasks\n")
sys.stderr.flush()
self._process_pending_gui_tasks()
self._process_pending_history_adds()
self._render_track_proposal_modal()
@@ -336,7 +325,7 @@ class App:
imgui.begin_child("HistoryChild", size=(0, -200))
self._render_discussion_panel()
imgui.end_child()
# Bottom part with tabs for message and response
# Bottom part with tabs for message and response
if imgui.begin_tab_bar("MessageResponseTabs"):
if imgui.begin_tab_item("Message")[0]:
self._render_message_panel()
@@ -738,10 +727,6 @@ class App:
if imgui.button('Plan Epic (Tier 1)', imgui.ImVec2(-1, 0)):
self._cb_plan_epic()
def _render_track_proposal_modal(self) -> None:
if self._show_track_proposal_modal:
imgui.open_popup("Track Proposal")
@@ -756,15 +741,15 @@ class App:
imgui.text("No tracks generated.")
else:
for idx, track in enumerate(self.proposed_tracks):
# Title Edit
# Title Edit
changed_t, new_t = imgui.input_text(f"Title##{idx}", track.get('title', ''))
if changed_t:
track['title'] = new_t
# Goal Edit
# Goal Edit
changed_g, new_g = imgui.input_text_multiline(f"Goal##{idx}", track.get('goal', ''), imgui.ImVec2(-1, 60))
if changed_g:
track['goal'] = new_g
# Buttons
# Buttons
if imgui.button(f"Remove##{idx}"):
self.proposed_tracks.pop(idx)
break
@@ -788,7 +773,7 @@ class App:
if not exp:
imgui.end()
return
registry = log_registry.LogRegistry("logs/log_registry.toml")
registry = log_registry.LogRegistry("logs/sessions/log_registry.toml")
sessions = registry.data
if imgui.begin_table("sessions_table", 7, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg | imgui.TableFlags_.resizable):
imgui.table_setup_column("Session ID")
@@ -1218,7 +1203,6 @@ class App:
toks = msg.get("tokens", 0)
imgui.text_disabled(f" [{role}] ~{toks:,} tokens")
shown += 1
imgui.separator()
if ai_client._provider == "gemini":
if ai_client._gemini_cache is not None:
@@ -1307,11 +1291,6 @@ class App:
if is_blinking:
imgui.pop_style_color(2)
def _render_tool_calls_panel(self) -> None:
imgui.text("Tool call history")
imgui.same_line()
@@ -1349,7 +1328,7 @@ class App:
imgui.begin_child(f"tc_script_fixed_width_{i}", imgui.ImVec2(0, 72), True, imgui.WindowFlags_.horizontal_scrollbar)
imgui.input_text_multiline(f"##tc_script_res_{i}", script, imgui.ImVec2(-1, -1), imgui.InputTextFlags_.read_only)
imgui.end_child()
# Result Display
# Result Display
imgui.text_colored(C_LBL, "Output:")
imgui.same_line()
if imgui.button(f"[+]##output_{i}"):
@@ -1370,7 +1349,7 @@ class App:
imgui.end_child()
def _render_mma_dashboard(self) -> None:
# Task 5.3: Dense Summary Line
# Task 5.3: Dense Summary Line
track_name = self.active_track.description if self.active_track else "None"
total_tickets = len(self.active_tickets)
done_tickets = sum(1 for t in self.active_tickets if t.get('status') == 'complete')
@@ -1380,7 +1359,6 @@ class App:
in_t = stats.get('input', 0)
out_t = stats.get('output', 0)
total_cost += cost_tracker.estimate_cost(model, in_t, out_t)
imgui.text("Track:")
imgui.same_line()
imgui.text_colored(C_VAL, track_name)
@@ -1402,7 +1380,6 @@ class App:
elif self.mma_status == "error": status_col = imgui.ImVec4(1, 0, 0, 1)
imgui.text_colored(status_col, self.mma_status.upper())
imgui.separator()
# 0. Conductor Setup
if imgui.collapsing_header("Conductor Setup"):
if imgui.button("Run Setup Scan"):
@@ -1410,7 +1387,7 @@ class App:
if self.ui_conductor_setup_summary:
imgui.input_text_multiline("##setup_summary", self.ui_conductor_setup_summary, imgui.ImVec2(-1, 120), imgui.InputTextFlags_.read_only)
imgui.separator()
# 1. Track Browser
# 1. Track Browser
imgui.text("Track Browser")
if imgui.begin_table("mma_tracks_table", 4, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg | imgui.TableFlags_.resizable):
imgui.table_setup_column("Title")
@@ -1449,8 +1426,7 @@ class App:
if imgui.button(f"Load##{track.get('id')}"):
self._cb_load_track(str(track.get("id") or ""))
imgui.end_table()
# 1b. New Track Form
# 1b. New Track Form
imgui.text("Create New Track")
changed_n, self.ui_new_track_name = imgui.input_text("Name##new_track", self.ui_new_track_name)
changed_d, self.ui_new_track_desc = imgui.input_text_multiline("Description##new_track", self.ui_new_track_desc, imgui.ImVec2(-1, 60))
@@ -1465,7 +1441,6 @@ class App:
self._cb_create_track(self.ui_new_track_name, self.ui_new_track_desc, self.ui_new_track_type)
self.ui_new_track_name = ""
self.ui_new_track_desc = ""
imgui.separator()
# 2. Global Controls
changed, self.mma_step_mode = imgui.checkbox("Step Mode (HITL)", self.mma_step_mode)
@@ -1477,7 +1452,7 @@ class App:
if self.active_tier:
imgui.same_line()
imgui.text_colored(C_VAL, f"| Active: {self.active_tier}")
# Approval pending indicator
# Approval pending indicator
any_pending = (
self._pending_mma_spawn is not None or
self._pending_mma_approval is not None or
@@ -1532,8 +1507,7 @@ class App:
cost = cost_tracker.estimate_cost(model, in_t, out_t)
total_cost += cost
imgui.text(f"${cost:,.4f}")
# Total Row
# Total Row
imgui.table_next_row()
imgui.table_set_bg_color(imgui.TableBgTarget_.row_bg0, imgui.get_color_u32(imgui.Col_.plot_lines_hovered))
imgui.table_next_column()
@@ -1582,13 +1556,12 @@ class App:
rendered: set[str] = set()
for root in roots:
self._render_ticket_dag_node(root, tickets_by_id, children_map, rendered)
# 5. Add Ticket Form
# 5. Add Ticket Form
imgui.separator()
if imgui.button("Add Ticket"):
self._show_add_ticket_form = not self._show_add_ticket_form
if self._show_add_ticket_form:
# Default Ticket ID
# Default Ticket ID
max_id = 0
for t in self.active_tickets:
tid = t.get('id', '')
@@ -1599,7 +1572,6 @@ class App:
self.ui_new_ticket_desc = ""
self.ui_new_ticket_target = ""
self.ui_new_ticket_deps = ""
if self._show_add_ticket_form:
imgui.begin_child("add_ticket_form", imgui.ImVec2(-1, 220), True)
imgui.text_colored(C_VAL, "New Ticket Details")
@@ -1607,7 +1579,6 @@ class App:
_, self.ui_new_ticket_desc = imgui.input_text_multiline("Description##new_ticket", self.ui_new_ticket_desc, imgui.ImVec2(-1, 60))
_, self.ui_new_ticket_target = imgui.input_text("Target File##new_ticket", self.ui_new_ticket_target)
_, self.ui_new_ticket_deps = imgui.input_text("Depends On (IDs, comma-separated)##new_ticket", self.ui_new_ticket_deps)
if imgui.button("Create"):
new_ticket = {
"id": self.ui_new_ticket_id,
@@ -1871,7 +1842,6 @@ class App:
def _render_theme_panel(self) -> None:
exp, opened = imgui.begin("Theme", self.show_windows["Theme"])
self.show_windows["Theme"] = bool(opened)
if exp:
imgui.text("Palette")
cp = theme.get_current_palette()
@@ -1919,7 +1889,6 @@ class App:
def run(self) -> None:
"""Initializes the ImGui runner and starts the main application loop."""
if "--headless" in sys.argv:
print("Headless mode active")
self._fetch_models(self.current_provider)