feat(gui): Implement Session Hub and context injection visibility
This commit is contained in:
@@ -243,6 +243,8 @@ class AppController:
|
||||
self.ai_status: str = 'idle'
|
||||
self.ai_response: str = ''
|
||||
self.last_md: str = ''
|
||||
self.last_aggregate_markdown: str = ''
|
||||
self.last_resolved_system_prompt: str = ''
|
||||
self.last_md_path: Optional[Path] = None
|
||||
self.last_file_items: List[Any] = []
|
||||
self.send_thread: Optional[threading.Thread] = None
|
||||
@@ -2516,6 +2518,11 @@ class AppController:
|
||||
# Build discussion history text separately
|
||||
history = flat.get("discussion", {}).get("history", [])
|
||||
discussion_text = aggregate.build_discussion_text(history)
|
||||
|
||||
csp = filter(bool, [self.ui_global_system_prompt.strip(), self.ui_project_system_prompt.strip()])
|
||||
self.last_resolved_system_prompt = "\n\n".join(csp)
|
||||
self.last_aggregate_markdown = full_md
|
||||
|
||||
return full_md, path, file_items, stable_md, discussion_text
|
||||
|
||||
def _cb_plan_epic(self) -> None:
|
||||
|
||||
52
src/gui_2.py
52
src/gui_2.py
@@ -214,6 +214,7 @@ class App:
|
||||
self.show_windows.setdefault("Tier 4: QA", False)
|
||||
self.show_windows.setdefault('External Tools', False)
|
||||
self.show_windows.setdefault('Shader Editor', False)
|
||||
self.show_windows.setdefault('Session Hub', False)
|
||||
self.ui_multi_viewport = gui_cfg.get("multi_viewport", False)
|
||||
self.layout_presets = self.config.get("layout_presets", {})
|
||||
self._new_preset_name = ""
|
||||
@@ -322,7 +323,15 @@ class App:
|
||||
|
||||
@ui_file_paths.setter
|
||||
def ui_file_paths(self, paths: list[str]) -> None:
|
||||
self.files = [models.FileItem(path=p) for p in paths]
|
||||
old_files = {f.path: f for f in self.files if hasattr(f, 'path')}
|
||||
new_files = []
|
||||
now = time.time()
|
||||
for p in paths:
|
||||
if p in old_files:
|
||||
new_files.append(old_files[p])
|
||||
else:
|
||||
new_files.append(models.FileItem(path=p, injected_at=now))
|
||||
self.files = new_files
|
||||
|
||||
@property
|
||||
def ui_screenshot_paths(self) -> list[str]:
|
||||
@@ -849,6 +858,8 @@ class App:
|
||||
if self.show_windows.get("Diagnostics", False):
|
||||
self._render_diagnostics_panel()
|
||||
|
||||
self._render_session_hub()
|
||||
|
||||
self.perf_monitor.end_frame()
|
||||
# ---- Modals / Popups
|
||||
with self._pending_dialog_lock:
|
||||
@@ -2087,6 +2098,29 @@ class App:
|
||||
if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_diagnostics_panel")
|
||||
imgui.end()
|
||||
|
||||
def _render_session_hub(self) -> None:
|
||||
if self.show_windows.get('Session Hub', False):
|
||||
exp, opened = imgui.begin('Session Hub', self.show_windows['Session Hub'])
|
||||
self.show_windows['Session Hub'] = bool(opened)
|
||||
if exp:
|
||||
if imgui.begin_tab_bar('session_hub_tabs'):
|
||||
if imgui.begin_tab_item('Aggregate MD')[0]:
|
||||
if imgui.button("Copy"):
|
||||
imgui.set_clipboard_text(self.last_aggregate_markdown)
|
||||
imgui.begin_child("last_agg_md", imgui.ImVec2(0, 0), True)
|
||||
markdown_helper.render(self.last_aggregate_markdown, context_id="session_hub_agg")
|
||||
imgui.end_child()
|
||||
imgui.end_tab_item()
|
||||
if imgui.begin_tab_item('System Prompt')[0]:
|
||||
if imgui.button("Copy"):
|
||||
imgui.set_clipboard_text(self.last_resolved_system_prompt)
|
||||
imgui.begin_child("last_sys_prompt", imgui.ImVec2(0, 0), True)
|
||||
markdown_helper.render(self.last_resolved_system_prompt, context_id="session_hub_sys")
|
||||
imgui.end_child()
|
||||
imgui.end_tab_item()
|
||||
imgui.end_tab_bar()
|
||||
imgui.end()
|
||||
|
||||
def _render_markdown_test(self) -> None:
|
||||
imgui.text("Markdown Test Panel")
|
||||
imgui.separator()
|
||||
@@ -2397,6 +2431,22 @@ def hello():
|
||||
if ts_str:
|
||||
imgui.same_line()
|
||||
imgui.text_colored(vec4(120, 120, 100), str(ts_str))
|
||||
# Visual indicator for file injections
|
||||
e_dt = project_manager.parse_ts(ts_str)
|
||||
if e_dt:
|
||||
e_unix = e_dt.timestamp()
|
||||
next_unix = float('inf')
|
||||
if i + 1 < len(self.disc_entries):
|
||||
n_ts = self.disc_entries[i+1].get("ts", "")
|
||||
n_dt = project_manager.parse_ts(n_ts)
|
||||
if n_dt: next_unix = n_dt.timestamp()
|
||||
injected_here = [f for f in self.files if hasattr(f, 'injected_at') and f.injected_at and e_unix <= f.injected_at < next_unix]
|
||||
if injected_here:
|
||||
imgui.same_line()
|
||||
imgui.text_colored(vec4(100, 255, 100), f"[{len(injected_here)}+]")
|
||||
if imgui.is_item_hovered():
|
||||
tooltip = "Files injected at this point:\n" + "\n".join([f.path for f in injected_here])
|
||||
imgui.set_tooltip(tooltip)
|
||||
if collapsed:
|
||||
imgui.same_line()
|
||||
if imgui.button("Ins"):
|
||||
|
||||
@@ -357,12 +357,14 @@ class FileItem:
|
||||
path: str
|
||||
auto_aggregate: bool = True
|
||||
force_full: bool = False
|
||||
injected_at: Optional[float] = None
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"path": self.path,
|
||||
"auto_aggregate": self.auto_aggregate,
|
||||
"force_full": self.force_full,
|
||||
"injected_at": self.injected_at,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@@ -371,6 +373,7 @@ class FileItem:
|
||||
path=data["path"],
|
||||
auto_aggregate=data.get("auto_aggregate", True),
|
||||
force_full=data.get("force_full", False),
|
||||
injected_at=data.get("injected_at"),
|
||||
)
|
||||
|
||||
@dataclass
|
||||
|
||||
Reference in New Issue
Block a user