making a dent (disasterous one)

This commit is contained in:
2026-05-12 02:07:52 -04:00
parent 643f36e7d1
commit fb45b44824
2 changed files with 195 additions and 236 deletions
+191 -232
View File
@@ -1,15 +1,23 @@
# gui_2.py # gui_2.py
from __future__ import annotations from __future__ import annotations
import tomli_w
import datetime
import time
import math
import json
import sys
import os
import shutil
import copy import copy
import datetime
import difflib
import json
import math
import numpy as np
import os
import re
import shutil
import subprocess
import sys
import threading import threading
import time
# from defer import defer
import tomli_w
# from contextlib import ExitStack
import traceback
import typing
from pathlib import Path from pathlib import Path
from tkinter import filedialog, Tk from tkinter import filedialog, Tk
from typing import Optional, Any from typing import Optional, Any
@@ -19,26 +27,20 @@ from src import session_logger
from src import project_manager from src import project_manager
from src import paths from src import paths
from src import presets from src import presets
from src import theme_2 as theme
from src import theme_nerv_fx as theme_fx
from src import api_hooks from src import api_hooks
import numpy as np
from src import log_registry from src import log_registry
from src import log_pruner from src import log_pruner
from src import models from src import models
from src import app_controller from src import app_controller
from src import workspace_manager from src import history
from src import mcp_client from src import mcp_client
from src import aggregate from src import aggregate
from src import markdown_helper from src import markdown_helper
from src import bg_shader from src import bg_shader
from src import thinking_parser from src import thinking_parser
from src import history from src import theme_2 as theme
import typing from src import theme_nerv_fx as theme_fx
import re from src import workspace_manager
import difflib
import subprocess
import traceback
if sys.platform == "win32": if sys.platform == "win32":
import win32gui import win32gui
import win32con import win32con
@@ -614,18 +616,18 @@ class App:
if show_content: if show_content:
h = 150 if is_standalone else 100 h = 150 if is_standalone else 100
imscope.child(f"thinking_content_{entry_index}", imgui.ImVec2(0, h), True) with imscope.child(f"thinking_content_{entry_index}", imgui.ImVec2(0, h), True):
for idx, seg in enumerate(segments): for idx, seg in enumerate(segments):
content = seg.get("content", "") content = seg.get("content", "")
marker = seg.get("marker", "thinking") marker = seg.get("marker", "thinking")
imscope.id(f"think_{entry_index}_{idx}") with imscope.id(f"think_{entry_index}_{idx}"):
imgui.text_colored(vec4(180, 150, 80), f"[{marker}]") imgui.text_colored(vec4(180, 150, 80), f"[{marker}]")
if self.ui_word_wrap: if self.ui_word_wrap:
imscope.text_wrap(imgui.get_content_region_avail().x) imscope.text_wrap(imgui.get_content_region_avail().x)
imgui.text_colored(vec4(200, 200, 150), content) imgui.text_colored(vec4(200, 200, 150), content)
else: else:
imgui.text_colored(vec4(200, 200, 150), content) imgui.text_colored(vec4(200, 200, 150), content)
imgui.separator() imgui.separator()
imgui.unindent() imgui.unindent()
imgui.pop_style_color(2) imgui.pop_style_color(2)
@@ -811,6 +813,112 @@ class App:
if not history: imgui.text("No history available.") if not history: imgui.text("No history available.")
else: iterate_history() else: iterate_history()
def _render_files_and_media(self) -> None:
avail = imgui.get_content_region_avail().y
if not hasattr(self, 'files_screenshots_split'): self.files_screenshots_split = 0.65
split_y = int(avail * self.files_screenshots_split)
if imgui.collapsing_header("Files", imgui.TreeNodeFlags_.default_open):
with imscope.child("Files_child", imgui.ImVec2(-1, split_y), True):
if not hasattr(self, 'files_last_selected'): self.files_last_selected = -1
with imscope.table("files_table", 5, imgui.TableFlags_.resizable | imgui.TableFlags_.borders):
imgui.table_setup_column("", imgui.TableColumnFlags_.width_fixed, 20)
imgui.table_setup_column("Path", imgui.TableColumnFlags_.width_stretch)
imgui.table_setup_column("Agg", imgui.TableColumnFlags_.width_fixed, 0)
imgui.table_setup_column("Full", imgui.TableColumnFlags_.width_fixed, 0)
imgui.table_setup_column("Cache", imgui.TableColumnFlags_.width_fixed, 0)
imgui.table_headers_row()
self.files.sort(key=lambda f: f.path.lower() if hasattr(f, 'path') else str(f).lower())
for i, f_item in enumerate(self.files):
imgui.table_next_row(); imgui.table_set_column_index(0)
clicked, f_item.selected = imgui.checkbox(f"##{i}", f_item.selected)
if clicked:
if (imgui.is_key_down(imgui.Key.left_shift) or imgui.is_key_down(imgui.Key.right_shift)) and self.files_last_selected >= 0:
start_i = min(self.files_last_selected, i)
end_i = max(self.files_last_selected, i)
for j in range(start_i, end_i + 1): self.files[j].selected = True
self.files_last_selected = i
imgui.table_set_column_index(1); imgui.text(f_item.path if hasattr(f_item, 'path') else str(f_item))
imgui.table_set_column_index(2)
if f_item.auto_aggregate: imgui.text_colored(imgui.ImVec4(0.3, 0.8, 1, 1), "A")
else: imgui.text_disabled(" ")
imgui.same_line(spacing=1)
if imgui.invisible_button(f"agg{i}", imgui.ImVec2(15, 15)):
f_item.auto_aggregate = not f_item.auto_aggregate
if f_item.auto_aggregate: f_item.force_full = False
imgui.table_set_column_index(3)
if f_item.force_full: imgui.text_colored(imgui.ImVec4(1, 0.6, 0.3, 1), "F")
else: imgui.text_disabled(" ")
imgui.same_line(spacing=1)
if imgui.invisible_button(f"full{i}", imgui.ImVec2(15, 15)):
f_item.force_full = not f_item.force_full
if f_item.force_full: f_item.auto_aggregate = False
imgui.table_set_column_index(4)
fpath = f_item.path if hasattr(f_item, 'path') else str(f_item)
is_cached = any(fpath in c for c in getattr(self, '_cached_files', []))
if is_cached: imgui.text_colored(imgui.ImVec4(0, 1, 0, 1), "Y")
else: imgui.text_colored(imgui.ImVec4(0.5, 0.5, 0.5, 1), "-")
if imgui.button("Add Files##addf"):
r = hide_tk_root(); paths = filedialog.askopenfilenames(); r.destroy()
for p in paths:
if p not in [f.path if hasattr(f, 'path') else f for f in self.files]: self.files.append(models.FileItem(path=p))
imgui.same_line()
if imgui.button("Sel All##selall"):
for f in self.files:
f.selected = True
imgui.same_line()
if imgui.button("Unsel##unselall"):
for f in self.files:
f.selected = False
imgui.same_line()
if imgui.button("None##nonesel"):
for f in self.files:
if f.selected:
f.auto_aggregate = False
f.force_full = False
imgui.same_line()
if imgui.button("Agg##aggsel"):
for f in self.files:
if f.selected:
f.auto_aggregate = True
f.force_full = False
imgui.same_line()
if imgui.button("Full##fullsel"):
for f in self.files:
if f.selected:
f.force_full = True
f.auto_aggregate = False
imgui.same_line()
if imgui.button("Del##dels"):
self.files = [f for f in self.files if not f.selected]
imgui.separator()
if imgui.collapsing_header("Screenshots", imgui.TreeNodeFlags_.default_open):
with imscope.child("Shots_child", imgui.ImVec2(-1, -1), True):
for i, s in enumerate(self.screenshots):
if imgui.button(f"x##s{i}"):
self.screenshots.pop(i)
break
imgui.same_line(); imgui.text(s)
if imgui.button("Add Screenshots##adds"):
r = hide_tk_root(); paths = filedialog.askopenfilenames(filetypes=[("Images", "*.png *.jpg *.jpeg *.gif *.bmp *.webp"), ("All", "*.*")]); r.destroy()
for p in paths:
if p not in self.screenshots: self.screenshots.append(p)
return
def _gui_func__abusrd_try_scope(self) -> None: def _gui_func__abusrd_try_scope(self) -> None:
self.perf_monitor.start_frame() self.perf_monitor.start_frame()
self._autofocus_response_tab = self.controller._autofocus_response_tab self._autofocus_response_tab = self.controller._autofocus_response_tab
@@ -824,8 +932,7 @@ class App:
sys.stderr.flush() sys.stderr.flush()
self._process_pending_gui_tasks() self._process_pending_gui_tasks()
self._process_pending_history_adds() self._process_pending_history_adds()
if self.controller._process_pending_tool_calls(): if self.controller._process_pending_tool_calls(): self._tool_log_dirty = True
self._tool_log_dirty = True
#endregion: Process GUI task queue #endregion: Process GUI task queue
self._render_track_proposal_modal() self._render_track_proposal_modal()
@@ -848,41 +955,34 @@ class App:
models.save_config(self.config) models.save_config(self.config)
except Exception: except Exception:
pass # silent — don't disrupt the GUI loop pass # silent — don't disrupt the GUI loop
# Sync pending comms
# Sync pending comms
with self._pending_comms_lock: with self._pending_comms_lock:
if self._pending_comms: if self._pending_comms:
if self.ui_auto_scroll_comms: if self.ui_auto_scroll_comms: self._scroll_comms_to_bottom = True
self._scroll_comms_to_bottom = True
self._comms_log_dirty = True self._comms_log_dirty = True
for c in self._pending_comms: for c in self._pending_comms: self._comms_log.append(c)
self._comms_log.append(c)
self._pending_comms.clear() self._pending_comms.clear()
if self.ui_focus_agent != self._last_ui_focus_agent: if self.ui_focus_agent != self._last_ui_focus_agent:
self._comms_log_dirty = True self._comms_log_dirty = True
self._tool_log_dirty = True self._tool_log_dirty = True
self._last_ui_focus_agent = self.ui_focus_agent self._last_ui_focus_agent = self.ui_focus_agent
if self._comms_log_dirty: if self._comms_log_dirty:
if self.is_viewing_prior_session: if self.is_viewing_prior_session: self._comms_log_cache = self.prior_session_entries
self._comms_log_cache = self.prior_session_entries
else: else:
log_raw = list(self._comms_log) log_raw = list(self._comms_log)
if self.ui_focus_agent: if self.ui_focus_agent: self._comms_log_cache = [e for e in log_raw if e.get("source_tier", "").startswith(self.ui_focus_agent)]
self._comms_log_cache = [e for e in log_raw if e.get("source_tier", "").startswith(self.ui_focus_agent)] else: self._comms_log_cache = log_raw
else:
self._comms_log_cache = log_raw
self._comms_log_dirty = False self._comms_log_dirty = False
if self._tool_log_dirty: if self._tool_log_dirty:
if self.is_viewing_prior_session: if self.is_viewing_prior_session: self._tool_log_cache = self.prior_tool_calls
self._tool_log_cache = self.prior_tool_calls
else: else:
log_raw = list(self._tool_log) log_raw = list(self._tool_log)
if self.ui_focus_agent: if self.ui_focus_agent: self._tool_log_cache = [e for e in log_raw if e.get("source_tier", "").startswith(self.ui_focus_agent)]
self._tool_log_cache = [e for e in log_raw if e.get("source_tier", "").startswith(self.ui_focus_agent)] else: self._tool_log_cache = log_raw
else:
self._tool_log_cache = log_raw
self._tool_log_dirty = False self._tool_log_dirty = False
#region: Project Settings #region: Project Settings
@@ -898,119 +998,7 @@ class App:
if self.show_windows.get("Files & Media", False): if self.show_windows.get("Files & Media", False):
exp, opened = imgui.begin("Files & Media", self.show_windows["Files & Media"]) exp, opened = imgui.begin("Files & Media", self.show_windows["Files & Media"])
self.show_windows["Files & Media"] = bool(opened) self.show_windows["Files & Media"] = bool(opened)
if opened: if opened and exp: self._render_files_and_media()
if exp:
avail = imgui.get_content_region_avail().y
if not hasattr(self, 'files_screenshots_split'):
self.files_screenshots_split = 0.65
split_y = int(avail * self.files_screenshots_split)
if imgui.collapsing_header("Files", imgui.TreeNodeFlags_.default_open):
imgui.begin_child("Files_child", imgui.ImVec2(-1, split_y), True)
if not hasattr(self, 'files_last_selected'):
self.files_last_selected = -1
if imgui.begin_table("files_table", 5, imgui.TableFlags_.resizable | imgui.TableFlags_.borders):
imgui.table_setup_column("", imgui.TableColumnFlags_.width_fixed, 20)
imgui.table_setup_column("Path", imgui.TableColumnFlags_.width_stretch)
imgui.table_setup_column("Agg", imgui.TableColumnFlags_.width_fixed, 0)
imgui.table_setup_column("Full", imgui.TableColumnFlags_.width_fixed, 0)
imgui.table_setup_column("Cache", imgui.TableColumnFlags_.width_fixed, 0)
imgui.table_headers_row()
self.files.sort(key=lambda f: f.path.lower() if hasattr(f, 'path') else str(f).lower())
for i, f_item in enumerate(self.files):
imgui.table_next_row()
imgui.table_set_column_index(0)
clicked, f_item.selected = imgui.checkbox(f"##{i}", f_item.selected)
if clicked:
if (imgui.is_key_down(imgui.Key.left_shift) or imgui.is_key_down(imgui.Key.right_shift)) and self.files_last_selected >= 0:
start_i = min(self.files_last_selected, i)
end_i = max(self.files_last_selected, i)
for j in range(start_i, end_i + 1):
self.files[j].selected = True
self.files_last_selected = i
imgui.table_set_column_index(1)
imgui.text(f_item.path if hasattr(f_item, 'path') else str(f_item))
imgui.table_set_column_index(2)
if f_item.auto_aggregate:
imgui.text_colored(imgui.ImVec4(0.3, 0.8, 1, 1), "A")
else:
imgui.text_disabled(" ")
imgui.same_line(spacing=1)
if imgui.invisible_button(f"agg{i}", imgui.ImVec2(15, 15)):
f_item.auto_aggregate = not f_item.auto_aggregate
if f_item.auto_aggregate:
f_item.force_full = False
imgui.table_set_column_index(3)
if f_item.force_full:
imgui.text_colored(imgui.ImVec4(1, 0.6, 0.3, 1), "F")
else:
imgui.text_disabled(" ")
imgui.same_line(spacing=1)
if imgui.invisible_button(f"full{i}", imgui.ImVec2(15, 15)):
f_item.force_full = not f_item.force_full
if f_item.force_full:
f_item.auto_aggregate = False
imgui.table_set_column_index(4)
fpath = f_item.path if hasattr(f_item, 'path') else str(f_item)
is_cached = any(fpath in c for c in getattr(self, '_cached_files', []))
if is_cached:
imgui.text_colored(imgui.ImVec4(0, 1, 0, 1), "Y")
else:
imgui.text_colored(imgui.ImVec4(0.5, 0.5, 0.5, 1), "-")
imgui.end_table()
if imgui.button("Add Files##addf"):
r = hide_tk_root()
paths = filedialog.askopenfilenames()
r.destroy()
for p in paths:
if p not in [f.path if hasattr(f, 'path') else f for f in self.files]:
self.files.append(models.FileItem(path=p))
imgui.same_line()
if imgui.button("Sel All##selall"):
for f in self.files:
f.selected = True
imgui.same_line()
if imgui.button("Unsel##unselall"):
for f in self.files:
f.selected = False
imgui.same_line()
if imgui.button("None##nonesel"):
for f in self.files:
if f.selected:
f.auto_aggregate = False
f.force_full = False
imgui.same_line()
if imgui.button("Agg##aggsel"):
for f in self.files:
if f.selected:
f.auto_aggregate = True
f.force_full = False
imgui.same_line()
if imgui.button("Full##fullsel"):
for f in self.files:
if f.selected:
f.force_full = True
f.auto_aggregate = False
imgui.same_line()
if imgui.button("Del##dels"):
self.files = [f for f in self.files if not f.selected]
imgui.end_child()
imgui.separator()
if imgui.collapsing_header("Screenshots", imgui.TreeNodeFlags_.default_open):
imgui.begin_child("Shots_child", imgui.ImVec2(-1, -1), True)
for i, s in enumerate(self.screenshots):
if imgui.button(f"x##s{i}"):
self.screenshots.pop(i)
break
imgui.same_line()
imgui.text(s)
if imgui.button("Add Screenshots##adds"):
r = hide_tk_root()
paths = filedialog.askopenfilenames(filetypes=[("Images", "*.png *.jpg *.jpeg *.gif *.bmp *.webp"), ("All", "*.*")])
r.destroy()
for p in paths:
if p not in self.screenshots:
self.screenshots.append(p)
imgui.end_child()
imgui.end() imgui.end()
#endregion: Files & Media window #endregion: Files & Media window
@@ -1020,13 +1008,11 @@ class App:
self.show_windows["AI Settings"] = bool(opened) self.show_windows["AI Settings"] = bool(opened)
if exp: if exp:
self._render_persona_selector_panel() self._render_persona_selector_panel()
if imgui.collapsing_header("Provider & Model"): if imgui.collapsing_header("Provider & Model"): self._render_provider_panel()
self._render_provider_panel() if imgui.collapsing_header("System Prompts"): self._render_system_prompts_panel()
if imgui.collapsing_header("System Prompts"): if imgui.collapsing_header("RAG Settings"): self._render_rag_panel()
self._render_system_prompts_panel()
if imgui.collapsing_header("RAG Settings"):
self._render_rag_panel()
self._render_agent_tools_panel() self._render_agent_tools_panel()
#endregion: AI Settings
if self.ui_separate_usage_analytics and self.show_windows.get("Usage Analytics", False): if self.ui_separate_usage_analytics and self.show_windows.get("Usage Analytics", False):
exp, opened = imgui.begin("Usage Analytics", self.show_windows["Usage Analytics"]) exp, opened = imgui.begin("Usage Analytics", self.show_windows["Usage Analytics"])
@@ -1034,6 +1020,7 @@ class App:
if exp: if exp:
self._render_usage_analytics_panel() self._render_usage_analytics_panel()
imgui.end() imgui.end()
if self.show_windows.get("MMA Dashboard", False): if self.show_windows.get("MMA Dashboard", False):
exp, opened = imgui.begin("MMA Dashboard", self.show_windows["MMA Dashboard"]) exp, opened = imgui.begin("MMA Dashboard", self.show_windows["MMA Dashboard"])
self.show_windows["MMA Dashboard"] = bool(opened) self.show_windows["MMA Dashboard"] = bool(opened)
@@ -1042,68 +1029,55 @@ class App:
self._render_mma_dashboard() self._render_mma_dashboard()
if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_mma_dashboard") if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_mma_dashboard")
imgui.end() imgui.end()
#endregion: AI Settings
#region: Seprate Task Dag to Tier 4 #region: Seprate Task Dag to Tier 4
if self.ui_separate_task_dag and self.show_windows.get("Task DAG", False): if self.ui_separate_task_dag and self.show_windows.get("Task DAG", False):
exp, opened = imgui.begin("Task DAG", self.show_windows["Task DAG"]) exp, opened = imgui.begin("Task DAG", self.show_windows["Task DAG"])
self.show_windows["Task DAG"] = bool(opened) self.show_windows["Task DAG"] = bool(opened)
if exp: if exp: self._render_task_dag_panel()
self._render_task_dag_panel()
imgui.end() imgui.end()
if self.ui_separate_tier1 and self.show_windows.get("Tier 1: Strategy", False): if self.ui_separate_tier1 and self.show_windows.get("Tier 1: Strategy", False):
exp, opened = imgui.begin("Tier 1: Strategy", self.show_windows["Tier 1: Strategy"]) exp, opened = imgui.begin("Tier 1: Strategy", self.show_windows["Tier 1: Strategy"])
self.show_windows["Tier 1: Strategy"] = bool(opened) self.show_windows["Tier 1: Strategy"] = bool(opened)
if exp: if exp: self._render_tier_stream_panel("Tier 1", "Tier 1")
self._render_tier_stream_panel("Tier 1", "Tier 1")
imgui.end() imgui.end()
if self.ui_separate_tier2 and self.show_windows.get("Tier 2: Tech Lead", False): if self.ui_separate_tier2 and self.show_windows.get("Tier 2: Tech Lead", False):
exp, opened = imgui.begin("Tier 2: Tech Lead", self.show_windows["Tier 2: Tech Lead"]) exp, opened = imgui.begin("Tier 2: Tech Lead", self.show_windows["Tier 2: Tech Lead"])
self.show_windows["Tier 2: Tech Lead"] = bool(opened) self.show_windows["Tier 2: Tech Lead"] = bool(opened)
if exp: if exp: self._render_tier_stream_panel("Tier 2", "Tier 2 (Tech Lead)")
self._render_tier_stream_panel("Tier 2", "Tier 2 (Tech Lead)")
imgui.end() imgui.end()
if self.ui_separate_tier3 and self.show_windows.get("Tier 3: Workers", False): if self.ui_separate_tier3 and self.show_windows.get("Tier 3: Workers", False):
exp, opened = imgui.begin("Tier 3: Workers", self.show_windows["Tier 3: Workers"]) exp, opened = imgui.begin("Tier 3: Workers", self.show_windows["Tier 3: Workers"])
self.show_windows["Tier 3: Workers"] = bool(opened) self.show_windows["Tier 3: Workers"] = bool(opened)
if exp: if exp: self._render_tier_stream_panel("Tier 3", None)
self._render_tier_stream_panel("Tier 3", None)
imgui.end() imgui.end()
if self.ui_separate_tier4 and self.show_windows.get("Tier 4: QA", False): if self.ui_separate_tier4 and self.show_windows.get("Tier 4: QA", False):
exp, opened = imgui.begin("Tier 4: QA", self.show_windows["Tier 4: QA"]) exp, opened = imgui.begin("Tier 4: QA", self.show_windows["Tier 4: QA"])
self.show_windows["Tier 4: QA"] = bool(opened) self.show_windows["Tier 4: QA"] = bool(opened)
if exp: if exp: self._render_tier_stream_panel("Tier 4", "Tier 4 (QA)")
self._render_tier_stream_panel("Tier 4", "Tier 4 (QA)")
imgui.end() imgui.end()
#endregion: Separate Task Dag to Tier 4 #endregion: Separate Task Dag to Tier 4
if self.show_windows.get("Theme", False): if self.show_windows.get("Theme", False): self._render_theme_panel()
self._render_theme_panel()
#region: Discussion Hub #region: Discussion Hub
if self.show_windows.get("Discussion Hub", False): if self.show_windows.get("Discussion Hub", False):
exp, opened = imgui.begin("Discussion Hub", self.show_windows["Discussion Hub"]) with imscope.window("Discussion Hub", self.show_windows["Discussion Hub"]) as (exp, opened):
self.show_windows["Discussion Hub"] = bool(opened) self.show_windows["Discussion Hub"] = bool(opened)
if exp: if exp:
if imgui.begin_tab_bar("discussion_hub_tabs"): if imscope.tab_bar("discussion_hub_tabs"):
if imgui.begin_tab_item("Discussion")[0]: if imscope.tab_item("Discussion"):
self._render_discussion_tab() self._render_discussion_tab()
imgui.end_tab_item() if imscope.tab_item("Context Composition"):
if imgui.begin_tab_item("Context Composition")[0]: self._render_context_composition_panel()
self._render_context_composition_panel() if imscope.tab_item("Snapshot"):
imgui.end_tab_item() self._render_snapshot_tab()
if imgui.begin_tab_item("Snapshot")[0]: if imscope.tab_item("Takes"):
self._render_snapshot_tab() self._render_takes_panel()
imgui.end_tab_item()
if imgui.begin_tab_item("Takes")[0]:
self._render_takes_panel()
imgui.end_tab_item()
imgui.end_tab_bar()
imgui.end()
#endregion: Discussion Hub #endregion: Discussion Hub
#region: Operations Hub #region: Operations Hub
@@ -1122,23 +1096,17 @@ class App:
if ch3: self.show_windows['External Tools'] = self.ui_separate_external_tools if ch3: self.show_windows['External Tools'] = self.ui_separate_external_tools
imgui.pop_style_var() imgui.pop_style_var()
show_tc_tab = not self.ui_separate_tool_calls_panel show_tc_tab = not self.ui_separate_tool_calls_panel
show_usage_tab = not self.ui_separate_usage_analytics show_usage_tab = not self.ui_separate_usage_analytics
if imgui.begin_tab_bar("ops_tabs"): with imscope.tab_bar("ops_tabs"):
if imgui.begin_tab_item("Comms History")[0]: with imscope.tab_item("Comms History"): self._render_comms_history_panel()
self._render_comms_history_panel()
imgui.end_tab_item()
if show_tc_tab: if show_tc_tab:
if imgui.begin_tab_item("Tool Calls")[0]: with imscope.tab_item("Tool Calls"): self._render_tool_calls_panel()
self._render_tool_calls_panel()
imgui.end_tab_item()
if show_usage_tab: if show_usage_tab:
if imgui.begin_tab_item("Usage Analytics")[0]: with imscope.tab_item("Usage Analytics"): self._render_usage_analytics_panel()
self._render_usage_analytics_panel()
imgui.end_tab_item()
if not self.ui_separate_external_tools: if not self.ui_separate_external_tools:
if imgui.begin_tab_item("External Tools")[0]: with imscope.tab_item("External Tools"):
self._render_external_tools_panel() self._render_external_tools_panel()
imgui.separator() imgui.separator()
imgui.text("") imgui.text("")
@@ -1146,8 +1114,7 @@ class App:
self._render_external_editor_panel() self._render_external_editor_panel()
except Exception as e: except Exception as e:
imgui.text_colored(vec4(1, 0.3, 0.3, 1), f"Error: {str(e)}") imgui.text_colored(vec4(1, 0.3, 0.3, 1), f"Error: {str(e)}")
imgui.end_tab_item() with imscope.tab_item("Workspace Layouts"):
if imgui.begin_tab_item("Workspace Layouts")[0]:
imgui.text("Experimental: Auto-switch layout by Tier") imgui.text("Experimental: Auto-switch layout by Tier")
ch, self.controller.ui_auto_switch_layout = imgui.checkbox("Enable Auto-Switch", self.controller.ui_auto_switch_layout) ch, self.controller.ui_auto_switch_layout = imgui.checkbox("Enable Auto-Switch", self.controller.ui_auto_switch_layout)
if self.controller.ui_auto_switch_layout: if self.controller.ui_auto_switch_layout:
@@ -1155,43 +1122,36 @@ class App:
imgui.text("Tier Bindings (select profile for each tier)") imgui.text("Tier Bindings (select profile for each tier)")
profiles = [""] + [p.name for p in self.controller.workspace_profiles.values()] profiles = [""] + [p.name for p in self.controller.workspace_profiles.values()]
for t in ["Tier 1", "Tier 2", "Tier 3", "Tier 4"]: for t in ["Tier 1", "Tier 2", "Tier 3", "Tier 4"]:
curr = self.controller.ui_tier_layout_bindings.get(t, "") curr = self.controller.ui_tier_layout_bindings.get(t, "")
idx = profiles.index(curr) if curr in profiles else 0 idx = profiles.index(curr) if curr in profiles else 0
ch_combo, new_idx = imgui.combo(t, idx, profiles) ch_combo, new_idx = imgui.combo(t, idx, profiles)
if ch_combo: if ch_combo: self.controller.ui_tier_layout_bindings[t] = profiles[new_idx]
self.controller.ui_tier_layout_bindings[t] = profiles[new_idx] imgui.end()
imgui.end_tab_item()
imgui.end_tab_bar()
imgui.end()
#endregion: Operations Hub #endregion: Operations Hub
#region: Separate Message, Response, Tool Calls, External Tools #region: Separate Message, Response, Tool Calls, External Tools
if self.ui_separate_message_panel and self.show_windows.get("Message", False): if self.ui_separate_message_panel and self.show_windows.get("Message", False):
exp, opened = imgui.begin("Message", self.show_windows["Message"]) exp, opened = imgui.begin("Message", self.show_windows["Message"])
self.show_windows["Message"] = bool(opened) self.show_windows["Message"] = bool(opened)
if exp: if exp: self._render_message_panel()
self._render_message_panel()
imgui.end() imgui.end()
if self.ui_separate_response_panel and self.show_windows.get("Response", False): if self.ui_separate_response_panel and self.show_windows.get("Response", False):
exp, opened = imgui.begin("Response", self.show_windows["Response"]) exp, opened = imgui.begin("Response", self.show_windows["Response"])
self.show_windows["Response"] = bool(opened) self.show_windows["Response"] = bool(opened)
if exp: if exp: self._render_response_panel()
self._render_response_panel()
imgui.end() imgui.end()
if self.ui_separate_tool_calls_panel and self.show_windows.get("Tool Calls", False): if self.ui_separate_tool_calls_panel and self.show_windows.get("Tool Calls", False):
exp, opened = imgui.begin("Tool Calls", self.show_windows["Tool Calls"]) exp, opened = imgui.begin("Tool Calls", self.show_windows["Tool Calls"])
self.show_windows["Tool Calls"] = bool(opened) self.show_windows["Tool Calls"] = bool(opened)
if exp: if exp: self._render_tool_calls_panel()
self._render_tool_calls_panel()
imgui.end() imgui.end()
if self.ui_separate_external_tools and self.show_windows.get('External Tools', False): if self.ui_separate_external_tools and self.show_windows.get('External Tools', False):
exp, opened = imgui.begin('External Tools', self.show_windows['External Tools']) exp, opened = imgui.begin('External Tools', self.show_windows['External Tools'])
self.show_windows['External Tools'] = bool(opened) self.show_windows['External Tools'] = bool(opened)
if exp: if exp: self._render_external_tools_panel()
self._render_external_tools_panel()
imgui.end() imgui.end()
if self.show_windows.get("Log Management", False): if self.show_windows.get("Log Management", False):
@@ -1200,8 +1160,7 @@ class App:
if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_log_management") if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_log_management")
#endregion: Separate Message, Response, Tool Calls, External Tools #endregion: Separate Message, Response, Tool Calls, External Tools
if self.show_windows.get("Diagnostics", False): if self.show_windows.get("Diagnostics", False): self._render_diagnostics_panel()
self._render_diagnostics_panel()
self.perf_monitor.end_frame() self.perf_monitor.end_frame()
+3 -3
View File
@@ -133,9 +133,9 @@ class _ScopeTabItem:
self._flags = flags self._flags = flags
self._open = None self._open = None
def __enter__(self): def __enter__(self):
self._open = imgui.begin_tab_item(self._label, self._flags) exp, self._open = imgui.begin_tab_item(self._label, None, self._flags)
return self._open return exp, self._open
def __exit__(self, *args): def __exit__(self, *args):
if self._open[0]: if self._open:
imgui.end_tab_item() imgui.end_tab_item()
return False return False