diff --git a/config.toml b/config.toml index d22d4596..a6e8ed35 100644 --- a/config.toml +++ b/config.toml @@ -21,11 +21,11 @@ active = "C:/projects/Pikuma/ps1-ai/pikuma_ps1.toml" [gui] separate_message_panel = true separate_response_panel = true -separate_tool_calls_panel = false +separate_tool_calls_panel = true bg_shader_enabled = false crt_filter_enabled = false separate_task_dag = false -separate_usage_analytics = false +separate_usage_analytics = true separate_tier1 = false separate_tier2 = false separate_tier3 = false @@ -38,7 +38,7 @@ separate_external_tools = false "AI Settings" = true "MMA Dashboard" = false "Task DAG" = false -"Usage Analytics" = false +"Usage Analytics" = true "Tier 1" = false "Tier 2" = false "Tier 3" = false @@ -51,7 +51,7 @@ separate_external_tools = false "Operations Hub" = true Message = true Response = true -"Tool Calls" = false +"Tool Calls" = true "Text Viewer" = false Theme = true "Log Management" = true @@ -66,7 +66,7 @@ palette = "Nord Dark" font_path = "C:/projects/manual_slop/assets/fonts/MapleMono-Regular.ttf" font_size = 20.0 scale = 1.0 -transparency = 1.0 +transparency = 0.46000000834465027 child_transparency = 1.0 [mma] diff --git a/manualslop_layout.ini b/manualslop_layout.ini index 2433ae47..b3c484ff 100644 --- a/manualslop_layout.ini +++ b/manualslop_layout.ini @@ -44,22 +44,22 @@ Collapsed=0 DockId=0x00000010,0 [Window][Message] -Pos=1427,28 -Size=2077,2063 +Pos=1144,28 +Size=1769,1701 Collapsed=0 DockId=0x00000006,0 [Window][Response] Pos=0,28 -Size=1425,2063 +Size=1142,1701 Collapsed=0 -DockId=0x00000010,4 +DockId=0x00000010,5 [Window][Tool Calls] -Pos=591,28 -Size=1777,1410 +Pos=1144,28 +Size=1769,1701 Collapsed=0 -DockId=0x0000000E,0 +DockId=0x00000006,3 [Window][Comms History] ViewportPos=43,95 @@ -77,7 +77,7 @@ DockId=0xAFC85805,2 [Window][Theme] Pos=0,28 -Size=1425,2063 +Size=1142,1701 Collapsed=0 DockId=0x00000010,3 @@ -96,7 +96,7 @@ DockId=0x00000006,3 Pos=0,975 Size=1010,730 Collapsed=0 -DockId=0x00000007,0 +DockId=0x0000000B,0 [Window][AI Settings Hub] Pos=406,17 @@ -105,26 +105,26 @@ Collapsed=0 DockId=0x0000000D,0 [Window][Discussion Hub] -Pos=1427,28 -Size=2077,2063 +Pos=1144,28 +Size=1769,1701 Collapsed=0 DockId=0x00000006,1 [Window][Operations Hub] Pos=0,28 -Size=1425,2063 +Size=1142,1701 +Collapsed=0 +DockId=0x00000010,4 + +[Window][Files & Media] +Pos=0,28 +Size=1142,1701 Collapsed=0 DockId=0x00000010,2 -[Window][Files & Media] -Pos=1427,28 -Size=2077,2063 -Collapsed=0 -DockId=0x00000006,2 - [Window][AI Settings] Pos=0,28 -Size=1425,2063 +Size=1142,1701 Collapsed=0 DockId=0x00000010,1 @@ -140,10 +140,10 @@ Collapsed=0 DockId=0x00000006,2 [Window][Log Management] -Pos=1427,28 -Size=2077,2063 +Pos=1144,28 +Size=1769,1701 Collapsed=0 -DockId=0x00000006,3 +DockId=0x00000006,2 [Window][Track Proposal] Pos=709,326 @@ -332,10 +332,9 @@ Size=967,499 Collapsed=0 [Window][Usage Analytics] -Pos=1529,28 -Size=705,1570 -Collapsed=0 -DockId=0x00000006,2 +Pos=605,71 +Size=369,459 +Collapsed=1 [Window][Tool Preset Manager] Pos=516,112 @@ -344,7 +343,7 @@ Collapsed=0 [Window][Persona Editor] Pos=329,138 -Size=1572,1019 +Size=1823,1516 Collapsed=0 [Window][Prompt Presets Manager] @@ -353,7 +352,7 @@ Size=1569,655 Collapsed=0 [Window][External Tools] -Pos=531,376 +Pos=1148,346 Size=616,409 Collapsed=0 @@ -411,7 +410,7 @@ DockId=0x00000006,1 [Window][Project Settings] Pos=0,28 -Size=1425,2063 +Size=1142,1701 Collapsed=0 DockId=0x00000010,0 @@ -497,13 +496,13 @@ Size=1780,1669 Collapsed=0 [Window][Context Preview] -Pos=894,28 -Size=1474,1410 +Pos=1360,28 +Size=1561,1677 Collapsed=0 -DockId=0x00000006,0 +DockId=0x00000006,4 [Window][Text Viewer] -Pos=922,455 +Pos=95,448 Size=658,469 Collapsed=0 @@ -513,12 +512,12 @@ Size=900,700 Collapsed=0 [Window][###Text_Viewer] -Pos=1859,273 -Size=1191,973 +Pos=58,169 +Size=1801,1532 Collapsed=0 [Window][Structural File Editor] -Pos=548,493 +Pos=549,493 Size=1400,900 Collapsed=0 @@ -686,20 +685,18 @@ Column 0 Width=495 Column 1 Weight=1.0000 [Docking][Data] -DockNode ID=0x00000008 Pos=3125,170 Size=593,1157 Split=Y - DockNode ID=0x00000009 Parent=0x00000008 SizeRef=1029,147 Selected=0x0469CA7A - DockNode ID=0x0000000A Parent=0x00000008 SizeRef=1029,145 Selected=0xDF822E02 -DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,28 Size=3504,2063 Split=X - DockNode ID=0x00000003 Parent=0xAFC85805 SizeRef=2357,1183 Split=X - DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=X Selected=0xF4139CA2 - DockNode ID=0x00000007 Parent=0x0000000B SizeRef=1512,858 Split=X Selected=0x8CA2375C - DockNode ID=0x00000005 Parent=0x00000007 SizeRef=1425,1681 Split=Y Selected=0x3F1379AF - DockNode ID=0x00000010 Parent=0x00000005 SizeRef=983,1140 CentralNode=1 Selected=0x418C7449 - DockNode ID=0x00000011 Parent=0x00000005 SizeRef=983,184 Selected=0x432BAE4E - DockNode ID=0x00000006 Parent=0x00000007 SizeRef=2077,1681 Selected=0x66CFB56E - DockNode ID=0x0000000E Parent=0x0000000B SizeRef=1777,858 Selected=0x1D56B311 - DockNode ID=0x0000000D Parent=0x00000003 SizeRef=435,1186 Selected=0x363E93D6 - DockNode ID=0x00000004 Parent=0xAFC85805 SizeRef=488,1183 Selected=0x3AEC3498 +DockNode ID=0x00000008 Pos=3125,170 Size=593,1157 Split=Y + DockNode ID=0x00000009 Parent=0x00000008 SizeRef=1029,147 Selected=0x0469CA7A + DockNode ID=0x0000000A Parent=0x00000008 SizeRef=1029,145 Selected=0xDF822E02 +DockSpace ID=0xAFC85805 Window=0x079D3A04 Pos=0,28 Size=2913,1701 Split=X + DockNode ID=0x00000003 Parent=0xAFC85805 SizeRef=2357,1183 Split=X + DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=X Selected=0xF4139CA2 + DockNode ID=0x00000005 Parent=0x0000000B SizeRef=1142,1681 Split=Y Selected=0x3F1379AF + DockNode ID=0x00000010 Parent=0x00000005 SizeRef=983,1140 CentralNode=1 Selected=0x0D5A5273 + DockNode ID=0x00000011 Parent=0x00000005 SizeRef=983,184 Selected=0x432BAE4E + DockNode ID=0x00000006 Parent=0x0000000B SizeRef=1769,1681 Selected=0x66CFB56E + DockNode ID=0x0000000D Parent=0x00000003 SizeRef=435,1186 Selected=0x363E93D6 + DockNode ID=0x00000004 Parent=0xAFC85805 SizeRef=488,1183 Selected=0x3AEC3498 ;;;<<>>;;; ;;;<<>>;;; diff --git a/src/discussion_entry_renderer.py b/src/discussion_entry_renderer.py index d894b8d1..d2438853 100644 --- a/src/discussion_entry_renderer.py +++ b/src/discussion_entry_renderer.py @@ -53,7 +53,7 @@ def render_thinking_trace(app: 'App', entry: dict, segments: list[dict], entry_i def render_discussion_entry(app: 'App', entry: dict, index: int) -> None: with imscope.id(f"disc_{index}"): role = entry.get("role", "User") - bg_col = get_role_tint(role) + bg_col = theme.get_role_tint(role) draw_list = imgui.get_window_draw_list() p_min = imgui.get_cursor_screen_pos() @@ -122,8 +122,8 @@ def render_discussion_entry(app: 'App', entry: dict, index: int) -> None: imgui.end_group() - # 2. Draw Background Rectangle - draw_list.channels_set_current(0) # Background + # Finalize Background Tint + draw_list.channels_set_current(0) p_max = imgui.get_item_rect_max() # Ensure full width coverage p_max.x = p_min.x + full_width + imgui.get_style().window_padding.x diff --git a/src/gui_2.py b/src/gui_2.py index ec8d9540..2632b8d0 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -1275,7 +1275,8 @@ def render_main_interface(app: App) -> None: app._render_window_if_open("Log Management", lambda: render_log_management(app)) app._render_window_if_open("Diagnostics", lambda: render_diagnostics_panel(app)) app._render_window_if_open("Context Preview", lambda: render_context_preview_window(app)) - app._render_window_if_open("Text Viewer", lambda: render_text_viewer_window(app)) + + render_text_viewer_window(app) app.perf_monitor.end_frame() @@ -1498,7 +1499,7 @@ def render_token_budget_panel(app: App) -> None: usage = app.session_usage total = usage["input_tokens"] + usage["output_tokens"] if total == 0 and usage.get("total_tokens", 0) > 0: total = usage["total_tokens"] - render_selectable_label(app, "session_telemetry_tokens", f"Tokens: {total:,} (In: {usage['input_tokens']:,} Out: {usage['output_tokens']:,})", width=-1, color=C_RES) + ui_shared.render_selectable_label(app, "session_telemetry_tokens", f"Tokens: {total:,} (In: {usage['input_tokens']:,} Out: {usage['output_tokens']:,})", width=-1, color=C_RES) if usage.get("last_latency", 0.0) > 0: imgui.text_colored(C_LBL, f" Last Latency: {usage['last_latency']:.2f}s") if usage["cache_read_input_tokens"]: imgui.text_colored(C_LBL, f" Cache Read: {usage['cache_read_input_tokens']:,} Creation: {usage['cache_creation_input_tokens']:,}") if app._gemini_cache_text: imgui.text_colored(C_SUB, app._gemini_cache_text) @@ -1555,13 +1556,13 @@ def render_token_budget_panel(app: App) -> None: tokens = in_t + out_t cost = cost_tracker.estimate_cost(model, in_t, out_t) imgui.table_next_row() - imgui.table_set_column_index(0); render_selectable_label(app, f"tier_{tier}", tier, width=-1) - imgui.table_set_column_index(1); render_selectable_label(app, f"model_{tier}", model.split("-")[0], width=-1) - imgui.table_set_column_index(2); render_selectable_label(app, f"tokens_{tier}", f"{tokens:,}", width=-1) - imgui.table_set_column_index(3); render_selectable_label(app, f"cost_{tier}", f"${cost:.4f}", width=-1, color=imgui.ImVec4(0.2, 0.9, 0.2, 1)) + imgui.table_set_column_index(0); ui_shared.render_selectable_label(app, f"tier_{tier}", tier, width=-1) + imgui.table_set_column_index(1); ui_shared.render_selectable_label(app, f"model_{tier}", model.split("-")[0], width=-1) + imgui.table_set_column_index(2); ui_shared.render_selectable_label(app, f"tokens_{tier}", f"{tokens:,}", width=-1) + imgui.table_set_column_index(3); ui_shared.render_selectable_label(app, f"cost_{tier}", f"${cost:.4f}", width=-1, color=imgui.ImVec4(0.2, 0.9, 0.2, 1)) imgui.end_table() tier_total = sum(cost_tracker.estimate_cost(stats.get('model', ''), stats.get('input', 0), stats.get('output', 0)) for stats in app.mma_tier_usage.values()) - render_selectable_label(app, "session_total_cost", f"Session Total: ${tier_total:.4f}", width=-1, color=imgui.ImVec4(0, 1, 0, 1)) + ui_shared.render_selectable_label(app, "session_total_cost", f"Session Total: ${tier_total:.4f}", width=-1, color=imgui.ImVec4(0, 1, 0, 1)) else: imgui.text_disabled("No MMA tier usage data") if stats.get("would_trim"): @@ -2003,7 +2004,7 @@ def render_provider_panel(app: App) -> None: imgui.text("Gemini CLI") sid = "None" if hasattr(ai_client, "_gemini_cli_adapter") and ai_client._gemini_cli_adapter: sid = ai_client._gemini_cli_adapter.session_id or "None" - imgui.text("Session ID:"); imgui.same_line(); render_selectable_label(app, "gemini_cli_sid", sid, width=200) + imgui.text("Session ID:"); imgui.same_line(); ui_shared.render_selectable_label(app, "gemini_cli_sid", sid, width=200) if imgui.button("Reset CLI Session"): ai_client.reset_session() imgui.text("Binary Path") ch, app.ui_gemini_cli_path = imgui.input_text("##gcli_path", app.ui_gemini_cli_path) @@ -3130,7 +3131,7 @@ def render_thinking_trace(app: App, entry: dict, segments: list[dict], entry_ind else: imgui.text(content) else: - render_selectable_label(app, f"think_text_{entry_index}_{idx}", content, multiline=True, height=-1) + ui_shared.render_selectable_label(app, f"think_text_{entry_index}_{idx}", content, multiline=True, height=-1) imgui.separator() def render_discussion_entry(app: App, entry: dict, index: int) -> None: @@ -3581,7 +3582,7 @@ def render_discussion_metadata(app: App) -> None: imgui.separator() imgui.text_colored(C_LBL, "commit:"); imgui.same_line() - render_selectable_label(app, 'git_commit_val', git_commit[:12] if git_commit else '(none)', width=100, color=(C_IN if git_commit else C_LBL)) + ui_shared.render_selectable_label(app, 'git_commit_val', git_commit[:12] if git_commit else '(none)', width=100, color=(C_IN if git_commit else C_LBL)) imgui.same_line() if imgui.button("Update Commit"): if app.ui_project_git_dir: @@ -3881,12 +3882,12 @@ def render_tool_calls_panel(app: App) -> None: imgui.table_next_column() script_preview = script.replace("\n", " ")[:150] if len(script) > 150: script_preview += "..." - render_selectable_label(app, f'tc_script_{i}', script_preview, width=-1) + ui_shared.render_selectable_label(app, f'tc_script_{i}', script_preview, width=-1) imgui.table_next_column() res_preview = res.replace("\n", " ")[:30] if len(res) > 30: res_preview += "..." - render_selectable_label(app, f'tc_res_{i}', res_preview, width=-1) + ui_shared.render_selectable_label(app, f'tc_res_{i}', res_preview, width=-1) imgui.end_table() @@ -4365,24 +4366,16 @@ def render_error_tint(app: App) -> None: imgui.text_colored(imgui.ImVec4(1, 0, 0, 1), "HOT RELOAD ERROR") imgui.text_wrapped(HotReloader.last_error or "Unknown error") -def render_text_viewer(app: App, label: str, content: str, text_type: str = 'text', force_open: bool = False, id_suffix: str = "") -> None: - if imgui.button(f"[+]##{id_suffix or str(id(content))}") or force_open: - app.text_viewer_type = text_type - app.show_windows["Text Viewer"] = True - app.text_viewer_title = label - app.text_viewer_content = content - app.show_windows["Text Viewer"] = True def render_heavy_text(app: App, label: str, content: str, id_suffix: str = "") -> None: if imgui.button(f"[+]##{label}{id_suffix}"): - app.show_windows["Text Viewer"] = True - app.show_windows["Text Viewer"] = True app.text_viewer_type = 'markdown' if label in ('message', 'text', 'content', 'system') else 'json' if label in ('tool_calls', 'data') else 'powershell' if label == 'script' else 'text' app.text_viewer_title = label app.text_viewer_content = content + app.show_windows["Text Viewer"] = True imgui.same_line() imgui.text_colored(C_LBL, f"{label}:"); imgui.same_line() - render_selectable_label(app, f"heavy_label_{label}_{id_suffix}", content[:60].replace("\n", " ") + ("..." if len(content)>60 else ""), color=C_VAL) + ui_shared.render_selectable_label(app, f"heavy_label_{label}_{id_suffix}", content[:60].replace("\n", " ") + ("..." if len(content)>60 else ""), color=C_VAL) if content: ctx_id = f"{label}_{id_suffix}" @@ -4402,27 +4395,6 @@ def render_heavy_text(app: App, label: str, content: str, id_suffix: str = "") - imgui.end_child() -def render_selectable_label(app: App, label: str, value: str, width: float = 0.0, multiline: bool = False, height: float = 0.0, color: Optional[imgui.ImVec4] = None) -> None: - with imscope.id(label + str(hash(value))): - with imscope.style_color(imgui.Col_.frame_bg, vec4(0, 0, 0, 0)), \ - imscope.style_color(imgui.Col_.frame_bg_hovered, vec4(0, 0, 0, 0)), \ - imscope.style_color(imgui.Col_.frame_bg_active, vec4(0, 0, 0, 0)), \ - imscope.style_color(imgui.Col_.border, vec4(0, 0, 0, 0)): - with imscope.style_var(imgui.StyleVar_.frame_border_size, 0.0), \ - imscope.style_var(imgui.StyleVar_.frame_padding, imgui.ImVec2(0, 0)): - if color: - with imscope.style_color(imgui.Col_.text, color): - if multiline: - imgui.input_text_multiline("##" + label, value, imgui.ImVec2(width, height), imgui.InputTextFlags_.read_only) - else: - if width > 0: imgui.set_next_item_width(width) - imgui.input_text("##" + label, value, imgui.InputTextFlags_.read_only) - else: - if multiline: - imgui.input_text_multiline("##" + label, value, imgui.ImVec2(width, height), imgui.InputTextFlags_.read_only) - else: - if width > 0: imgui.set_next_item_width(width) - imgui.input_text("##" + label, value, imgui.InputTextFlags_.read_only) #endregion: Misc Tools @@ -4741,7 +4713,7 @@ def render_tier_stream_panel(app: App, tier_key: str, stream_key: str | None) -> if stream_key is not None: content = app.mma_streams.get(stream_key, "") imgui.begin_child(f"##stream_content_{tier_key}", imgui.ImVec2(-1, -1)) - render_selectable_label(app, f'stream_{tier_key}', content, width=-1, multiline=True, height=0) + ui_shared.render_selectable_label(app, f'stream_{tier_key}', content, width=-1, multiline=True, height=0) try: if len(content) != app._tier_stream_last_len.get(stream_key, -1): imgui.set_scroll_here_y(1.0) @@ -4768,7 +4740,7 @@ def render_tier_stream_panel(app: App, tier_key: str, stream_key: str | None) -> else: imgui.text(f"{ticket_id} [{status}]") imgui.begin_child(f"##tier3_{ticket_id}_scroll", imgui.ImVec2(-1, 150), True) - render_selectable_label(app, f'stream_t3_{ticket_id}', app.mma_streams[key], width=-1, multiline=True, height=0) + ui_shared.render_selectable_label(app, f'stream_t3_{ticket_id}', app.mma_streams[key], width=-1, multiline=True, height=0) try: if len(app.mma_streams[key]) != app._tier_stream_last_len.get(key, -1): imgui.set_scroll_here_y(1.0)