feat(gui): Implement Takes panel (Phase 4)
- Replaced _render_takes_placeholder with _render_takes_panel - Shows list of takes with entry count and switch/delete actions - Includes synthesis UI with take selection and prompt - Uses existing synthesis_formatter for diff generation
This commit is contained in:
58
src/gui_2.py
58
src/gui_2.py
@@ -734,7 +734,7 @@ class App:
|
|||||||
self._render_snapshot_tab()
|
self._render_snapshot_tab()
|
||||||
imgui.end_tab_item()
|
imgui.end_tab_item()
|
||||||
if imgui.begin_tab_item("Takes")[0]:
|
if imgui.begin_tab_item("Takes")[0]:
|
||||||
self._render_takes_placeholder()
|
self._render_takes_panel()
|
||||||
imgui.end_tab_item()
|
imgui.end_tab_item()
|
||||||
imgui.end_tab_bar()
|
imgui.end_tab_bar()
|
||||||
imgui.end()
|
imgui.end()
|
||||||
@@ -2175,11 +2175,61 @@ class App:
|
|||||||
imgui.end_tab_item()
|
imgui.end_tab_item()
|
||||||
imgui.end_tab_bar()
|
imgui.end_tab_bar()
|
||||||
|
|
||||||
def _render_takes_placeholder(self) -> None:
|
def _render_takes_panel(self) -> None:
|
||||||
imgui.text("Takes & Synthesis")
|
imgui.text("Takes & Synthesis")
|
||||||
imgui.separator()
|
imgui.separator()
|
||||||
imgui.text_colored(C_LBL, "Coming in Phase 4...")
|
discussions = self.project.get('discussion', {}).get('discussions', {})
|
||||||
|
if not hasattr(self, 'ui_synthesis_selected_takes'):
|
||||||
|
self.ui_synthesis_selected_takes = {name: False for name in discussions}
|
||||||
|
if not hasattr(self, 'ui_synthesis_prompt'):
|
||||||
|
self.ui_synthesis_prompt = ""
|
||||||
|
if imgui.begin_table("takes_table", 3, imgui.TableFlags_.resizable | imgui.TableFlags_.borders):
|
||||||
|
imgui.table_setup_column("Name", imgui.TableColumnFlags_.width_stretch)
|
||||||
|
imgui.table_setup_column("Entries", imgui.TableColumnFlags_.width_fixed, 80)
|
||||||
|
imgui.table_setup_column("Actions", imgui.TableColumnFlags_.width_fixed, 150)
|
||||||
|
imgui.table_headers_row()
|
||||||
|
for name, disc in discussions.items():
|
||||||
|
imgui.table_next_row()
|
||||||
|
imgui.table_set_column_index(0)
|
||||||
|
is_active = name == self.active_discussion
|
||||||
|
if is_active:
|
||||||
|
imgui.text_colored(C_IN, name)
|
||||||
|
else:
|
||||||
|
imgui.text(name)
|
||||||
|
imgui.table_set_column_index(1)
|
||||||
|
history = disc.get('history', [])
|
||||||
|
imgui.text(f"{len(history)}")
|
||||||
|
imgui.table_set_column_index(2)
|
||||||
|
if imgui.button(f"Switch##{name}"):
|
||||||
|
self._switch_discussion(name)
|
||||||
|
imgui.same_line()
|
||||||
|
if name != "main" and imgui.button(f"Delete##{name}"):
|
||||||
|
del discussions[name]
|
||||||
|
imgui.end_table()
|
||||||
|
imgui.separator()
|
||||||
|
imgui.text("Synthesis")
|
||||||
|
imgui.text("Select takes to synthesize:")
|
||||||
|
for name in discussions:
|
||||||
|
_, self.ui_synthesis_selected_takes[name] = imgui.checkbox(name, self.ui_synthesis_selected_takes.get(name, False))
|
||||||
|
imgui.spacing()
|
||||||
|
imgui.text("Synthesis Prompt:")
|
||||||
|
_, self.ui_synthesis_prompt = imgui.input_text_multiline("##synthesis_prompt", self.ui_synthesis_prompt, imgui.ImVec2(-1, 100))
|
||||||
|
if imgui.button("Generate Synthesis"):
|
||||||
|
selected = [name for name, sel in self.ui_synthesis_selected_takes.items() if sel]
|
||||||
|
if len(selected) > 1:
|
||||||
|
from src import synthesis_formatter
|
||||||
|
takes_dict = {name: discussions.get(name, {}).get('history', []) for name in selected}
|
||||||
|
diff_text = synthesis_formatter.format_takes_diff(takes_dict)
|
||||||
|
prompt = f"{self.ui_synthesis_prompt}\n\nHere are the variations:\n{diff_text}"
|
||||||
|
new_name = "synthesis_take"
|
||||||
|
counter = 1
|
||||||
|
while new_name in discussions:
|
||||||
|
new_name = f"synthesis_take_{counter}"
|
||||||
|
counter += 1
|
||||||
|
self._create_discussion(new_name)
|
||||||
|
with self._disc_entries_lock:
|
||||||
|
self.disc_entries.append({"role": "user", "content": prompt, "collapsed": False, "ts": project_manager.now_ts()})
|
||||||
|
self._handle_generate_send()
|
||||||
def _render_markdown_test(self) -> None:
|
def _render_markdown_test(self) -> None:
|
||||||
imgui.text("Markdown Test Panel")
|
imgui.text("Markdown Test Panel")
|
||||||
imgui.separator()
|
imgui.separator()
|
||||||
|
|||||||
16
tests/test_takes_panel.py
Normal file
16
tests/test_takes_panel.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import pytest
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
|
def test_takes_tab_replaces_placeholder():
|
||||||
|
import src.gui_2 as gui_2
|
||||||
|
|
||||||
|
source = inspect.getsource(gui_2.App._gui_func)
|
||||||
|
assert "_render_takes_placeholder" not in source, "Placeholder should be replaced"
|
||||||
|
|
||||||
|
|
||||||
|
def test_takes_panel_has_synthesis():
|
||||||
|
import src.gui_2 as gui_2
|
||||||
|
|
||||||
|
source = inspect.getsource(gui_2.App._render_takes_panel)
|
||||||
|
assert "synthesis" in source.lower(), "Should have synthesis functionality"
|
||||||
Reference in New Issue
Block a user