diff --git a/src/gui_2.py b/src/gui_2.py index 97fd2d35..6455aa5b 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -1648,6 +1648,30 @@ if __name__ == "__main__": main() def render_main_interface(app: App) -> None: + """ + Top-level per-frame orchestrator. Dispatches every subsystem in the correct order: + error/stale overlay tints, perf bookends, GUI task draining, modal rendering, + auto-save, comms/tool-log caching, and all dockable windows. + + SSDL Shape: + `[I:overlays] -> [I:task_drain] -> [I:modals] -> [I:windows] -> [I:popups]` + + ASCII Layout Map: + Full-screen dockspace (managed by imgui_bundle): + +-------------------+------------------------------------+ + | Project Settings | Discussion Hub | + | AI Settings | +--------------------------------+ | + | Files & Media | | History entries (scrollable) | | + | Usage Analytics | +--------------------------------+ | + | MMA Dashboard | [splitter] | + | Task DAG | [Message] [Response] | + | Tier 1..4 streams | | + +-------------------+------------------+-----------------+ + | Operations Hub (tab-bar) | Theme window | + | [Comms][Tools][Usage][Ext][Layouts] | | + +---------------------------------------+-----------------+ + (Modals: Approve Script, MMA Step/Spawn, Context, Patch...) + """ if hasattr(app, "controller") and hasattr(app.controller, "mark_first_frame_rendered"): app.controller.mark_first_frame_rendered() render_error_tint(app) @@ -1760,13 +1784,23 @@ def render_custom_title_bar(app: App) -> None: def render_usage_analytics_panel(app: App) -> None: """ Renders the aggregate dashboard panel for usage, budgeting, cache analytics, - tool performance metrics, and session insights. - - State Mutations: - None directly (delegated to sub-panels). + tool performance metrics, session insights, and RAG status. SSDL Shape: - `[I] -> [B:token_budget] -> [B:cache_panel] -> [B:tool_analytics] -> [B:session_insights]` + `[I:token_budget] -> [I:cache_panel] -> [I:tool_analytics] -> [I:session_insights] -> [I:rag_status]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | [Prompt Utilization sub-panel] | + | --- | + | [Cache Analytics sub-panel] | + | --- | + | [Tool Usage sub-panel] | + | --- | + | [Session Insights sub-panel] | + | --- | + | [RAG: indexing...] (clickable status badge) | + +---------------------------------------------------------+ """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_usage_analytics_panel") render_token_budget_panel(app) @@ -1794,15 +1828,32 @@ def render_usage_analytics_panel(app: App) -> None: def render_diagnostics_panel(app: App) -> None: """ - Renders the Diagnostics panel, displaying performance telemetry metrics. - Shows frame time, FPS, event queue throughput, and memory usage. + Renders the Diagnostics window. Shows FPS, frame time, CPU%, and input lag in a + summary table; when profiling is on, shows per-component moving-average timings, + optional sparkline graphs, and the diagnostic message log. - State Mutations: - Updates app.perf_profiling_enabled and visibility in app.show_windows["Diagnostics"]. + SSDL Shape: + `[I:perf_summary_table] -> [B:enable_profiling] => [I:component_timings_table] -> [I:graphs] -> [I:diag_log]` - SSDL Shape: - `[I] -> [B:perf_metrics] => [I:detailed_timings]` - """ + ASCII Layout Map: + +---------------------------------------------------------+ + | Performance Telemetry [ ] Enable Profiling | + | +----------------+---------+-------+ | + | | FPS | 120.0 | [ ] | | + | | Frame Time(ms) | 8.33 | [ ] | | + | | CPU % | 4.2 | [ ] | | + | +----------------+---------+-------+ | + | (when profiling enabled) | + | Detailed Component Timings | + | +--------------------+------+-----+------+------+----+ | + | | Component | Avg | Cnt | Max | Min | G | | + | +--------------------+------+-----+------+------+----+ | + | Diagnostic Log | + | +--------------------+------+---------------------+ | + | | 2026-06-12 22:00 | info | Cache rebuilt | | + | +--------------------+------+---------------------+ | + +---------------------------------------------------------+ + """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_diagnostics_panel") with imscope.window("Diagnostics", app.show_windows.get("Diagnostics", False)) as (exp, opened): app.show_windows["Diagnostics"] = bool(opened) @@ -1909,14 +1960,21 @@ def render_diagnostics_panel(app: App) -> None: def render_cache_panel(app: App) -> None: """ - Renders caching analytics and a clear cache utility for providers that support caching (Gemini). - - State Mutations: - app.controller (clears cached files) - app._cache_cleared_timestamp (updates trigger timestamp) + Renders Gemini cache analytics. Shows cache age, TTL remaining as a colour-coded + progress bar (green > 50%, yellow > 20%, red otherwise), and a [Clear Cache] button. + Skips rendering for non-Gemini providers. SSDL Shape: `[I:cache_stats] -> [B:progress_bar] => [B:clear_cache]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | Cache Analytics | + | Age: 4m 12s TTL: 55m 48s (93%) | + | [============================================= ] 93% | + | [Clear Cache] | + | Cache cleared - will rebuild on next request | + +---------------------------------------------------------+ """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_cache_panel") if app.current_provider != "gemini": @@ -1951,13 +2009,22 @@ def render_cache_panel(app: App) -> None: def render_tool_analytics_panel(app: App) -> None: """ - Renders a breakdown of tool execution telemetry, including calls, average latency, and failure rates. - - State Mutations: - app._cached_tool_stats, app._tool_stats_cache_time (throttled caching of tool telemetry) + Renders a breakdown of tool execution telemetry: calls, average latency ms, and + failure rate percentage per tool. Results are sorted by invocation count descending. SSDL Shape: `[I:tool_stats] -> [B:stats_table]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | Tool Usage | + | +------------------------+-------+----------+-------+ | + | | Tool | Count | Avg (ms) | Fail% | | + | +------------------------+-------+----------+-------+ | + | | py_get_definition | 42 | 35 | 0% | | + | | run_powershell | 18 | 820 | 5% | | + | +------------------------+-------+----------+-------+ | + +---------------------------------------------------------+ """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_tool_analytics_panel") imgui.text_colored(C_LBL(), 'Tool Usage') @@ -1998,13 +2065,30 @@ def render_tool_analytics_panel(app: App) -> None: def render_token_budget_panel(app: App) -> None: """ - Renders prompt token utilization breakdown, system/tools/history usage, and estimated pricing/costs. - - State Mutations: - app._token_stats_dirty, app._token_stats (requests API metrics calculations via background worker) + Renders prompt token utilization breakdown: session totals, cache read/creation stats, + a colour-coded utilisation progress bar, component breakdown table (System/Tools/History), + per-tier MMA cost table, trim warnings, and cache activity badge. SSDL Shape: `[I:session_tokens] -> [B:utilization_bar] -> [B:breakdown_table] -> [B:tier_costs_table]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | Prompt Utilization | + | Tokens: 24,200 (In: 18,000 Out: 6,200) Latency: 2.1s | + | Cache Read: 12,000 Creation: 2,000 | + | [============================== ] 63.2% | + | 24,200 / 38,000 tokens (13,800 remaining) | + | +-------------+--------+------+ | + | | System | 8,000 | 33% | | + | | Tools | 4,000 | 17% | | + | | History | 12,200 | 50% | | + | +-------------+--------+------+ | + | MMA Tier Costs | + | | Tier 1 | gemini | 14,000 | $0.0012 | | + | ⚠ WARNING: Next call will trim history | + | Cache Usage: ACTIVE | Age: 252s / 3600s | + +---------------------------------------------------------+ """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_token_budget_panel") imgui.text_colored(C_LBL(), 'Prompt Utilization') @@ -2123,14 +2207,25 @@ def render_token_budget_panel(app: App) -> None: def render_log_management(app: App) -> None: """ - Renders log management window, enabling browsing, starring/whitelisting, and loading of prior log sessions. - - State Mutations: - app.show_windows["Log Management"] - app._log_registry (creates and loads session logs registry toml) + Renders the Log Management window. Enables browsing, starring (whitelisting), and loading + of prior log sessions from the log registry. Provides one-click prune and refresh actions. SSDL Shape: - `[I:sessions] -> [B:registry_actions] -> [B:sessions_table]` + `[B:refresh | load | prune] -> [I:sessions_table] => [B:load | star/unstar per row]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | Log Management [x] | + | [Refresh Registry] [Load Log] [Force Prune Logs] | + | +------------+------------------+-----+--------+------+ | + | | Session ID | Start Time | Star| Size KB| Msgs | | + | +------------+------------------+-----+--------+------+ | + | | 20260612_2 | 2026-06-12 22:00 | YES | 120 | 84 | | + | | | | | [Load] [Unstar] | + | | 20260611_1 | 2026-06-11 18:30 | NO | 340 | 210 | | + | | | | | [Load] [Star] | + | +------------+------------------+-----+--------+------+ | + +---------------------------------------------------------+ """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_log_management") with imscope.window("Log Management", app.show_windows["Log Management"]) as (exp, opened): @@ -2213,13 +2308,18 @@ def render_log_management(app: App) -> None: def render_project_settings_hub(app: App) -> None: """ - Renders the Project Settings Hub containing tabs for project lists and paths. - - State Mutations: - None directly (delegated to sub-panels). + Renders the Project Settings Hub: a two-tab container for Projects and Paths configuration. SSDL Shape: - `[I] -> [B:tabs] => [I:sub-panel]` + `[I:tab_bar] => [I:projects_panel] | [I:paths_panel]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | [Projects] [Paths] | + | +-----------------------------------------------------+ | + | | | | + | +-----------------------------------------------------+ | + +---------------------------------------------------------+ """ with imscope.tab_bar('context_hub_tabs'): with imscope.tab_item('Projects') as (exp, _): @@ -2230,20 +2330,27 @@ def render_project_settings_hub(app: App) -> None: def render_projects_panel(app: App) -> None: """ Renders the project configuration panel. Allows setting execution mode, - repository path, output directory, managing projects, and layout wrapping/scrolling behavior. - - State Mutations: - app.ui_project_execution_mode - app.ui_project_git_dir - app.ui_output_dir - app.ui_project_conductor_dir - app.project_paths - app.ui_word_wrap - app.ui_auto_scroll_comms - app.ui_auto_scroll_tool_calls + repository path, output/conductor directories, managing projects list, + and global layout toggles (word-wrap, auto-scroll). SSDL Shape: `[I:active_project] -> [B:execution_mode] -> [B:directories] -> [I:project_files] -> [B:project_actions] -> [B:toggles]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | Active: my-feature-project | + | Execution Mode: [native v] | + | Git Directory: [C:\projects\manual_slop___] [Browse] | + | Output Dir: [C:\output____________________] [Browse] | + | Conductor Dir: [C:\projects\...\conductor___] [Browse] | + | Project Files | + | +-----------------------------------------------------+ | + | | [x] my-feature * (active) C:\proj\... | | + | | [x] chore-cleanup C:\proj\... | | + | +-----------------------------------------------------+ | + | [Add Project] [New Project] [Save All] | + | [ ] Word-Wrap [ ] Auto-scroll Comms [ ] Auto-scroll | + +---------------------------------------------------------+ """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_projects_panel") proj_name = app.project.get("project", {}).get("name", Path(app.active_project_path).stem) @@ -2331,14 +2438,21 @@ def render_projects_panel(app: App) -> None: def render_paths_panel(app: App) -> None: """ - Renders the System Path Configuration panel, allowing editing of logs - and scripts directories. Updates the directories on user input. - - State Mutations: - app.ui_logs_dir, app.ui_scripts_dir (via input text or file dialog select) + Renders the System Path Configuration panel. Shows source-tagged logs and scripts + directory fields, each with a Browse button, and Apply / Reset buttons. SSDL Shape: - `[I] -> [B:inputs] => [B:apply_reset]` + `[I:path_fields] => [B:apply_reset]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | System Path Configuration | + | Logs Directory (Source: env) | + | [C:\projects\manual_slop\logs___________] [Browse] | + | Scripts Directory (Source: default) | + | [C:\projects\manual_slop\scripts________] [Browse] | + | [Apply] [Reset] | + +---------------------------------------------------------+ """ if app.perf_profiling_enabled: app.perf_monitor.start_component("_render_paths_panel") path_info = paths.get_full_path_info() @@ -2383,13 +2497,22 @@ def render_paths_panel(app: App) -> None: def render_ai_settings_hub(app: App) -> None: """ Groups and renders all AI-related configuration panels in a unified hub sidebar. - Includes persona selection, LLM provider settings, system prompts, RAG switches, and tools. - - State Mutations: - None directly (delegated to child panels). + Includes persona selection, LLM provider settings, system prompts, RAG config, and tools. SSDL Shape: - `[I] -> [B:headers] => [I:sub-panels]` + `[I:persona_selector] -> [B:provider_header] -> [B:system_prompts_header] -> [B:rag_header] -> [I:agent_tools]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | [Persona Selector sub-panel] | + | > Provider & Model (collapsible) | + | [Provider sub-panel content] | + | > System Prompts (collapsible) | + | [System Prompts sub-panel content] | + | > RAG Settings (collapsible) | + | [RAG sub-panel content] | + | [Agent Tools sub-panel] | + +---------------------------------------------------------+ """ render_persona_selector_panel(app) if imgui.collapsing_header("Provider & Model"): render_provider_panel(app) @@ -2399,14 +2522,22 @@ def render_ai_settings_hub(app: App) -> None: def render_rag_panel(app: App) -> None: """ - Renders RAG configuration panel, exposing switches, provider selection, chunking parameters, - and index rebuild triggers. - - State Mutations: - app.controller.rag_config (provider, embedding, chunk size, overlap) + Renders RAG configuration panel. Exposes enable toggle, vector-store and embedding + provider selectors, chunk size/overlap inputs, RAG status label, and a Rebuild Index button. SSDL Shape: - `[I:config] -> [B:rag_switch] -> [B:combo_selectors] -> [B:chunking_inputs] => [B:rebuild_index]` + `[B:rag_switch] -> [B:combo_selectors] -> [B:chunking_inputs] => [B:rebuild_index]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | [x] Enable RAG | + | Vector Store Provider: [chroma v] | + | Embedding Provider: [gemini v] | + | Chunk Size: [512] | + | Chunk Overlap: [64] | + | Status: indexing... | + | [Rebuild Index] | + +---------------------------------------------------------+ """ conf = app.controller.rag_config if not conf: return @@ -2446,17 +2577,30 @@ def render_rag_panel(app: App) -> None: def render_system_prompts_panel(app: App) -> None: """ - Renders the System Prompts panel, exposing global and project-specific prompt selection, - editing boxes, base prompt defaults, and diff comparisons. - - State Mutations: - app.controller.ui_global_preset_name, app.controller.ui_project_preset_name - app.ui_global_system_prompt, app.ui_project_system_prompt - app.ui_base_system_prompt, app.ui_use_default_base_prompt - app.show_preset_manager_window (to open modal) + Renders the System Prompts panel. Exposes global preset selector + multiline edit, + base prompt toggle (default vs custom) with diff + reset, and project-level preset + selector + multiline edit. SSDL Shape: - `[I:presets] -> [B:global_preset] -> [B:base_preset_customizer] -> [B:project_preset]` + `[B:global_preset_combo] -> [I:global_text] -> [B:base_prompt_header] -> [I:base_text] -> [B:project_preset_combo] -> [I:project_text]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | Global System Prompt (all projects) | + | [coding-assistant v] [Manage Presets] | + | +-----------------------------------------------------+ | + | | You are a coding assistant... | | + | +-----------------------------------------------------+ | + | [x] Use Default Base System Prompt | + | [Reset to Default] [Show Diff] (?) | + | > Base System Prompt (foundational instructions) | + | [read-only or editable text area] | + | Project System Prompt | + | [feature-mode v] [Manage Presets] | + | +-----------------------------------------------------+ | + | | Focus on the rendering pipeline refactor... | | + | +-----------------------------------------------------+ | + +---------------------------------------------------------+ """ imgui.text("Global System Prompt (all projects)") preset_names = sorted(app.controller.presets.keys()) @@ -2511,16 +2655,20 @@ def render_system_prompts_panel(app: App) -> None: def render_agent_tools_panel(app: App) -> None: """ - Renders active tool presets and configuration options. - Allows selecting tool presets, toggling individual capability flags, and showing bias managers. - - State Mutations: - Modifies app.ui_active_tool_preset and local UI flags. + Renders the Active Tool Presets & Biases collapsible section. Shows a preset combo, + a Manage Presets button, and a Bias Profile combo. Displays a disabled notice when + tool calling is unsupported by the active provider/model. SSDL Shape: - `[Q:caps] -> [B:tool_calling] => [S:preset]` + `[B:collapsing_header] => [B:preset_combo] -> [B:manage_presets] -> [B:bias_combo]` + + ASCII Layout Map: + +---------------------------------------------------------+ + | > Active Tool Presets & Biases (open by default) | + | Tool Preset: [mcp-only v] [Manage Presets] | + | Bias Profile: [None v] | + +---------------------------------------------------------+ """ - caps = app._get_active_capabilities() if not caps.tool_calling: if imgui.collapsing_header("Active Tool Presets & Biases", imgui.TreeNodeFlags_.default_open): imgui.text_disabled(f"(tools not supported by {app.current_provider}/{app.current_model})")