still fixing regressions
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
[ai]
|
||||
provider = "gemini"
|
||||
provider = "gemini_cli"
|
||||
model = "gemini-2.5-flash-lite"
|
||||
temperature = 0.0
|
||||
max_tokens = 8192
|
||||
@@ -21,6 +21,7 @@ active = "C:\\projects\\manual_slop\\tests\\artifacts\\temp_project.toml"
|
||||
[gui]
|
||||
separate_message_panel = false
|
||||
separate_response_panel = false
|
||||
separate_tool_calls_panel = false
|
||||
|
||||
[gui.show_windows]
|
||||
"Context Hub" = true
|
||||
@@ -33,8 +34,9 @@ separate_response_panel = false
|
||||
"Tier 4: QA" = true
|
||||
"Discussion Hub" = true
|
||||
"Operations Hub" = true
|
||||
Message = false
|
||||
Response = false
|
||||
Message = true
|
||||
Response = true
|
||||
"Tool Calls" = false
|
||||
Theme = true
|
||||
"Log Management" = true
|
||||
Diagnostics = true
|
||||
|
||||
@@ -64,7 +64,7 @@ py_set_signature = false
|
||||
py_set_var_declaration = false
|
||||
|
||||
[gemini_cli]
|
||||
binary_path = "C:\\projects\\manual_slop\\.venv\\Scripts\\python.exe C:\\projects\\manual_slop\\tests\\mock_gemini_cli.py"
|
||||
binary_path = "gemini"
|
||||
|
||||
[mma]
|
||||
epic = ""
|
||||
|
||||
@@ -44,22 +44,19 @@ Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Message]
|
||||
Pos=2058,1284
|
||||
Size=1633,667
|
||||
Pos=2830,1055
|
||||
Size=954,371
|
||||
Collapsed=0
|
||||
|
||||
[Window][Response]
|
||||
Pos=1142,771
|
||||
Size=567,866
|
||||
Pos=2941,1527
|
||||
Size=718,484
|
||||
Collapsed=0
|
||||
|
||||
[Window][Tool Calls]
|
||||
ViewportPos=43,95
|
||||
ViewportId=0x78C57832
|
||||
Pos=0,1121
|
||||
Size=897,775
|
||||
Pos=1300,926
|
||||
Size=700,440
|
||||
Collapsed=0
|
||||
DockId=0x00000001,1
|
||||
|
||||
[Window][Comms History]
|
||||
ViewportPos=43,95
|
||||
@@ -67,7 +64,7 @@ ViewportId=0x78C57832
|
||||
Pos=0,1121
|
||||
Size=897,775
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
DockId=0x0000000B,0
|
||||
|
||||
[Window][System Prompts]
|
||||
Pos=0,749
|
||||
@@ -77,7 +74,7 @@ DockId=0xAFC85805,2
|
||||
|
||||
[Window][Theme]
|
||||
Pos=0,17
|
||||
Size=705,927
|
||||
Size=705,960
|
||||
Collapsed=0
|
||||
DockId=0x00000005,1
|
||||
|
||||
@@ -88,13 +85,13 @@ Collapsed=0
|
||||
|
||||
[Window][Diagnostics]
|
||||
Pos=707,17
|
||||
Size=1122,443
|
||||
Size=1358,379
|
||||
Collapsed=0
|
||||
DockId=0x0000001A,0
|
||||
|
||||
[Window][Context Hub]
|
||||
Pos=0,17
|
||||
Size=705,927
|
||||
Size=705,960
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
@@ -105,26 +102,26 @@ Collapsed=0
|
||||
DockId=0x0000000D,0
|
||||
|
||||
[Window][Discussion Hub]
|
||||
Pos=1831,17
|
||||
Size=1156,1507
|
||||
Pos=2067,17
|
||||
Size=920,1883
|
||||
Collapsed=0
|
||||
DockId=0x00000013,0
|
||||
|
||||
[Window][Operations Hub]
|
||||
Pos=707,462
|
||||
Size=1122,1062
|
||||
Pos=707,398
|
||||
Size=1358,1502
|
||||
Collapsed=0
|
||||
DockId=0x0000001B,0
|
||||
|
||||
[Window][Files & Media]
|
||||
Pos=0,946
|
||||
Size=705,1191
|
||||
Pos=0,979
|
||||
Size=705,1158
|
||||
Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
|
||||
[Window][AI Settings]
|
||||
Pos=0,946
|
||||
Size=705,1191
|
||||
Pos=0,979
|
||||
Size=705,1158
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
@@ -151,26 +148,26 @@ Size=262,209
|
||||
Collapsed=0
|
||||
|
||||
[Window][Tier 1: Strategy]
|
||||
Pos=707,1526
|
||||
Size=463,611
|
||||
Pos=707,1902
|
||||
Size=463,235
|
||||
Collapsed=0
|
||||
DockId=0x00000014,0
|
||||
|
||||
[Window][Tier 2: Tech Lead]
|
||||
Pos=1172,1526
|
||||
Size=730,611
|
||||
Pos=1172,1902
|
||||
Size=730,235
|
||||
Collapsed=0
|
||||
DockId=0x00000016,0
|
||||
|
||||
[Window][Tier 4: QA]
|
||||
Pos=2453,1526
|
||||
Size=534,611
|
||||
Pos=2453,1902
|
||||
Size=534,235
|
||||
Collapsed=0
|
||||
DockId=0x00000019,0
|
||||
|
||||
[Window][Tier 3: Workers]
|
||||
Pos=1904,1526
|
||||
Size=547,611
|
||||
Pos=1904,1902
|
||||
Size=547,235
|
||||
Collapsed=0
|
||||
DockId=0x00000018,0
|
||||
|
||||
@@ -184,6 +181,21 @@ Pos=60,60
|
||||
Size=800,600
|
||||
Collapsed=0
|
||||
|
||||
[Window][Text Viewer - Log Entry #1 (request)]
|
||||
Pos=60,60
|
||||
Size=900,700
|
||||
Collapsed=0
|
||||
|
||||
[Window][Text Viewer - Log Entry #2 (response)]
|
||||
Pos=363,873
|
||||
Size=1005,366
|
||||
Collapsed=0
|
||||
|
||||
[Window][Text Viewer - Entry #11]
|
||||
Pos=60,60
|
||||
Size=900,700
|
||||
Collapsed=0
|
||||
|
||||
[Table][0xFB6E3870,4]
|
||||
RefScale=13
|
||||
Column 0 Width=80
|
||||
@@ -221,33 +233,47 @@ Column 1 Width=60
|
||||
Column 2 Weight=1.0000
|
||||
Column 3 Width=100
|
||||
|
||||
[Table][0x8BCC69C7,6]
|
||||
RefScale=13
|
||||
Column 0 Width=40
|
||||
Column 1 Width=60
|
||||
Column 2 Width=123
|
||||
Column 3 Width=20
|
||||
Column 4 Weight=1.0000
|
||||
Column 5 Width=50
|
||||
|
||||
[Table][0x3751446B,4]
|
||||
RefScale=13
|
||||
Column 0 Width=40
|
||||
Column 1 Width=60
|
||||
Column 2 Weight=1.0000
|
||||
Column 3 Width=100
|
||||
|
||||
[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,17 Size=3840,2120 Split=X
|
||||
DockNode ID=0x00000003 Parent=0xAFC85805 SizeRef=2987,1183 Split=X
|
||||
DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=Y Selected=0xF4139CA2
|
||||
DockNode ID=0x00000002 Parent=0x0000000B SizeRef=1029,1119 Split=X Selected=0xF4139CA2
|
||||
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=705,858 Split=Y Selected=0x8CA2375C
|
||||
DockNode ID=0x00000005 Parent=0x00000007 SizeRef=295,927 Selected=0xF4139CA2
|
||||
DockNode ID=0x00000006 Parent=0x00000007 SizeRef=295,1191 CentralNode=1 Selected=0x7BD57D6A
|
||||
DockNode ID=0x0000000E Parent=0x00000002 SizeRef=2280,858 Split=Y Selected=0x418C7449
|
||||
DockNode ID=0x00000010 Parent=0x0000000E SizeRef=868,1507 Split=X Selected=0x418C7449
|
||||
DockNode ID=0x00000012 Parent=0x00000010 SizeRef=1122,402 Split=Y Selected=0xB4CBF21A
|
||||
DockNode ID=0x0000001A Parent=0x00000012 SizeRef=1141,443 Selected=0xB4CBF21A
|
||||
DockNode ID=0x0000001B Parent=0x00000012 SizeRef=1141,1062 Selected=0x418C7449
|
||||
DockNode ID=0x00000013 Parent=0x00000010 SizeRef=1156,402 Selected=0x6F2B5B04
|
||||
DockNode ID=0x00000011 Parent=0x0000000E SizeRef=868,611 Split=X Selected=0x5CDB7A4B
|
||||
DockNode ID=0x00000014 Parent=0x00000011 SizeRef=463,837 Selected=0xBB346584
|
||||
DockNode ID=0x00000015 Parent=0x00000011 SizeRef=1815,837 Split=X Selected=0x5CDB7A4B
|
||||
DockNode ID=0x00000016 Parent=0x00000015 SizeRef=730,837 Selected=0x390E7942
|
||||
DockNode ID=0x00000017 Parent=0x00000015 SizeRef=1083,837 Split=X Selected=0x655BC6E9
|
||||
DockNode ID=0x00000018 Parent=0x00000017 SizeRef=547,874 Selected=0x655BC6E9
|
||||
DockNode ID=0x00000019 Parent=0x00000017 SizeRef=534,874 Selected=0x5CDB7A4B
|
||||
DockNode ID=0x00000001 Parent=0x0000000B SizeRef=1029,775 Selected=0x8B4EBFA6
|
||||
DockNode ID=0x0000000D Parent=0x00000003 SizeRef=435,1186 Selected=0x363E93D6
|
||||
DockNode ID=0x00000004 Parent=0xAFC85805 SizeRef=851,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,17 Size=3840,2120 Split=X
|
||||
DockNode ID=0x00000003 Parent=0xAFC85805 SizeRef=2987,1183 Split=X
|
||||
DockNode ID=0x0000000B Parent=0x00000003 SizeRef=404,1186 Split=X Selected=0xF4139CA2
|
||||
DockNode ID=0x00000007 Parent=0x0000000B SizeRef=705,858 Split=Y Selected=0x8CA2375C
|
||||
DockNode ID=0x00000005 Parent=0x00000007 SizeRef=295,960 Selected=0xF4139CA2
|
||||
DockNode ID=0x00000006 Parent=0x00000007 SizeRef=295,1158 CentralNode=1 Selected=0x7BD57D6A
|
||||
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=2280,858 Split=Y Selected=0x418C7449
|
||||
DockNode ID=0x00000010 Parent=0x0000000E SizeRef=868,1883 Split=X Selected=0x418C7449
|
||||
DockNode ID=0x00000012 Parent=0x00000010 SizeRef=1358,402 Split=Y Selected=0xB4CBF21A
|
||||
DockNode ID=0x0000001A Parent=0x00000012 SizeRef=1141,379 Selected=0xB4CBF21A
|
||||
DockNode ID=0x0000001B Parent=0x00000012 SizeRef=1141,1502 Selected=0x418C7449
|
||||
DockNode ID=0x00000013 Parent=0x00000010 SizeRef=920,402 Selected=0x6F2B5B04
|
||||
DockNode ID=0x00000011 Parent=0x0000000E SizeRef=868,235 Split=X Selected=0x5CDB7A4B
|
||||
DockNode ID=0x00000014 Parent=0x00000011 SizeRef=463,837 Selected=0xBB346584
|
||||
DockNode ID=0x00000015 Parent=0x00000011 SizeRef=1815,837 Split=X Selected=0x5CDB7A4B
|
||||
DockNode ID=0x00000016 Parent=0x00000015 SizeRef=730,837 Selected=0x390E7942
|
||||
DockNode ID=0x00000017 Parent=0x00000015 SizeRef=1083,837 Split=X Selected=0x655BC6E9
|
||||
DockNode ID=0x00000018 Parent=0x00000017 SizeRef=547,874 Selected=0x655BC6E9
|
||||
DockNode ID=0x00000019 Parent=0x00000017 SizeRef=534,874 Selected=0x5CDB7A4B
|
||||
DockNode ID=0x0000000D Parent=0x00000003 SizeRef=435,1186 Selected=0x363E93D6
|
||||
DockNode ID=0x00000004 Parent=0xAFC85805 SizeRef=851,1183 Selected=0x3AEC3498
|
||||
|
||||
;;;<<<Layout_655921752_Default>>>;;;
|
||||
;;;<<<HelloImGui_Misc>>>;;;
|
||||
|
||||
@@ -584,3 +584,51 @@ System:
|
||||
|
||||
testing 123
|
||||
------------------
|
||||
--- MOCK INVOKED ---
|
||||
ARGS: ['C:\\projects\\manual_slop\\tests\\mock_gemini_cli.py', '-m', 'gemini-2.5-flash-lite', '--prompt', '', '--output-format', 'stream-json']
|
||||
PROMPT:
|
||||
You are a helpful coding assistant with access to a PowerShell tool (run_powershell) and MCP tools (file access: read_file, list_directory, search_files, get_file_summary, web access: web_search, fetch_url). When calling file/directory tools, always use the 'path' parameter for the target path. When asked to create or edit files, prefer targeted edits over full rewrites. Always explain what you are doing before invoking the tool.
|
||||
|
||||
When writing or rewriting large files (especially those containing quotes, backticks, or special characters), avoid python -c with inline strings. Instead: (1) write a .py helper script to disk using a PS here-string (@'...'@ for literal content), (2) run it with `python <script>`, (3) delete the helper. For small targeted edits, use PowerShell's (Get-Content) / .Replace() / Set-Content or Add-Content directly.
|
||||
|
||||
When making function calls using tools that accept array or object parameters ensure those are structured using JSON. For example:
|
||||
When you need to verify a change, rely on the exit code and stdout/stderr from the tool — the user's context files are automatically refreshed after every tool call, so you do NOT need to re-read files that are already provided in the <context> block.
|
||||
|
||||
<context>
|
||||
|
||||
</context>
|
||||
|
||||
testing gemini
|
||||
------------------
|
||||
--- MOCK INVOKED ---
|
||||
ARGS: ['C:\\projects\\manual_slop\\tests\\mock_gemini_cli.py', '-m', 'gemini-2.5-flash-lite', '--prompt', '', '--resume', 'mock-session-default', '--output-format', 'stream-json']
|
||||
PROMPT:
|
||||
You are a helpful coding assistant with access to a PowerShell tool (run_powershell) and MCP tools (file access: read_file, list_directory, search_files, get_file_summary, web access: web_search, fetch_url). When calling file/directory tools, always use the 'path' parameter for the target path. When asked to create or edit files, prefer targeted edits over full rewrites. Always explain what you are doing before invoking the tool.
|
||||
|
||||
When writing or rewriting large files (especially those containing quotes, backticks, or special characters), avoid python -c with inline strings. Instead: (1) write a .py helper script to disk using a PS here-string (@'...'@ for literal content), (2) run it with `python <script>`, (3) delete the helper. For small targeted edits, use PowerShell's (Get-Content) / .Replace() / Set-Content or Add-Content directly.
|
||||
|
||||
When making function calls using tools that accept array or object parameters ensure those are structured using JSON. For example:
|
||||
When you need to verify a change, rely on the exit code and stdout/stderr from the tool — the user's context files are automatically refreshed after every tool call, so you do NOT need to re-read files that are already provided in the <context> block.
|
||||
|
||||
<context>
|
||||
|
||||
</context>
|
||||
|
||||
1+ 1?
|
||||
------------------
|
||||
--- MOCK INVOKED ---
|
||||
ARGS: ['C:\\projects\\manual_slop\\tests\\mock_gemini_cli.py', '-m', 'gemini-2.5-flash-lite', '--prompt', '', '--resume', 'mock-session-final', '--output-format', 'stream-json']
|
||||
PROMPT:
|
||||
You are a helpful coding assistant with access to a PowerShell tool (run_powershell) and MCP tools (file access: read_file, list_directory, search_files, get_file_summary, web access: web_search, fetch_url). When calling file/directory tools, always use the 'path' parameter for the target path. When asked to create or edit files, prefer targeted edits over full rewrites. Always explain what you are doing before invoking the tool.
|
||||
|
||||
When writing or rewriting large files (especially those containing quotes, backticks, or special characters), avoid python -c with inline strings. Instead: (1) write a .py helper script to disk using a PS here-string (@'...'@ for literal content), (2) run it with `python <script>`, (3) delete the helper. For small targeted edits, use PowerShell's (Get-Content) / .Replace() / Set-Content or Add-Content directly.
|
||||
|
||||
When making function calls using tools that accept array or object parameters ensure those are structured using JSON. For example:
|
||||
When you need to verify a change, rely on the exit code and stdout/stderr from the tool — the user's context files are automatically refreshed after every tool call, so you do NOT need to re-read files that are already provided in the <context> block.
|
||||
|
||||
<context>
|
||||
|
||||
</context>
|
||||
|
||||
1+ 1?
|
||||
------------------
|
||||
|
||||
@@ -640,6 +640,7 @@ class AppController:
|
||||
"Operations Hub": True,
|
||||
"Message": False,
|
||||
"Response": False,
|
||||
"Tool Calls": False,
|
||||
"Theme": True,
|
||||
"Log Management": False,
|
||||
"Diagnostics": False,
|
||||
@@ -1714,6 +1715,7 @@ class AppController:
|
||||
"show_windows": self.show_windows,
|
||||
"separate_message_panel": getattr(self, "ui_separate_message_panel", False),
|
||||
"separate_response_panel": getattr(self, "ui_separate_response_panel", False),
|
||||
"separate_tool_calls_panel": getattr(self, "ui_separate_tool_calls_panel", False),
|
||||
}
|
||||
theme.save_to_config(self.config)
|
||||
|
||||
|
||||
205
src/gui_2.py
205
src/gui_2.py
@@ -107,11 +107,13 @@ class App:
|
||||
gui_cfg = self.config.get("gui", {})
|
||||
self.ui_separate_message_panel = gui_cfg.get("separate_message_panel", False)
|
||||
self.ui_separate_response_panel = gui_cfg.get("separate_response_panel", False)
|
||||
self.ui_separate_tool_calls_panel = gui_cfg.get("separate_tool_calls_panel", False)
|
||||
self._comms_log_cache: list[dict[str, Any]] = []
|
||||
self._comms_log_dirty: bool = True
|
||||
self._tool_log_cache: list[dict[str, Any]] = []
|
||||
self._tool_log_dirty: bool = True
|
||||
self._last_ui_focus_agent: Optional[str] = None
|
||||
self._log_registry: Optional[log_registry.LogRegistry] = None
|
||||
|
||||
def _handle_approve_tool(self, user_data=None) -> None:
|
||||
"""UI-level wrapper for approving a pending tool execution ask."""
|
||||
@@ -426,15 +428,22 @@ class App:
|
||||
if imgui.button("x##clear_focus"):
|
||||
self.ui_focus_agent = None
|
||||
if exp:
|
||||
imgui.push_style_var(imgui.StyleVar_.item_spacing, imgui.ImVec2(10, 4))
|
||||
ch, self.ui_separate_tool_calls_panel = imgui.checkbox("Pop Out Tool Calls", self.ui_separate_tool_calls_panel)
|
||||
if ch: self.show_windows["Tool Calls"] = self.ui_separate_tool_calls_panel
|
||||
imgui.pop_style_var()
|
||||
|
||||
show_tc_tab = not self.ui_separate_tool_calls_panel
|
||||
|
||||
if imgui.begin_tab_bar("ops_tabs"):
|
||||
if imgui.begin_tab_item("Comms History")[0]:
|
||||
self._render_comms_history_panel()
|
||||
imgui.end_tab_item()
|
||||
if imgui.begin_tab_item("Tool Calls")[0]:
|
||||
self._render_tool_calls_panel()
|
||||
imgui.end_tab_item()
|
||||
if show_tc_tab:
|
||||
if imgui.begin_tab_item("Tool Calls")[0]:
|
||||
self._render_tool_calls_panel()
|
||||
imgui.end_tab_item()
|
||||
imgui.end_tab_bar()
|
||||
|
||||
imgui.end()
|
||||
|
||||
if self.ui_separate_message_panel and self.show_windows.get("Message", False):
|
||||
@@ -451,6 +460,13 @@ class App:
|
||||
self._render_response_panel()
|
||||
imgui.end()
|
||||
|
||||
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"])
|
||||
self.show_windows["Tool Calls"] = bool(opened)
|
||||
if exp:
|
||||
self._render_tool_calls_panel()
|
||||
imgui.end()
|
||||
|
||||
if self.show_windows.get("Log Management", False):
|
||||
self._render_log_management()
|
||||
if self.show_windows["Diagnostics"]:
|
||||
@@ -863,7 +879,18 @@ class App:
|
||||
if not exp:
|
||||
imgui.end()
|
||||
return
|
||||
registry = log_registry.LogRegistry(str(paths.get_logs_dir() / "log_registry.toml"))
|
||||
|
||||
if self._log_registry is None:
|
||||
self._log_registry = log_registry.LogRegistry(str(paths.get_logs_dir() / "log_registry.toml"))
|
||||
else:
|
||||
# Refresh data occasionally or on demand? For now let's just use the cached object.
|
||||
# The LogRegistry object loads data into self.data upon __init__.
|
||||
# We might want a refresh button or to reload every few seconds.
|
||||
if imgui.button("Refresh Registry"):
|
||||
self._log_registry = log_registry.LogRegistry(str(paths.get_logs_dir() / "log_registry.toml"))
|
||||
imgui.same_line()
|
||||
|
||||
registry = self._log_registry
|
||||
sessions = registry.data
|
||||
if imgui.begin_table("sessions_table", 7, imgui.TableFlags_.borders | imgui.TableFlags_.row_bg | imgui.TableFlags_.resizable):
|
||||
imgui.table_setup_column("Session ID")
|
||||
@@ -1145,6 +1172,8 @@ class App:
|
||||
if imgui.button("+" if collapsed else "-"):
|
||||
entry["collapsed"] = not collapsed
|
||||
imgui.same_line()
|
||||
self._render_text_viewer(f"Entry #{i+1}", entry["content"])
|
||||
imgui.same_line()
|
||||
imgui.set_next_item_width(120)
|
||||
if imgui.begin_combo("##role", entry["role"]):
|
||||
for r in self.disc_roles:
|
||||
@@ -1164,8 +1193,6 @@ class App:
|
||||
if imgui.button("Ins"):
|
||||
self.disc_entries.insert(i, {"role": "User", "content": "", "collapsed": True, "ts": project_manager.now_ts()})
|
||||
imgui.same_line()
|
||||
self._render_text_viewer(f"Entry #{i+1}", entry["content"])
|
||||
imgui.same_line()
|
||||
if imgui.button("Del"):
|
||||
self.disc_entries.pop(i)
|
||||
imgui.pop_id()
|
||||
@@ -1405,113 +1432,88 @@ class App:
|
||||
self.ai_status = "idle"
|
||||
imgui.separator()
|
||||
|
||||
imgui.text_colored(C_OUT, "OUT")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(C_REQ, "request")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(C_TC, "tool_call")
|
||||
imgui.same_line()
|
||||
imgui.text(" ")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(C_IN, "IN")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(C_RES, "response")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(C_TR, "tool_result")
|
||||
imgui.separator()
|
||||
|
||||
# Use tinted background for prior session
|
||||
if self.is_viewing_prior_session:
|
||||
imgui.push_style_color(imgui.Col_.child_bg, vec4(40, 30, 20))
|
||||
|
||||
imgui.begin_child("comms_scroll", imgui.ImVec2(0, 0), False, imgui.WindowFlags_.horizontal_scrollbar)
|
||||
|
||||
log_to_render = self._comms_log_cache
|
||||
|
||||
flags = imgui.TableFlags_.resizable | imgui.TableFlags_.hideable | imgui.TableFlags_.borders_inner_v | imgui.TableFlags_.row_bg | imgui.TableFlags_.scroll_y
|
||||
|
||||
# Set a max height for the table or use available region
|
||||
avail = imgui.get_content_region_avail()
|
||||
if imgui.begin_table("comms_table", 6, flags, imgui.ImVec2(0, avail.y)):
|
||||
imgui.table_setup_column("#", imgui.TableColumnFlags_.width_fixed, 40)
|
||||
imgui.table_setup_column("Tier", imgui.TableColumnFlags_.width_fixed, 60)
|
||||
imgui.table_setup_column("Type", imgui.TableColumnFlags_.width_fixed, 80)
|
||||
imgui.table_setup_column("!", imgui.TableColumnFlags_.width_fixed, 20)
|
||||
imgui.table_setup_column("Content", imgui.TableColumnFlags_.width_stretch)
|
||||
imgui.table_setup_column("Action", imgui.TableColumnFlags_.width_fixed, 50)
|
||||
|
||||
imgui.table_headers_row()
|
||||
clipper = imgui.ListClipper()
|
||||
clipper.begin(len(log_to_render))
|
||||
while clipper.step():
|
||||
for i in range(clipper.display_start, clipper.display_end):
|
||||
entry = log_to_render[i]
|
||||
imgui.push_id(f"comms_entry_{i}")
|
||||
|
||||
i_display = i + 1
|
||||
ts = entry.get("ts", "00:00:00")
|
||||
direction = entry.get("direction", "??")
|
||||
kind = entry.get("kind", entry.get("type", "??"))
|
||||
provider = entry.get("provider", "?")
|
||||
model = entry.get("model", "?")
|
||||
tier = entry.get("source_tier", "main")
|
||||
payload = entry.get("payload", {})
|
||||
if not payload and kind not in ("request", "response", "tool_call", "tool_result"):
|
||||
payload = entry # legacy
|
||||
|
||||
def payload_to_str(msg_kind, payload):
|
||||
if msg_kind == "request":
|
||||
return payload.get("message", "")
|
||||
elif msg_kind == "response":
|
||||
# Row 1: #Idx TS DIR KIND Provider/Model [Tier]
|
||||
imgui.text_colored(C_LBL, f"#{i_display}")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(vec4(160, 160, 160), ts)
|
||||
imgui.same_line()
|
||||
d_col = DIR_COLORS.get(direction, C_VAL)
|
||||
imgui.text_colored(d_col, direction)
|
||||
imgui.same_line()
|
||||
k_col = KIND_COLORS.get(kind, C_VAL)
|
||||
imgui.text_colored(k_col, kind)
|
||||
imgui.same_line()
|
||||
imgui.text_colored(C_LBL, f"{provider}/{model}")
|
||||
imgui.same_line()
|
||||
imgui.text_colored(C_SUB, f"[{tier}]")
|
||||
|
||||
# Optimized content rendering using _render_heavy_text logic
|
||||
if kind == "request":
|
||||
self._render_heavy_text("message", payload.get("message", ""))
|
||||
elif kind == "response":
|
||||
r = payload.get("round", 0)
|
||||
sr = payload.get("stop_reason", "STOP")
|
||||
text = payload.get("text", "")
|
||||
imgui.text_colored(C_LBL, f"round: {r} stop_reason: {sr}")
|
||||
self._render_heavy_text("text", payload.get("text", ""))
|
||||
tcs = payload.get("tool_calls", [])
|
||||
tc_str = f" ({len(tcs)} tool calls)" if tcs else ""
|
||||
return f"[R{r}] [{sr}]{tc_str} {text}"
|
||||
elif msg_kind == "tool_call":
|
||||
content = f"Call: {payload.get('name', '?')}"
|
||||
if "script" in payload:
|
||||
content += f" | Script: {payload['script']}"
|
||||
elif "args" in payload:
|
||||
content += f" | Args: {json.dumps(payload['args'])}"
|
||||
return content
|
||||
elif msg_kind == "tool_result":
|
||||
return f"Result: {payload.get('name', '?')} | {payload.get('output', '')}"
|
||||
return str(payload)
|
||||
if tcs:
|
||||
self._render_heavy_text("tool_calls", json.dumps(tcs, indent=1))
|
||||
elif kind == "tool_call":
|
||||
self._render_heavy_text(payload.get("name", "call"), payload.get("script") or json.dumps(payload.get("args", {}), indent=1))
|
||||
elif kind == "tool_result":
|
||||
self._render_heavy_text(payload.get("name", "result"), payload.get("output", ""))
|
||||
else:
|
||||
self._render_heavy_text("data", str(payload))
|
||||
|
||||
clipper = imgui.ListClipper()
|
||||
clipper.begin(len(log_to_render))
|
||||
while clipper.step():
|
||||
for i in range(clipper.display_start, clipper.display_end):
|
||||
entry = log_to_render[i]
|
||||
imgui.table_next_row()
|
||||
|
||||
i_display = i + 1
|
||||
source = entry.get("source_tier", "main")
|
||||
msg_kind = entry.get("kind", entry.get("type", "?")) # Handle legacy 'type'
|
||||
payload = entry.get("payload", {})
|
||||
if not payload and msg_kind not in ("request", "response", "tool_call", "tool_result"):
|
||||
payload = entry # Legacy format where entry IS the payload
|
||||
|
||||
full_content = payload_to_str(msg_kind, payload)
|
||||
content_preview = full_content
|
||||
if len(content_preview) > 500: # Increased clamp
|
||||
content_preview = content_preview[:500] + "..."
|
||||
|
||||
# FG Color based on kind
|
||||
fg = C_VAL
|
||||
if msg_kind == "request": fg = C_REQ
|
||||
elif msg_kind == "response": fg = C_RES
|
||||
elif msg_kind == "tool_call": fg = C_TC
|
||||
elif msg_kind == "tool_result": fg = C_TR
|
||||
elif msg_kind == "error": fg = vec4(255, 80, 80)
|
||||
|
||||
imgui.table_next_column()
|
||||
imgui.text_colored(C_LBL, f"#{i_display}")
|
||||
|
||||
imgui.table_next_column()
|
||||
imgui.text_colored(C_SUB, f"[{source}]")
|
||||
|
||||
imgui.table_next_column()
|
||||
imgui.text_colored(fg, msg_kind)
|
||||
|
||||
imgui.table_next_column()
|
||||
elapsed = time.time() - entry.get("local_ts", 0)
|
||||
if elapsed < 3.0:
|
||||
blink = (math.sin(elapsed * 15) * 0.5 + 0.5)
|
||||
imgui.text_colored(vec4(255, 255, 0, blink), "*")
|
||||
else:
|
||||
imgui.text("")
|
||||
|
||||
imgui.table_next_column()
|
||||
if self.ui_word_wrap:
|
||||
imgui.push_text_wrap_pos(0.0)
|
||||
imgui.text_unformatted(content_preview)
|
||||
imgui.pop_text_wrap_pos()
|
||||
else:
|
||||
imgui.text_unformatted(content_preview)
|
||||
|
||||
imgui.table_next_column()
|
||||
if imgui.button(f"View##{i}"):
|
||||
self.text_viewer_title = f"Log Entry #{i_display} ({msg_kind})"
|
||||
self.text_viewer_content = full_content
|
||||
self.show_text_viewer = True
|
||||
|
||||
imgui.end_table()
|
||||
imgui.separator()
|
||||
imgui.pop_id()
|
||||
|
||||
if self._scroll_comms_to_bottom:
|
||||
# Table with scroll_y handles its own scrolling
|
||||
# We might need ed.set_scroll_y or similar if we wanted precise control
|
||||
# but usually imgui.set_scroll_here_y works inside the table
|
||||
pass
|
||||
imgui.set_scroll_here_y(1.0)
|
||||
self._scroll_comms_to_bottom = False
|
||||
|
||||
imgui.end_child()
|
||||
if self.is_viewing_prior_session:
|
||||
imgui.pop_style_color()
|
||||
|
||||
@@ -1993,9 +1995,10 @@ class App:
|
||||
imgui.separator()
|
||||
ch1, self.ui_separate_message_panel = imgui.checkbox("Separate Message Panel", self.ui_separate_message_panel)
|
||||
ch2, self.ui_separate_response_panel = imgui.checkbox("Separate Response Panel", self.ui_separate_response_panel)
|
||||
ch3, self.ui_separate_tool_calls_panel = imgui.checkbox("Separate Tool Calls Panel", self.ui_separate_tool_calls_panel)
|
||||
if ch1: self.show_windows["Message"] = self.ui_separate_message_panel
|
||||
if ch2: self.show_windows["Response"] = self.ui_separate_response_panel
|
||||
|
||||
if ch3: self.show_windows["Tool Calls"] = self.ui_separate_tool_calls_panel
|
||||
imgui.separator()
|
||||
imgui.text("Font")
|
||||
imgui.push_item_width(-150)
|
||||
|
||||
Reference in New Issue
Block a user