fixing regresssions

This commit is contained in:
2026-03-06 20:12:35 -05:00
parent 0e9f84f026
commit 4c92817928
6 changed files with 423 additions and 167 deletions

View File

@@ -1,5 +1,5 @@
[ai]
provider = "gemini_cli"
provider = "gemini"
model = "gemini-2.5-flash-lite"
temperature = 0.0
max_tokens = 8192

View File

@@ -44,16 +44,14 @@ Collapsed=0
DockId=0x00000006,0
[Window][Message]
Pos=0,749
Size=1680,451
Pos=2058,1284
Size=1633,667
Collapsed=0
DockId=0x0000000F,0
[Window][Response]
Pos=0,749
Size=1680,451
Pos=1142,771
Size=567,866
Collapsed=0
DockId=0x0000000F,1
[Window][Tool Calls]
ViewportPos=43,95
@@ -75,7 +73,7 @@ DockId=0x00000001,0
Pos=0,749
Size=1680,451
Collapsed=0
DockId=0x0000000F,2
DockId=0xAFC85805,2
[Window][Theme]
Pos=0,17
@@ -90,7 +88,7 @@ Collapsed=0
[Window][Diagnostics]
Pos=707,17
Size=1141,657
Size=1122,443
Collapsed=0
DockId=0x0000001A,0
@@ -107,14 +105,14 @@ Collapsed=0
DockId=0x0000000D,0
[Window][Discussion Hub]
Pos=1850,17
Size=1137,1311
Pos=1831,17
Size=1156,1507
Collapsed=0
DockId=0x00000013,0
[Window][Operations Hub]
Pos=707,676
Size=1141,652
Pos=707,462
Size=1122,1062
Collapsed=0
DockId=0x0000001B,0
@@ -153,26 +151,26 @@ Size=262,209
Collapsed=0
[Window][Tier 1: Strategy]
Pos=707,1330
Size=463,807
Pos=707,1526
Size=463,611
Collapsed=0
DockId=0x00000014,0
[Window][Tier 2: Tech Lead]
Pos=1172,1330
Size=730,807
Pos=1172,1526
Size=730,611
Collapsed=0
DockId=0x00000016,0
[Window][Tier 4: QA]
Pos=2453,1330
Size=534,807
Pos=2453,1526
Size=534,611
Collapsed=0
DockId=0x00000019,0
[Window][Tier 3: Workers]
Pos=1904,1330
Size=547,807
Pos=1904,1526
Size=547,611
Collapsed=0
DockId=0x00000018,0
@@ -208,35 +206,48 @@ Column 1 Weight=1.0000
Column 2 Weight=1.0000
Column 3 Weight=1.0000
[Table][0x8389904A,5]
RefScale=13
Column 0 Width=40
Column 1 Width=60
Column 2 Width=80
Column 3 Width=20
Column 4 Weight=1.0000
[Table][0x2A6000B6,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=Y
DockNode ID=0x0000000C Parent=0xAFC85805 SizeRef=1362,1041 Split=X Selected=0x5D11106F
DockNode ID=0x00000003 Parent=0x0000000C 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,1311 Split=X Selected=0x418C7449
DockNode ID=0x00000012 Parent=0x00000010 SizeRef=1141,402 Split=Y Selected=0xB4CBF21A
DockNode ID=0x0000001A Parent=0x00000012 SizeRef=1141,657 Selected=0xB4CBF21A
DockNode ID=0x0000001B Parent=0x00000012 SizeRef=1141,652 Selected=0x418C7449
DockNode ID=0x00000013 Parent=0x00000010 SizeRef=1137,402 Selected=0x6F2B5B04
DockNode ID=0x00000011 Parent=0x0000000E SizeRef=868,807 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=0x0000000C SizeRef=851,1183 Selected=0x3AEC3498
DockNode ID=0x0000000F Parent=0xAFC85805 SizeRef=1362,451 Selected=0xDD6419BC
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
;;;<<<Layout_655921752_Default>>>;;;
;;;<<<HelloImGui_Misc>>>;;;

View File

@@ -367,3 +367,220 @@ System:
test
------------------
--- 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>
[DISCUSSION HISTORY]
## Discussion History
### Discussion Excerpt 1
@2026-03-06T19:34:06
System:
[PERFORMANCE ALERT] Frame time high: 430.6ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 2
@2026-03-06T19:34:41
System:
[PERFORMANCE ALERT] Frame time high: 58.2ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 3
@2026-03-06T19:38:51
System:
[PERFORMANCE ALERT] Frame time high: 409.3ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 4
@2026-03-06T19:40:43
System:
[PERFORMANCE ALERT] Frame time high: 64.5ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 5
@2026-03-06T19:41:13
System:
[PERFORMANCE ALERT] CPU usage high: 94.0%. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 6
@2026-03-06T19:41:59
System:
[PERFORMANCE ALERT] Frame time high: 440.6ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 7
@2026-03-06T19:43:42
System:
[PERFORMANCE ALERT] Frame time high: 58.3ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 8
@2026-03-06T19:45:01
System:
[PERFORMANCE ALERT] Frame time high: 435.0ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 9
@2026-03-06T19:45:31
System:
[PERFORMANCE ALERT] CPU usage high: 114.1%. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 10
@2026-03-06T19:52:00
System:
[PERFORMANCE ALERT] Frame time high: 538.9ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 11
@2026-03-06T19:52:08
System:
[PERFORMANCE ALERT] Frame time high: 419.0ms. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 12
@2026-03-06T19:52:59
System:
[PERFORMANCE ALERT] CPU usage high: 121.9%. Please consider optimizing recent changes or reducing load.
---
### Discussion Excerpt 13
@2026-03-06T19:57:28
System:
[PERFORMANCE ALERT] CPU usage high: 92.2%. Please consider optimizing recent changes or reducing load.
---
test
------------------
--- 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>
another test
------------------
--- 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>
hows it going?
------------------
--- 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>
hows the day gone
------------------
--- 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>
tell me the day's date
------------------
--- 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>
[DISCUSSION HISTORY]
## Discussion History
### Discussion Excerpt 1
@2026-03-06T20:08:29
System:
[PERFORMANCE ALERT] CPU usage high: 93.0%. Please consider optimizing recent changes or reducing load.
---
testing 123
------------------

View File

@@ -134,7 +134,9 @@ def _get_combined_system_prompt() -> str:
return f"{_SYSTEM_PROMPT}\n\n[USER SYSTEM PROMPT]\n{_custom_system_prompt}"
return _SYSTEM_PROMPT
_comms_log: list[dict[str, Any]] = []
from collections import deque
_comms_log: deque[dict[str, Any]] = deque(maxlen=1000)
COMMS_CLAMP_CHARS: int = 300
@@ -147,6 +149,7 @@ def _append_comms(direction: str, kind: str, payload: dict[str, Any]) -> None:
"model": _model,
"payload": payload,
"source_tier": get_current_tier(),
"local_ts": time.time(),
}
_comms_log.append(entry)
if comms_log_callback is not None:

