From b4734f4bba44606b1af243b9e05d76478ea568a8 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 22 Feb 2026 17:28:00 -0500 Subject: [PATCH] fix for gui --- config.toml | 2 +- gui.py | 24 +++++++++++++++--------- manual_slop.toml | 9 ++++++++- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/config.toml b/config.toml index 527645c..b360adf 100644 --- a/config.toml +++ b/config.toml @@ -10,7 +10,7 @@ system_prompt = "DO NOT EVER make a shell script unless told to. DO NOT EVER mak palette = "10x Dark" font_path = "C:/Users/Ed/AppData/Local/uv/cache/archive-v0/WSthkYsQ82b_ywV6DkiaJ/pygame_gui/data/FiraCode-Regular.ttf" font_size = 18.0 -scale = 1.1 +scale = 1.25 [projects] paths = [ diff --git a/gui.py b/gui.py index 495923b..015a232 100644 --- a/gui.py +++ b/gui.py @@ -1,4 +1,4 @@ -# gui.py +# gui.py """ Note(Gemini): The main DearPyGui interface orchestrator. @@ -301,9 +301,9 @@ class ConfirmDialog: with dpg.group(horizontal=True): dpg.add_text("Script:") dpg.add_button( - label="[+ Maximize]", - user_data=f"{self._tag}_script", - callback=lambda s, a, u: _show_text_viewer("Confirm Script", dpg.get_value(u)) + label="[+ Maximize]", + user_data=self._script, + callback=lambda s, a, u: _show_text_viewer("Confirm Script", u) ) dpg.add_input_text( tag=f"{self._tag}_script", @@ -432,6 +432,8 @@ class App: self._pending_dialog_lock = threading.Lock() self._tool_log: list[tuple[str, str]] = [] + self._last_script: str = "" + self._last_output: str = "" # Comms log entries queued from background thread for main-thread rendering self._pending_comms: list[dict] = [] @@ -748,6 +750,8 @@ class App: return output def _append_tool_log(self, script: str, result: str): + self._last_script = script + self._last_output = result self._tool_log.append((script, result)) self._rebuild_tool_log() @@ -1917,8 +1921,7 @@ class App: dpg.add_text("Script:") dpg.add_button( label="[+ Maximize]", - user_data="last_script_text", - callback=lambda s, a, u: _show_text_viewer("Last Script", dpg.get_value(u)) + callback=lambda s, a, u: _show_text_viewer("Last Script", self._last_script), ) dpg.add_input_text( tag="last_script_text", @@ -1934,8 +1937,7 @@ class App: dpg.add_text("Output:") dpg.add_button( label="[+ Maximize]", - user_data="last_script_output", - callback=lambda s, a, u: _show_text_viewer("Last Output", dpg.get_value(u)) + callback=lambda s, a, u: _show_text_viewer("Last Output", self._last_output), ) dpg.add_input_text( tag="last_script_output", @@ -2119,4 +2121,8 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() + + + + diff --git a/manual_slop.toml b/manual_slop.toml index e71259a..8ad8c26 100644 --- a/manual_slop.toml +++ b/manual_slop.toml @@ -25,6 +25,7 @@ paths = [ "C:/projects/manual_slop/project_manager.py", "C:/projects/manual_slop/mcp_client.py", "C:/projects/manual_slop/summarize.py", + "C:\\projects\\manual_slop\\docs\\**\\*", ] [screenshots] @@ -161,8 +162,14 @@ history = [ [discussion.discussions.docs] git_commit = "" -last_updated = "2026-02-22T17:16:20" +last_updated = "2026-02-22T17:26:12" history = [ "@2026-02-22T17:05:29\nUser:\nUpdate docs with latest state of the codebase files. ai_client.py and aggregate.py both recieved updates.", "@2026-02-22T17:06:43\nVendor API:\n[GEMINI QUOTA EXHAUSTED]\n\n429 RESOURCE_EXHAUSTED. {'error': {'code': 429, 'message': 'Resource has been exhausted (e.g. check quota).', 'status': 'RESOURCE_EXHAUSTED'}}", + "@2026-02-22T17:16:20\nUser:\nswitched to sonnet 4.6 try to finish.", + "@2026-02-22T17:17:21\nAI:\nLet me read the MainContext.md file first to see what needs to be updated.\n\nNow I have the full picture. The previous task was to update MainContext.md with the latest state of `ai_client.py` and `aggregate.py`. The key changes I need to document are:\n\n1. **`ai_client.py`**: Added `web_search` and `fetch_url` to MCP tools (they're in the tool specs and dispatch)\n2. **`aggregate.py`**: The `run()` function now uses `build_markdown_from_items` (avoiding double I/O), and `summary_only=False` is the default\n\nLet me update the relevant sections in MainContext.md:\n\nNow update the aggregate.py bullet and add a note about the `run()` function's double-I/O optimization:\n\nNow append a new \"Latest Changes\" entry at the bottom of the file to document these updates clearly:\n\nMainContext.md has been updated with:\n\n1. **`mcp_client.py` bullet** — updated to list all 6 tools (including `web_search` and `fetch_url`), noting web tools are unrestricted while file tools remain access-controlled.\n\n2. **`aggregate.py` bullet** — clarified that `run()` returns a 3-tuple, uses `build_markdown_from_items` to avoid double I/O, and that `summary_only=False` is the default.\n\n3. **MCP file tools section** — renamed to \"MCP tools\", updated the tool count to 6, added descriptions for `web_search` (`_DDGParser`) and `fetch_url` (`_TextExtractor`, 40k char truncation, DDG redirect handling).\n\n4. **New \"Updates (2026-02-22)\" section** at the bottom summarising all the changes in both files.", + "@2026-02-22T17:20:36\nUser:\nLets also update the other docs if they don't accurately represent how ai_client works anymore, including the header comment of the file.\nSee docs/guide_architecture.py and docs/Readme.md", + "@2026-02-22T17:22:33\nAI:\n(User annotation, ai did some basic scavaging but was interrupted by bad tool prompt bug)", + "@2026-02-22T17:23:07\nUser:\napologies you were trying to do a tool call and my panel glitched when I attempted to maximize the view, we problably need to also fix that (gui.py related).", + "@2026-02-22T17:25:34\nAI:\nLet me read the current state of the relevant files to understand what happened and what needs to be updated.\n\nGood. Now I have the full picture. There are two tasks:\n\n1. **Update the docs** (`guide_architecture.md`, `guide_tools.md`, `docs/Readme.md`) to reflect the current state of `ai_client.py` (web tools, Gemini cache management, etc.)\n2. **Fix the GUI bug** — the `_show_text_viewer` callback crashes when called from a button inside the ConfirmDialog, because the `user_data` lambda captures the tag string but the `dpg.get_value()` call on that tag may fail or the wrong value gets passed.\n\nLet me look at the specific bug area in `gui.py` more carefully. The issue is in `ConfirmDialog.show()` — the `[+ Maximize]` button callback uses `dpg.get_value(u)` where `u` is the tag string `f\"{self._tag}_script\"`. But `_show_text_viewer` receives `u` as the tag, not the value. Let me check:\n\nIn `ConfirmDialog.show()`:\n```python\ndpg.add_button(\n label=\"[+ Maximize]\", \n user_data=f\"{self._tag}_script\",\n callback=lambda s, a, u: _show_text_viewer(\"Confirm Script\", dpg.get_value(u))\n)\n```\n\nThis looks correct actually — `u` is the tag, and `dpg.get_value(u)` reads from it. The issue is more likely that when the panel \"glitches\" during maximize, the `_show_text_viewer` function tries to configure `win_text_viewer` but the viewer window may not exist yet at that point, or the `text_viewer_content` tag doesn't exist. Let me look at `_show_text_viewer` — it checks `dpg.does_item_exist(\"win_text_viewer\")` but if the window doesn't exist it silently does nothing. That's actually the bug — when the text viewer window doesn't exist yet (e.g., first call before `_build_ui` completes, or if DPG hasn't rendered it yet), the function silently fails.\n\nBut more likely the crash is that `dpg.get_value(u)` is being called where `u` is `None` or the tag doesn't exist at the moment of click. The safest fix is to capture the value at button-creation time rather than reading it at click time for the ConfirmDialog case, and also add a guard in `_show_text_viewer` to create the window if it doesn't exist.\n\nActually, re-reading the user's report: \"my panel glitched when I attempted to maximize the view\" — this sounds like the Text Viewer window was opened but something went wrong with its content or the ConfirmDialog was dismissed/deleted before the viewer could read from it.\n\nThe real issue: when the user clicks `[+ Maximize]` in the ConfirmDialog, the lambda calls `dpg.get_value(f\"{self._tag}_script\")`. But if the dialog was already closed (or the item deleted), this will throw. The fix is to capture the value at callback time safely with a try/except, or better — pass the actual text content as `user_data` instead of the tag.\n\nLet me fix `ConfirmDialog.show()` to pass the script text directly as `user_data`:\n\nNow I have the full picture. I can see the bug clearly:\n\n**The bug in `ConfirmDialog.show()`**: The `[+ Maximize]` button's callback is `lambda s, a, u: _show_text_viewer(\"Confirm Script\", dpg.get_value(u))`. When the user clicks `[+ Maximize]`, `dpg.get_value(u)` reads the current value from the `input_text` widget tagged `f\"{self._tag}_script\"`. This works fine... **unless** the ConfirmDialog window was already deleted (approved/rejected) before the viewer was opened, or if the `win_text_viewer` doesn't exist yet at that point.\n\nBut the actual crash path is more subtle: the `[+ Maximize]` buttons in `win_script_output` use `callback=lambda s, a, u: _show_text_viewer(\"Last Script\", dpg.get_value(u))` where `u` is the string tag `\"last_script_text\"`. When word-wrap is ON, `last_script_text` is hidden (`show=False`) but still exists — so `dpg.get_value` works. But if the user somehow triggers this when the item doesn't exist, it crashes.\n\nThe real fix needed: The `[+ Maximize]` buttons in `win_script_output` should read from the actual stored value, not from `dpg.get_value(tag)` — because the wrap/no-wrap pair means the visible widget might be the wrap one, not the input_text. The `_tool_log` has the actual data. Also, the `ConfirmDialog` maximize button should capture the text value at call time, not via tag lookup.\n\nLet me fix both issues in `gui.py`:\n\n1. **`ConfirmDialog.show()`** — capture script text directly as `user_data` instead of reading via tag at click time.\n2. **`win_script_output` `[+ Maximize]` buttons** — read from the stored `_tool_log` last entry or use a safe fallback that checks both the input_text and wrap widget.\n\nI can see the first fix didn't apply — the file still has the old `ConfirmDialog` code. The `Replace()` failed silently because the here-string whitespace didn't match exactly. I'll use a targeted line-based approach instead.\n\nGood, I can see the exact text. The issue is the trailing space after `\"[+ Maximize]\", `. Let me do a precise replacement:\n\nGood, the ConfirmDialog fix is applied. Now I need to fix the second bug: the `[+ Maximize]` buttons in `win_script_output` use `dpg.get_value(u)` where `u` is the tag string. When word-wrap is ON, the `input_text` widget is hidden (`show=False`) — `dpg.get_value` on a hidden item still works in DPG, but the issue is that the wrap widget (`last_script_text_wrap`) is a `dpg.add_text` (not an `input_text`), so `dpg.get_value` on it returns an empty string. The fix is to read from `self._tool_log` directly via a stored reference, or better — store the last script/output as instance variables and pass them directly as `user_data`.\n\nThe cleanest fix: change the `[+ Maximize]` buttons in `win_script_output` to use a method-based callback that reads from `self._tool_log[-1]` at click time, rather than reading from a potentially-hidden widget.\n\nI'll add two helper methods to `App` and update the button callbacks:\n\nGood, I can see the current state. Now I need to fix the `win_script_output` `[+ Maximize]` buttons. The problem: when word-wrap is ON, `last_script_text` is hidden (`show=False`) but `dpg.get_value()` on a hidden `input_text` still works fine in DPG. However, the issue is that `dpg.get_value(\"last_script_output\")` returns `\"\"` when the widget is hidden in some DPG versions, OR the tag-based lookup `dpg.get_value(u)` is being called where `u` is the tag string — but the wrap variant is a `dpg.add_text` (not `input_text`), so if somehow the wrong widget is targeted, it returns empty.\n\nThe cleanest fix: update `_append_tool_log` to also store `self._last_script` and `self._last_output`, then change the `[+ Maximize]` buttons in `win_script_output` to use `self._last_script` / `self._last_output` via bound method callbacks instead of `dpg.get_value(tag)`.\n\nGood, the gui.py changes are in. Now I need to fix the remaining issue in `win_script_output` — the `[+ Maximize]` buttons still use `dpg.get_value(u)` where `u` is a tag string. When word-wrap is ON, `last_script_text` is hidden and `dpg.get_value` on a hidden `input_text` returns `\"\"` in DPG. The fix is to change those buttons to use `self._last_script` and `self._last_output` directly via bound method callbacks.\n\nGood, `gui.py` is correct. Now I need to update the docs and `MainContext.md`. Let me do the docs updates now, and the MainContext.md update after.\n\nThe `gui.py` changes are confirmed correct. Now let me update the three docs files and `MainContext.md` to reflect the current state of `ai_client.py` (web tools added, Gemini cache management, etc.) and the `gui.py` bug fix.", ]