From e376cc99a897949b54aecc47c67164d525b6fadd Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 12 Jun 2026 22:16:06 -0400 Subject: [PATCH] Add SSDL-style docstrings to Core Interaction Loop panels (comms history, message input, response stream, tool calls, and script approval) --- project_history.toml | 2 +- src/gui_2.py | 131 +++++++++++++++++++++++++++++++------------ 2 files changed, 95 insertions(+), 38 deletions(-) diff --git a/project_history.toml b/project_history.toml index 5e65c9cc..daf2adc0 100644 --- a/project_history.toml +++ b/project_history.toml @@ -9,5 +9,5 @@ active = "main" [discussions.main] git_commit = "" -last_updated = "2026-06-12T22:10:33" +last_updated = "2026-06-12T22:15:59" history = [] diff --git a/src/gui_2.py b/src/gui_2.py index 245047bb..a0cecbc7 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -191,22 +191,22 @@ def _detect_refresh_rate_win32() -> float: from ctypes import wintypes class _DEVMODE(ctypes.Structure): _fields_ = [ - ("dmDeviceName", wintypes.WCHAR * 32), ("dmSpecVersion", wintypes.WORD), - ("dmDriverVersion", wintypes.WORD), ("dmSize", wintypes.WORD), - ("dmDriverExtra", wintypes.WORD), ("dmFields", wintypes.DWORD), - ("dmStuff", ctypes.c_byte * 16), ("dmColor", wintypes.SHORT), - ("dmDuplex", wintypes.SHORT), ("dmYResolution", wintypes.SHORT), - ("dmTTOption", wintypes.SHORT), ("dmCollate", wintypes.SHORT), - ("dmFormName", wintypes.WCHAR * 32), ("dmLogPixels", wintypes.WORD), - ("dmBitsPerPel", wintypes.DWORD), ("dmPelsWidth", wintypes.DWORD), - ("dmPelsHeight", wintypes.DWORD), ("dmDisplayFlags", wintypes.DWORD), - ("dmDisplayFrequency", wintypes.DWORD), ("dmICMMethod", wintypes.DWORD), - ("dmICMIntent", wintypes.DWORD), ("dmMediaType", wintypes.DWORD), - ("dmDitherType", wintypes.DWORD), ("dmReserved1", wintypes.DWORD), - ("dmReserved2", wintypes.DWORD), ("dmPanningWidth", wintypes.DWORD), - ("dmPanningHeight", wintypes.DWORD), + ("dmDeviceName", wintypes.WCHAR * 32), ("dmSpecVersion", wintypes.WORD), + ("dmDriverVersion", wintypes.WORD), ("dmSize", wintypes.WORD), + ("dmDriverExtra", wintypes.WORD), ("dmFields", wintypes.DWORD), + ("dmStuff", ctypes.c_byte * 16), ("dmColor", wintypes.SHORT), + ("dmDuplex", wintypes.SHORT), ("dmYResolution", wintypes.SHORT), + ("dmTTOption", wintypes.SHORT), ("dmCollate", wintypes.SHORT), + ("dmFormName", wintypes.WCHAR * 32), ("dmLogPixels", wintypes.WORD), + ("dmBitsPerPel", wintypes.DWORD), ("dmPelsWidth", wintypes.DWORD), + ("dmPelsHeight", wintypes.DWORD), ("dmDisplayFlags", wintypes.DWORD), + ("dmDisplayFrequency", wintypes.DWORD), ("dmICMMethod", wintypes.DWORD), + ("dmICMIntent", wintypes.DWORD), ("dmMediaType", wintypes.DWORD), + ("dmDitherType", wintypes.DWORD), ("dmReserved1", wintypes.DWORD), + ("dmReserved2", wintypes.DWORD), ("dmPanningWidth", wintypes.DWORD), + ("dmPanningHeight", wintypes.DWORD), ] - dm = _DEVMODE() + dm = _DEVMODE() dm.dmSize = ctypes.sizeof(_DEVMODE) if ctypes.windll.user32.EnumDisplaySettingsW(None, -1, ctypes.byref(dm)): # dmDisplayFrequency is 0 or 1 for "default/hardware" on some drivers. @@ -256,7 +256,6 @@ def _apply_runtime_caps_override(app: "App", caps: "VendorCapabilities") -> "Ven return replace(caps, local=True) return caps - def _render_v2_capability_badges(caps: "VendorCapabilities") -> None: """Render small colored badges for the 11 v2 capability flags. @@ -272,30 +271,28 @@ def _render_v2_capability_badges(caps: "VendorCapabilities") -> None: which are already gated elsewhere in the GUI. """ badged_fields: list[tuple[str, str]] = [ - ("reasoning", "Reasoning"), + ("reasoning", "Reasoning"), ("structured_output", "JSON"), - ("code_execution", "Code"), - ("web_search", "Web"), - ("x_search", "X"), - ("file_search", "File"), - ("mcp_support", "MCP"), - ("audio", "Audio"), - ("video", "Video"), - ("grounding", "Ground"), - ("computer_use", "Comp"), + ("code_execution", "Code"), + ("web_search", "Web"), + ("x_search", "X"), + ("file_search", "File"), + ("mcp_support", "MCP"), + ("audio", "Audio"), + ("video", "Video"), + ("grounding", "Ground"), + ("computer_use", "Comp"), ] enabled: list[tuple[str, str]] = [] for field_name, label in badged_fields: if getattr(caps, field_name, False): enabled.append((field_name, label)) - if not enabled: - return + if not enabled: return imgui.text("Capabilities") for field_name, label in enabled: - imgui.same_line() - imgui.text_colored(theme.get_color("status_success"), f" [{label}]") - if imgui.is_item_hovered(): - imgui.set_tooltip(f"caps.{field_name}=True") + imgui.same_line(); imgui.text_colored(theme.get_color("status_success"), f" [{label}]") + if imgui.is_item_hovered(): imgui.set_tooltip(f"caps.{field_name}=True") + class App: """The main ImGui interface orchestrator for Manual Slop.""" @@ -337,10 +334,10 @@ class App: from src.hot_reloader import HotReloader, HotModule if 'src.gui_2' not in HotReloader.HOT_MODULES: HotReloader.register(HotModule( - name='src.gui_2', - file_path=__file__, - state_keys=['active_discussion', 'show_windows', 'ui_file_paths', 'ui_screenshot_paths', 'disc_entries', 'disc_roles'], - delegation_targets=['_render_main_interface', '_render_discussion_hub', '_render_files_and_media', '_render_ai_settings_hub', '_render_operations_hub', '_render_mma_dashboard'] + name = 'src.gui_2', + file_path = __file__, + state_keys = ['active_discussion', 'show_windows', 'ui_file_paths', 'ui_screenshot_paths', 'disc_entries', 'disc_roles'], + delegation_targets = ['_render_main_interface', '_render_discussion_hub', '_render_files_and_media', '_render_ai_settings_hub', '_render_operations_hub', '_render_mma_dashboard'] )) with startup_profiler.phase("app_init_workspace"): @@ -4772,6 +4769,17 @@ def render_synthesis_panel(app: App) -> None: app._handle_generate_send() def render_comms_history_panel(app: App) -> None: + """ + Renders the communications history log panel. Displays outgoing requests, incoming responses, + and tool call inputs/outputs in chronological order. + + State Mutations: + app._comms_log_dirty (marks log for reload) + app._comms_log (clears log on user clear request) + + SSDL Shape: + `[I:ai_status] -> [B:clear_exit_buttons] -> [I:direction_colors] -> [I:entries_scroll_list]` + """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_comms_history_panel") st_col = theme.get_color("text_disabled") if theme.is_nerv_active(): st_col = theme.get_color("status_success") # DATA_GREEN for status in NERV @@ -5203,6 +5211,18 @@ def render_vendor_state(app: App) -> None: # TODO(Ed): Shouldn't this just be a imgui.end_table() def render_message_panel(app: App) -> None: + """ + Renders user message text input area, exposing buttons to generate assistant responses, + inject contextual files, or reset active conversation sessions. + + State Mutations: + app.ui_ai_input (stores user message content) + app.show_inject_modal (triggers inject modal visibility) + app.disc_entries (appends user message to history) + + SSDL Shape: + `[I:live_indicator] -> [I:input_textbox] -> [B:gen_send_buttons] -> [B:inject_reset]` + """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_message_panel") # LIVE indicator is_live = app.ai_status in ["running powershell...", "fetching url...", "searching web...", "powershell done, awaiting AI..."] @@ -5241,6 +5261,17 @@ def render_message_panel(app: App) -> None: if app.perf_profiling_enabled: app.perf_monitor.end_component("_render_message_panel") def render_response_panel(app: App) -> None: + """ + Renders assistant stream output panel. Renders thinking traces, markdown segments, + and exports active responses to history entries. + + State Mutations: + app._trigger_blink, app._is_blinking, app._blink_start_time (visual transition indicators) + app.disc_entries (appends generated responses to history) + + SSDL Shape: + `[I:response_text] -> [I:thinking_trace] -> [I:markdown_view] => [B:export_to_history]` + """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_response_panel") if app._trigger_blink: app._trigger_blink = False @@ -5281,6 +5312,20 @@ def render_response_panel(app: App) -> None: if app.perf_profiling_enabled: app.perf_monitor.end_component("_render_response_panel") def render_tool_calls_panel(app: App) -> None: + """ + Renders tool call execution log. Displays script execution details, status codes, + and outputs in a table. + + State Mutations: + app._tool_log (clears tool log) + app._tool_log_dirty (marks tool log for reload) + app.text_viewer_title, app.text_viewer_content, app.text_viewer_type (triggers text viewer) + app.show_windows["Text Viewer"] + app._scroll_tool_calls_to_bottom + + SSDL Shape: + `[I:tool_log] -> [B:clear_button] => [I:calls_table]` + """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_tool_calls_panel") imgui.text("Tool call history") imgui.same_line() @@ -5576,7 +5621,19 @@ def render_external_editor_panel(app: App) -> None: imgui.text_colored(C_TC(), f"Error: {str(e)}") def render_approve_script_modal(app: App) -> None: - """Renders the modal dialog for approving AI-generated PowerShell scripts.""" + """ + Renders the modal dialog for approving AI-generated PowerShell scripts. + Supports full script editing or markdown code blocks preview. + + State Mutations: + app._pending_dialog_open + app.ui_approve_modal_preview + dlg._script (allows direct script mutation prior to approval) + app._pending_dialog (resets active pending dialog lock) + + SSDL Shape: + `[I:command_details] -> [B:preview_checkbox] -> [I:preview_box_or_editor] => [B:approve_reject]` + """ with app._pending_dialog_lock: dlg = app._pending_dialog if dlg: