From c4a3034093c83838947bdbef9b6f66ec7b533bad Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sat, 21 Feb 2026 17:24:21 -0500 Subject: [PATCH] progresss --- config.toml | 2 +- dpg_layout.ini | 210 +++++++++++++++++-------------------------------- gui.py | 37 ++++++++- 3 files changed, 107 insertions(+), 142 deletions(-) diff --git a/config.toml b/config.toml index bcf02f5..91ae13e 100644 --- a/config.toml +++ b/config.toml @@ -23,7 +23,7 @@ paths = [] [discussion] history = [ - "User:\nAdd support for properly handling files that we have in config with anthropics api (your context will have documentation reguarding it). This will allow us to free up the main markdown file were sending as a message.\nWe also want to make sure the messaging of that giant markdown is chunked as anthropic does have an upper limit per messages.\nAI:\nGood. Now the big rewrite of `ai_client.py`. The strategy:\n\n- Add a new `_send_anthropic_files` path that uses `file_cache.get_file_id()` to upload files individually as `document`/`image` content blocks, keeping the context message lean\n- The fallback (and also for oversized content) uses chunked text blocks — split the markdown into ≤180k-char chunks (well under the ~200k token limit with headroom for overhead), each sent as a separate `text` content block with `cache_control` on the last one\n- `send()` now accepts an optional `file_items` parameter from aggregate\n- `reset_session()` also resets the file_cache client\nUser:\ncontinue. Also got this error when trying to run latest version of this program. However I can use an old version for now.\nAi:\nNow fix `gui.py` — patch the three 2-tuple unpack sites and thread `file_items` through to `send()`:\n[User]\ncontinue. My bad the error in comms was shown int he screenshot I linked. in the md context. Make sure to update MainContext.md when done.\nAI:\nfinished without sending a response...\nUser:\nSeems to be working...! \nMake a richer discussioon history editor, with structual support for the user/ai message nodes and buttons in the reponse and message panels for adding their entries to it on click.\nAI:\nThe existing format already uses `[User]\\n...` and `[AI]\\n...` prefixes. The new structured editor will parse those naturally and write them back in the same format. Now let me implement the full changes:\nUser:\nYou had failres in your last few called scripts. Git diff shows now changes to python files.\nI'll add the comms and tool logs to your context. \nWe should remove the script content from the tool log and just save the script name so that it doesn't bloat it. \nSame with omitting full message sent in the comms log, very expensive to send to you or read manually.\nVendor API:\nERROR: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'A maximum of 4 blocks with cache_control may be provided. Found 5.'}, 'request_id': 'req_011CYMxgMXvcZUVFNyFz1Lx8'}\nUser:\nI'm not able to send a message for a while now...\n(Message finally sent)\nAI:\nCompleted without a response message showing up.\nUser:\nRestarts custom prompting program.\nUser:\nOk lets try this again...\nLets do the discussion history improvmeents. I want a sort of visual editor where each entry is its own block. \nThere should be a role field and a content filed and I should have buttons for appending the current response or current message to it\n. I should be able to insert or remove anywhere as well.\nVendor API:\nERROR: Error code: 500 - {'type': 'error', 'error': {'type': 'api_error', 'message': 'Internal server error'}, 'request_id': 'req_011CYMyjgyfDn2b6JnPD6rvJ'}\nUser:\ncontinue...\nVendor API:\nERROR: Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'File not found: file_011CYMyjXYsf951nBgTvQmkE'}, 'request_id': 'req_011CYMysoSaH2xPxVtZurjSc'}\nUser:\nreverting to older editor...\nOk I'm back on an older prompting editor. Lets get this working again... with latest..\nAI:\nGood. Now I'll rewrite the Discussion History panel in `gui.py`. The changes are:\n\n1. Add `_parse_history_entries()` — converts the raw TOML string array into `[{role, content}]` dicts\n2. Add `self.disc_entries` list of dicts to `App.__init__`\n3. Replace `_build_ui`'s Discussion window with a structured block editor inside a scrollable child window\n4. Add `_rebuild_disc_list()` — full redraw of the structured editor\n5. Add `_make_disc_*` callbacks for insert/remove/role-change/content-change\n6. Add `cb_append_message_to_history()` and `cb_append_response_to_history()`\n7. Add **→ History** buttons to Message and Response panels\n8. Update `_flush_to_config()` to serialise `disc_entries` back to the string array format\n9. Remove the old `cb_add_excerpt` / `cb_clear_discussion` / `cb_save_discussion` callbacks (replaced)\nUser:\nsounds good, continue!\nVendor API:\nERROR: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages.10: `tool_use` ids were found without `tool_result` blocks immediately after: toolu_01BjaPJPVFoNnNoRCLvPA8qF. Each `tool_use` block must have a corresponding `tool_result` block in the next message.'}, 'request_id': 'req_011CYMzHG47TKTPp7iLcE5NP'}\nUser:\nreverting to an even older version..", + "User:\nAdd support for properly handling files that we have in config with anthropics api (your context will have documentation reguarding it). This will allow us to free up the main markdown file were sending as a message.\nWe also want to make sure the messaging of that giant markdown is chunked as anthropic does have an upper limit per messages.\nAI:\nGood. Now the big rewrite of `ai_client.py`. The strategy:\n\n- Add a new `_send_anthropic_files` path that uses `file_cache.get_file_id()` to upload files individually as `document`/`image` content blocks, keeping the context message lean\n- The fallback (and also for oversized content) uses chunked text blocks — split the markdown into ≤180k-char chunks (well under the ~200k token limit with headroom for overhead), each sent as a separate `text` content block with `cache_control` on the last one\n- `send()` now accepts an optional `file_items` parameter from aggregate\n- `reset_session()` also resets the file_cache client\nUser:\ncontinue. Also got this error when trying to run latest version of this program. However I can use an old version for now.\nAi:\nNow fix `gui.py` — patch the three 2-tuple unpack sites and thread `file_items` through to `send()`:\n[User]\ncontinue. My bad the error in comms was shown int he screenshot I linked. in the md context. Make sure to update MainContext.md when done.\nAI:\nfinished without sending a response...\nUser:\nSeems to be working...! \nMake a richer discussioon history editor, with structual support for the user/ai message nodes and buttons in the reponse and message panels for adding their entries to it on click.\nAI:\nThe existing format already uses `[User]\\n...` and `[AI]\\n...` prefixes. The new structured editor will parse those naturally and write them back in the same format. Now let me implement the full changes:\nUser:\nYou had failres in your last few called scripts. Git diff shows now changes to python files.\nI'll add the comms and tool logs to your context. \nWe should remove the script content from the tool log and just save the script name so that it doesn't bloat it. \nSame with omitting full message sent in the comms log, very expensive to send to you or read manually.\nVendor API:\nERROR: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'A maximum of 4 blocks with cache_control may be provided. Found 5.'}, 'request_id': 'req_011CYMxgMXvcZUVFNyFz1Lx8'}\nUser:\nI'm not able to send a message for a while now...\n(Message finally sent)\nAI:\nCompleted without a response message showing up.\nUser:\nRestarts custom prompting program.\nUser:\nOk lets try this again...\nLets do the discussion history improvmeents. I want a sort of visual editor where each entry is its own block. \nThere should be a role field and a content filed and I should have buttons for appending the current response or current message to it\n. I should be able to insert or remove anywhere as well.\nVendor API:\nERROR: Error code: 500 - {'type': 'error', 'error': {'type': 'api_error', 'message': 'Internal server error'}, 'request_id': 'req_011CYMyjgyfDn2b6JnPD6rvJ'}\nUser:\ncontinue...\nVendor API:\nERROR: Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'File not found: file_011CYMyjXYsf951nBgTvQmkE'}, 'request_id': 'req_011CYMysoSaH2xPxVtZurjSc'}\nUser:\nreverting to older editor...\nOk I'm back on an older prompting editor. Lets get this working again... with latest..\nAI:\nGood. Now I'll rewrite the Discussion History panel in `gui.py`. The changes are:\n\n1. Add `_parse_history_entries()` — converts the raw TOML string array into `[{role, content}]` dicts\n2. Add `self.disc_entries` list of dicts to `App.__init__`\n3. Replace `_build_ui`'s Discussion window with a structured block editor inside a scrollable child window\n4. Add `_rebuild_disc_list()` — full redraw of the structured editor\n5. Add `_make_disc_*` callbacks for insert/remove/role-change/content-change\n6. Add `cb_append_message_to_history()` and `cb_append_response_to_history()`\n7. Add **→ History** buttons to Message and Response panels\n8. Update `_flush_to_config()` to serialise `disc_entries` back to the string array format\n9. Remove the old `cb_add_excerpt` / `cb_clear_discussion` / `cb_save_discussion` callbacks (replaced)\nUser:\nsounds good, continue!\nVendor API:\nERROR: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages.10: `tool_use` ids were found without `tool_result` blocks immediately after: toolu_01BjaPJPVFoNnNoRCLvPA8qF. Each `tool_use` block must have a corresponding `tool_result` block in the next message.'}, 'request_id': 'req_011CYMzHG47TKTPp7iLcE5NP'}\nUser:\nreverting to an even older version..\nUser:\nOk lets see if we can get it to work with this version and get everything fixed on latest...\nAI:\nThe cache_control logic looks correct already (system=1, tools=1, context_last=1 = 3 total, under the limit of 4). The error seen previously was likely from an older version. Good.\n\nNow let me fix the **comms log** (omit full message from OUT/request) and **tool log** (omit script body from `session_logger`):\nAI:\nNo response\nUser:\nrestarting...", ] [ai] diff --git a/dpg_layout.ini b/dpg_layout.ini index d00d413..c1227c5 100644 --- a/dpg_layout.ini +++ b/dpg_layout.ini @@ -16,9 +16,9 @@ DockId=0x00000005,0 [Window][###30] Pos=0,654 -Size=549,742 +Size=549,1342 Collapsed=0 -DockId=0x00000025,0 +DockId=0x00000027,0 [Window][###66] Pos=0,1491 @@ -42,7 +42,7 @@ DockId=0x0000000D,0 Pos=378,494 Size=829,1643 Collapsed=0 -DockId=0x0000001F,0 +DockId=0x00000025,0 [Window][###103] Pos=1613,1330 @@ -103,17 +103,17 @@ DockId=0x00000014,0 Pos=2531,0 Size=1309,1690 Collapsed=0 -DockId=0x0000001F,0 +DockId=0x00000025,0 [Window][###106] Pos=551,0 -Size=1275,2137 +Size=972,2137 Collapsed=0 -DockId=0x00000012,2 +DockId=0x00000012,0 [Window][###100] -Pos=2821,0 -Size=1019,1412 +Pos=2622,0 +Size=1218,1412 Collapsed=0 DockId=0x00000024,0 @@ -146,7 +146,7 @@ Collapsed=0 Pos=551,0 Size=1060,2137 Collapsed=0 -DockId=0x0000001F,0 +DockId=0x00000025,0 [Window][###78] Pos=0,1422 @@ -164,7 +164,7 @@ DockId=0x00000015,0 Pos=551,0 Size=1060,2137 Collapsed=0 -DockId=0x0000001F,1 +DockId=0x00000025,1 [Window][###110] Pos=2438,0 @@ -174,9 +174,9 @@ DockId=0x00000016,0 [Window][###112] Pos=551,0 -Size=1275,2137 +Size=972,2137 Collapsed=0 -DockId=0x00000012,1 +DockId=0x00000012,2 [Window][###145] Pos=1578,868 @@ -210,7 +210,7 @@ Collapsed=0 [Window][###115] Pos=551,0 -Size=1275,2137 +Size=847,2137 Collapsed=0 DockId=0x00000012,0 @@ -221,26 +221,26 @@ Collapsed=0 DockId=0x00000022,0 [Window][###85] -Pos=1828,0 -Size=991,1412 +Pos=1400,0 +Size=1220,1412 Collapsed=0 -DockId=0x0000001F,0 +DockId=0x00000025,0 [Window][###92] Pos=551,0 -Size=1275,2137 +Size=847,2137 Collapsed=0 DockId=0x00000012,2 [Window][###107] -Pos=1828,1414 -Size=2012,723 +Pos=1400,1414 +Size=2440,723 Collapsed=0 DockId=0x0000001A,0 [Window][###109] Pos=551,0 -Size=1275,2137 +Size=847,2137 Collapsed=0 DockId=0x00000012,1 @@ -284,125 +284,35 @@ Pos=1578,868 Size=700,440 Collapsed=0 -[Window][###596] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###691] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###803] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###935] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###1073] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###1217] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###72] -Pos=0,1398 -Size=549,739 +[Window][###104] +Pos=1525,1246 +Size=2315,607 Collapsed=0 DockId=0x00000026,0 -[Window][###82] -Pos=1828,0 -Size=2012,1162 -Collapsed=0 -DockId=0x0000001F,0 - -[Window][###89] -Pos=551,0 -Size=1275,2137 -Collapsed=0 -DockId=0x00000012,0 - -[Window][###97] -Pos=1828,1649 -Size=2012,488 +[Window][###72] +Pos=0,1998 +Size=549,139 Collapsed=0 DockId=0x00000028,0 -[Window][###104] -Pos=1828,1164 -Size=2012,483 +[Window][###82] +Pos=1525,0 +Size=2315,1244 Collapsed=0 -DockId=0x00000027,0 +DockId=0x00000025,0 -[Window][###219] -Pos=1578,868 -Size=700,440 +[Window][###89] +Pos=551,0 +Size=972,2137 Collapsed=0 +DockId=0x00000012,1 -[Window][###313] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###402] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###508] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###634] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###763] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###912] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###1031] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###1167] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###1323] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###1482] -Pos=1578,868 -Size=700,440 -Collapsed=0 - -[Window][###1650] -Pos=1578,868 -Size=700,440 +[Window][###97] +Pos=1525,1855 +Size=2315,282 Collapsed=0 +DockId=0x00000020,0 [Window][###139] Pos=1578,868 @@ -419,7 +329,7 @@ Pos=1578,868 Size=700,440 Collapsed=0 -[Window][###457] +[Window][###460] Pos=1578,868 Size=700,440 Collapsed=0 @@ -429,7 +339,27 @@ Pos=1578,868 Size=700,440 Collapsed=0 -[Window][###460] +[Window][###752] +Pos=1578,868 +Size=700,440 +Collapsed=0 + +[Window][###846] +Pos=1578,868 +Size=700,440 +Collapsed=0 + +[Window][###981] +Pos=1578,868 +Size=700,440 +Collapsed=0 + +[Window][###1125] +Pos=1578,868 +Size=700,440 +Collapsed=0 + +[Window][###1272] Pos=1578,868 Size=700,440 Collapsed=0 @@ -442,8 +372,8 @@ DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,0 Size=3840, DockNode ID=0x00000009 Parent=0x00000006 SizeRef=235,453 Split=Y Selected=0x5F94F9BD DockNode ID=0x0000001D Parent=0x00000009 SizeRef=364,766 Split=Y Selected=0x5F94F9BD DockNode ID=0x00000021 Parent=0x0000001D SizeRef=549,696 Split=Y Selected=0x5F94F9BD - DockNode ID=0x00000025 Parent=0x00000021 SizeRef=549,742 Selected=0x5F94F9BD - DockNode ID=0x00000026 Parent=0x00000021 SizeRef=549,739 Selected=0xBEC5E8CB + DockNode ID=0x00000027 Parent=0x00000021 SizeRef=549,1342 Selected=0x5F94F9BD + DockNode ID=0x00000028 Parent=0x00000021 SizeRef=549,139 Selected=0xBEC5E8CB DockNode ID=0x00000022 Parent=0x0000001D SizeRef=549,785 Selected=0x0CE534DB DockNode ID=0x0000001E Parent=0x00000009 SizeRef=364,715 Selected=0xF475F06A DockNode ID=0x0000000A Parent=0x00000006 SizeRef=235,350 Selected=0x80199DAE @@ -451,20 +381,20 @@ DockSpace ID=0x7C6B3D9B Window=0xA87D555D Pos=0,0 Size=3840, DockNode ID=0x00000001 Parent=0x00000004 SizeRef=1060,1161 Split=Y Selected=0x40484D8F DockNode ID=0x00000007 Parent=0x00000001 SizeRef=595,492 Selected=0xBA13FCDE DockNode ID=0x00000008 Parent=0x00000001 SizeRef=595,1643 Split=X Selected=0x40484D8F - DockNode ID=0x0000000F Parent=0x00000008 SizeRef=1275,2137 Split=Y Selected=0x07E8375F + DockNode ID=0x0000000F Parent=0x00000008 SizeRef=972,2137 Split=Y Selected=0x07E8375F DockNode ID=0x00000011 Parent=0x0000000F SizeRef=835,425 Selected=0x72F373AE DockNode ID=0x00000012 Parent=0x0000000F SizeRef=835,1710 Selected=0x3934423A - DockNode ID=0x00000010 Parent=0x00000008 SizeRef=2012,2137 Split=Y Selected=0xCE7F911A + DockNode ID=0x00000010 Parent=0x00000008 SizeRef=2315,2137 Split=Y Selected=0xCE7F911A DockNode ID=0x00000013 Parent=0x00000010 SizeRef=1967,1690 Split=X Selected=0xCE7F911A DockNode ID=0x00000017 Parent=0x00000013 SizeRef=1314,1749 Selected=0x4B454E0B DockNode ID=0x00000018 Parent=0x00000013 SizeRef=1309,1749 Split=Y Selected=0x88A8C2FF DockNode ID=0x00000019 Parent=0x00000018 SizeRef=2440,1412 Split=X Selected=0x88A8C2FF - DockNode ID=0x00000023 Parent=0x00000019 SizeRef=991,737 Split=Y Selected=0x7D28643F - DockNode ID=0x0000001F Parent=0x00000023 SizeRef=2440,1162 CentralNode=1 Selected=0x4F935A1E - DockNode ID=0x00000020 Parent=0x00000023 SizeRef=2440,973 Split=Y Selected=0x4C2F06CB - DockNode ID=0x00000027 Parent=0x00000020 SizeRef=1743,483 Selected=0x7D28643F - DockNode ID=0x00000028 Parent=0x00000020 SizeRef=1743,488 Selected=0x4C2F06CB - DockNode ID=0x00000024 Parent=0x00000019 SizeRef=1019,737 Selected=0x88A8C2FF + DockNode ID=0x00000023 Parent=0x00000019 SizeRef=1220,737 Split=Y Selected=0x4F935A1E + DockNode ID=0x0000001F Parent=0x00000023 SizeRef=2315,1853 Split=Y Selected=0x4F935A1E + DockNode ID=0x00000025 Parent=0x0000001F SizeRef=2315,1244 CentralNode=1 Selected=0x4F935A1E + DockNode ID=0x00000026 Parent=0x0000001F SizeRef=2315,607 Selected=0x7D28643F + DockNode ID=0x00000020 Parent=0x00000023 SizeRef=2315,282 Selected=0x4C2F06CB + DockNode ID=0x00000024 Parent=0x00000019 SizeRef=1218,737 Selected=0x88A8C2FF DockNode ID=0x0000001A Parent=0x00000018 SizeRef=2440,723 Selected=0x3A881EEF DockNode ID=0x00000014 Parent=0x00000010 SizeRef=1967,445 Selected=0xC36FF36B DockNode ID=0x00000002 Parent=0x00000004 SizeRef=2227,1161 Split=X Selected=0x714F2F7B diff --git a/gui.py b/gui.py index 228ebb5..acbd289 100644 --- a/gui.py +++ b/gui.py @@ -1,4 +1,4 @@ -# gui.py +# gui.py import dearpygui.dearpygui as dpg import tomllib import tomli_w @@ -283,6 +283,41 @@ class ConfirmDialog: return self._approved, self._script +DISC_ROLES = ["User", "AI", "Vendor API", "System"] + + +def _parse_history_entries(history: list[str]) -> list[dict]: + """ + Convert the raw TOML string array into a flat list of {role, content} dicts. + Each TOML string is one excerpt (may contain multiple role blocks separated + by lines like "Role:" or "[Role]"). We detect the common patterns: + "User:\n..." "AI:\n..." "[User]\n..." "[AI]\n..." + and split accordingly. Unrecognised text becomes a User entry. + """ + import re + entries: list[dict] = [] + role_pattern = re.compile( + r'^(?:\[)?(' + '|'.join(re.escape(r) for r in DISC_ROLES) + r')(?:\])?:?\s*$', + re.IGNORECASE | re.MULTILINE, + ) + for excerpt in history: + # Find all role header positions + splits = [(m.start(), m.end(), m.group(1).capitalize()) for m in role_pattern.finditer(excerpt)] + if not splits: + # No role headers found - treat whole excerpt as User content + text = excerpt.strip() + if text: + entries.append({"role": "User", "content": text}) + continue + # Extract content between headers + for idx, (start, end, role) in enumerate(splits): + next_start = splits[idx + 1][0] if idx + 1 < len(splits) else len(excerpt) + content = excerpt[end:next_start].strip() + # Normalise role capitalisation to match DISC_ROLES + matched = next((r for r in DISC_ROLES if r.lower() == role.lower()), role) + entries.append({"role": matched, "content": content}) + return entries + class App: def __init__(self): self.config = load_config()