View File

@@ -822,13 +822,6 @@ class AppController:
sys.stderr.write("[DEBUG] _process_event_queue entered\n")
sys.stderr.flush()
def tick_perf():
while True:
self.perf_monitor.start_frame()
time.sleep(0.01) # Measurable frame time
self.perf_monitor.end_frame()
time.sleep(0.006) # Aim for ~60 FPS total
threading.Thread(target=tick_perf, daemon=True).start()
while True:
event_name, payload = self.event_queue.get()
sys.stderr.write(f"[DEBUG] _process_event_queue got event: {event_name} with payload: {str(payload)[:100]}\n")

View File

@@ -109,6 +109,8 @@ class App:
self.ui_separate_response_panel = gui_cfg.get("separate_response_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
def _handle_approve_tool(self, user_data=None) -> None:
@@ -184,22 +186,23 @@ class App:
self.show_text_viewer = True
self.text_viewer_title = label
self.text_viewer_content = content
if not content:
imgui.text_disabled("(empty)")
return
if len(content) > COMMS_CLAMP_CHARS:
if self.ui_word_wrap:
imgui.push_text_wrap_pos(imgui.get_content_region_avail().x)
imgui.text(content)
imgui.pop_text_wrap_pos()
else:
imgui.begin_child(f"heavy_text_child_{label}", imgui.ImVec2(0, 80), True)
imgui.input_text_multiline(f"##{label}_input", content, imgui.ImVec2(-1, -1), imgui.InputTextFlags_.read_only)
imgui.end_child()
# Use a fixed-height multi-line input box for large text to avoid expensive frame-by-frame wrapping
imgui.begin_child(f"heavy_text_child_{label}_{hash(content)}", imgui.ImVec2(0, 80), True)
imgui.input_text_multiline(f"##{label}_input", content, imgui.ImVec2(-1, -1), imgui.InputTextFlags_.read_only)
imgui.end_child()
else:
if self.ui_word_wrap:
imgui.push_text_wrap_pos(imgui.get_content_region_avail().x)
imgui.text(content if content else "(empty)")
imgui.push_text_wrap_pos(0.0)
imgui.text_unformatted(content)
imgui.pop_text_wrap_pos()
else:
imgui.text(content if content else "(empty)")
imgui.text_unformatted(content)
# ---------------------------------------------------------------- gui
def _show_menus(self) -> None:
@@ -272,6 +275,7 @@ class App:
if self.ui_focus_agent != self._last_ui_focus_agent:
self._comms_log_dirty = True
self._tool_log_dirty = True
self._last_ui_focus_agent = self.ui_focus_agent
if self._comms_log_dirty:
@@ -284,12 +288,23 @@ class App:
else:
self._comms_log_cache = log_raw
self._comms_log_dirty = False
if self._tool_log_dirty:
log_raw = list(self._tool_log)
if self.ui_focus_agent:
self._tool_log_cache = [e for e in log_raw if e.get("source_tier") == self.ui_focus_agent]
else:
self._tool_log_cache = log_raw
self._tool_log_dirty = False
with self._pending_tool_calls_lock:
if self._pending_tool_calls and self.ui_auto_scroll_tool_calls:
self._scroll_tool_calls_to_bottom = True
for tc in self._pending_tool_calls:
self._tool_log.append(tc)
self._pending_tool_calls.clear()
if self._pending_tool_calls:
if self.ui_auto_scroll_tool_calls:
self._scroll_tool_calls_to_bottom = True
self._tool_log_dirty = True
for tc in self._pending_tool_calls:
self._tool_log.append(tc)
self._pending_tool_calls.clear()
if self.show_windows.get("Context Hub", False):
exp, opened = imgui.begin("Context Hub", self.show_windows["Context Hub"])
self.show_windows["Context Hub"] = bool(opened)
@@ -1359,18 +1374,15 @@ class App:
imgui.push_style_color(imgui.Col_.frame_bg, vec4(0, 255, 0, alpha))
imgui.push_style_color(imgui.Col_.child_bg, vec4(0, 255, 0, alpha))
# --- Always Render Content ---
if self.ui_word_wrap:
imgui.begin_child("resp_wrap", imgui.ImVec2(-1, -40), True)
imgui.push_text_wrap_pos(imgui.get_content_region_avail().x)
imgui.text(self.ai_response)
imgui.pop_text_wrap_pos()
imgui.end_child()
else:
imgui.input_text_multiline("##ai_out", self.ai_response, imgui.ImVec2(-1, -40), imgui.InputTextFlags_.read_only)
imgui.begin_child("response_scroll_area", imgui.ImVec2(0, -40), True)
imgui.input_text_multiline("##ai_out", self.ai_response, imgui.ImVec2(-1, -1), imgui.InputTextFlags_.read_only)
imgui.end_child()
imgui.separator()
if imgui.button("-> History"):
if self.ai_response:
self.disc_entries.append({"role": "AI", "content": self.ai_response, "collapsed": False, "ts": project_manager.now_ts()})
self.disc_entries.append({"role": "AI", "content": self.ai_response, "collapsed": True, "ts": project_manager.now_ts()})
if is_blinking:
imgui.pop_style_color(2)
@@ -1380,6 +1392,7 @@ class App:
if imgui.button("Clear##comms"):
ai_client.clear_comms_log()
self._comms_log.clear()
self._comms_log_dirty = True
imgui.same_line()
if imgui.button("Load Log"):
self.cb_load_prior_log()
@@ -1391,40 +1404,48 @@ class App:
self._comms_log_dirty = True
self.ai_status = "idle"
imgui.separator()
imgui.text_colored(vec4(255, 200, 100), "VIEWING PRIOR SESSION")
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
if imgui.begin_table("comms_table", 5, flags):
# 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()
def payload_to_str(msg_kind, payload):
if msg_kind == "request":
return payload.get("message", "")
elif msg_kind == "response":
r = payload.get("round", 0)
sr = payload.get("stop_reason", "STOP")
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)
clipper = imgui.ListClipper()
clipper.begin(len(log_to_render))
while clipper.step():
@@ -1434,18 +1455,23 @@ class App:
i_display = i + 1
source = entry.get("source_tier", "main")
msg_type = entry.get("type", "?")
content_text = entry.get("content", "")
if len(content_text) > COMMS_CLAMP_CHARS:
content_text = content_text[:COMMS_CLAMP_CHARS] + "..."
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
# FG Color based on type
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_type == "request": fg = C_REQ
elif msg_type == "response": fg = C_RES
elif msg_type == "tool_call": fg = C_TC
elif msg_type == "tool_result": fg = C_TR
elif msg_type == "error": fg = vec4(255, 80, 80)
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}")
@@ -1454,7 +1480,7 @@ class App:
imgui.text_colored(C_SUB, f"[{source}]")
imgui.table_next_column()
imgui.text_colored(fg, msg_type)
imgui.text_colored(fg, msg_kind)
imgui.table_next_column()
elapsed = time.time() - entry.get("local_ts", 0)
@@ -1467,18 +1493,25 @@ class App:
imgui.table_next_column()
if self.ui_word_wrap:
imgui.push_text_wrap_pos(0.0)
imgui.text_unformatted(content_text)
imgui.text_unformatted(content_preview)
imgui.pop_text_wrap_pos()
else:
imgui.text_unformatted(content_text)
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()
if self._scroll_comms_to_bottom:
imgui.set_scroll_here_y(1.0)
self._scroll_comms_to_bottom = False
# 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.end_child()
if self.is_viewing_prior_session:
imgui.pop_style_color()
@@ -1487,57 +1520,56 @@ class App:
imgui.same_line()
if imgui.button("Clear##tc"):
self._tool_log.clear()
self._tool_log_dirty = True
imgui.separator()
imgui.begin_child("scroll_area")
clipper = imgui.ListClipper()
tool_log_filtered = self._tool_log if not self.ui_focus_agent else [
e for e in self._tool_log if e.get("source_tier") == self.ui_focus_agent
]
clipper = imgui.ListClipper()
clipper.begin(len(tool_log_filtered))
while clipper.step():
for i_minus_one in range(clipper.display_start, clipper.display_end):
i = i_minus_one + 1
entry = tool_log_filtered[i_minus_one]
script = entry["script"]
result = entry["result"]
first_line = script.split('\n')[0] if script else 'Empty Script'
imgui.text_colored(C_KEY, f"Call #{i}: {first_line}")
# Script Display imgui.text_colored(C_LBL, "Script:")
imgui.same_line()
if imgui.button(f"[+]##script_{i}"):
self.show_text_viewer = True
self.text_viewer_title = f"Call Script #{i}"
self.text_viewer_content = script
if self.ui_word_wrap:
imgui.begin_child(f"tc_script_wrap_{i}", imgui.ImVec2(-1, 72), True)
imgui.push_text_wrap_pos(imgui.get_content_region_avail().x)
imgui.text(script)
imgui.pop_text_wrap_pos()
imgui.end_child()
else:
imgui.begin_child(f"tc_script_fixed_width_{i}", imgui.ImVec2(0, 72), True, imgui.WindowFlags_.horizontal_scrollbar)
imgui.input_text_multiline(f"##tc_script_res_{i}", script, imgui.ImVec2(-1, -1), imgui.InputTextFlags_.read_only)
imgui.end_child()
# Result Display
imgui.text_colored(C_LBL, "Output:")
imgui.same_line()
if imgui.button(f"[+]##output_{i}"):
self.show_text_viewer = True
self.text_viewer_title = f"Call Output #{i}"
self.text_viewer_content = result
if self.ui_word_wrap:
imgui.begin_child(f"tc_res_wrap_{i}", imgui.ImVec2(-1, 72), True)
imgui.push_text_wrap_pos(imgui.get_content_region_avail().x)
imgui.text(result)
imgui.pop_text_wrap_pos()
imgui.end_child()
else:
imgui.begin_child(f"tc_res_fixed_width_{i}", imgui.ImVec2(0, 72), True, imgui.WindowFlags_.horizontal_scrollbar)
imgui.input_text_multiline(f"##tc_res_val_{i}", result, imgui.ImVec2(-1, -1), imgui.InputTextFlags_.read_only)
imgui.end_child()
imgui.separator()
imgui.end_child()
log_to_render = self._tool_log_cache
flags = imgui.TableFlags_.resizable | imgui.TableFlags_.hideable | imgui.TableFlags_.borders_inner_v | imgui.TableFlags_.row_bg | imgui.TableFlags_.scroll_y
if imgui.begin_table("tool_calls_table", 4, flags, imgui.ImVec2(0, 0)):
imgui.table_setup_column("#", imgui.TableColumnFlags_.width_fixed, 40)
imgui.table_setup_column("Tier", imgui.TableColumnFlags_.width_fixed, 60)
imgui.table_setup_column("Script", imgui.TableColumnFlags_.width_stretch)
imgui.table_setup_column("Result", imgui.TableColumnFlags_.width_fixed, 100)
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.table_next_row()
imgui.table_next_column()
imgui.text_colored(C_LBL, f"#{i+1}")
imgui.table_next_column()
imgui.text_colored(C_SUB, f"[{entry.get('source_tier', 'main')}]")
imgui.table_next_column()
script = entry.get("script", "")
script_preview = script.replace("\n", " ")[:150]
if len(script) > 150: script_preview += "..."
if imgui.selectable(f"{script_preview}##tc_{i}", False, imgui.SelectableFlags_.span_all_columns)[0]:
self.text_viewer_title = f"Tool Script #{i+1}"
self.text_viewer_content = script
self.show_text_viewer = True
imgui.table_next_column()
res = entry.get("result", "")
res_preview = res.replace("\n", " ")[:30]
if len(res) > 30: res_preview += "..."
if imgui.button(f"View##res_{i}"):
self.text_viewer_title = f"Call Output #{i+1}"
self.text_viewer_content = res
self.show_text_viewer = True
imgui.end_table()
if self._scroll_tool_calls_to_bottom:
imgui.set_scroll_here_y(1.0)
self._scroll_tool_calls_to_bottom = False
def _render_mma_dashboard(self) -> None:
# Task 5.3: Dense Summary Line