Skip to content

fix #259: pass prior tool outputs to actions by $ref instead of inlining#267

Open
ahmad-ajmal wants to merge 2 commits into
V1.3.2from
fix/run-python-truncation
Open

fix #259: pass prior tool outputs to actions by $ref instead of inlining#267
ahmad-ajmal wants to merge 2 commits into
V1.3.2from
fix/run-python-truncation

Conversation

@ahmad-ajmal
Copy link
Copy Markdown
Collaborator

What

  • Add ActionOutputStore — every action invocation persists to agent_file_system/action_outputs/{session_id}/{action_name}__{run_id}.json at a stable {action_name}#{short_run_id} key.
  • Add $ref resolution in action parameters — LLM can pass {"$ref": "<key>", "path": "<dotted.path>"} instead of inlining prior data. Resolved by the manager before the handler runs.
  • Prompt size now bounded regardless of tool output size:
    • Event-stream entries above 2KB collapse to a structural skeleton (types, key names, list lengths — no list-item content) plus the archive key. A 30KB Discord-fetch result renders as ~300 chars in the stream, and renders the same way on every subsequent prompt instead of re-shipping the full payload each turn.
    • LLM responses themselves shrink — an $ref is ~80 chars where the inlined data was kilobytes. That smaller response is what enters the next prompt's event-stream history, so the saving compounds across turns.
  • Each action_start / action_end event stamps the exact $ref key in plain sight (e.g. Action get_discord_messages#c0b016 completed...) so the LLM never has to guess.
  • run_python exposes sibling parameters as Python globals — code references already-resolved data by name.
  • Side fixes uncovered along the way: parse subprocess JSON for sandboxed actions (was double-wrapped); fix stale externalize skip list to include read_file/grep_files/stream_read/stream_edit; remove "plan" from HIDDEN_EVENT_KINDS where it substring-matched "platform" and silently dropped every agent chat bubble.

Why

The LLM had no way to reference prior tool output — it could only quote it. When asked to process ~50 Discord messages it pasted the lot into run_python's code parameter as a triple-quoted string, blew past the model's output-token cap, and the response truncated mid-string. JSON parsing failed, the retry told it to "fix the JSON," and it reproduced the same failure three times until the task aborted.

Closes #259

How to test

  1. From a fresh session, ask the agent to retrieve ~50+ Discord messages and present them.
  2. Watch logs/<timestamp>.log for:
    • action_end events that include the (Reference this output via {"$ref": ..., ...}) suffix.
    • run_python INPUT DATA showing a $ref value (resolved before exec).
    • No Unterminated string / truncated: retries.
  3. Verify the formatted messages reach the chat panel in the browser.
  4. Inspect agent_file_system/action_outputs/<session_id>/ — one JSON file per action, each containing the full output dict.

Logs

Before:

2026-05-18 06:05:30.368 | WARNING  | agent_core.core.impl.action.router:_prompt_for_decision:678 - Failed to parse LLM decision on attempt 2: {
  "reasoning": "The 'Execute: Search for the message in the specified Discord channel.' todo is currently in progress. I have retrieved the messages from the Discord channel. Now I need to search through these messages to find the one that matches the content provided by the user. I will use a Python script to perform this search. After finding the message, I will update the todos to reflect the completion of this step and move to the verification phase.",
  "actions": [
    {
      "action_name": "run_python",
      "parameters": {
        "code": "import json\n\nuser_message_content = \"My apologies, everyone. I would like to request shifting the weekly meeting to 3:30 PM if possible. The CraftBot live call meeting just finished, and I need some time to settle a few things and take care of a few things.\\n\\nSorry for the short notice. If everyone is available at 3:30 PM, please shift the meeting to 2PM to 3:30 PM. If that is somehow not possible, it okay; please continue with the weekly meeting as planned, and I will connect with the team later and catch up on the updates.\\n\\nAppreciate your support & understanding.\"\n\ndiscord_messages_json = \"\"\"[\n    {\n        \"id\": \"1505794742590378066\",\n        \"content\": \"Perfect see you then\",\n        \"author\": {\"id\": \"731229477673238578\", \"username\": \"alanayalag\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T04:50:42.947000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505794706456711359\",\n        \"content\": \"Sure let's do that\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T04:50:34.332000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505794435089174629\",\n        \"content\": \"What if at 3 we us meet first and then 3:30 we join the team\",\n        \"author\": {\"id\": \"731229477673238578\", \"username\": \"alanayalag\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T04:49:29.633000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505794300317929573\",\n        \"content\": \"3:30 works fine for me\",\n        \"author\": {\"id\": \"731229477673238578\", \"username\": \"alanayalag\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T04:48:57.501000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505794172941107392\",\n        \"content\": \"or can you do on 330 instead?\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T04:48:27.132000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505793917348745290\",\n        \"content\": \"<@731229477673238578> we can still meet at 2PM\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T04:47:26.194000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505792053936918670\",\n        \"content\": \"@everyone \\nMy apologies, everyone. I would like to request shifting the weekly meeting to 3:30 PM if possible. The CraftBot live call meeting just finished, and I need some time to settle a few things and take care of a few things.\\n\\nSorry for the short notice. If everyone is available at 3:30 PM, please shift the meeting to 2PM to 3:30 PM. If that is somehow not possible, it okay; please continue with the weekly meeting as planned, and I will connect with the team later and catch up on the updates.\\n\\nAppreciate your support & understanding.\",\n        \"author\": {\"id\": \"1364652300559450204\", \"username\": \"korivi\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T04:40:01.922000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505759500345278485\",\n        \"content\": \"yea\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T02:30:40.541000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505759427117060156\",\n        \"content\": \"Meeting!?\",\n        \"author\": {\"id\": \"1364652300559450204\", \"username\": \"korivi\", \"bot\": false},\n        \"timestamp\": \"2026-05-18T02:30:23.082000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1505517728272744499\",\n        \"content\": \"@everyone Tomorrow I will meet <@318869429502869504> from 9 to 10am, then, <@1364652300559450204> <@194120883780976640> can we meet around 1130am? Then, <@194120883780976640> <@652504033105543188> <@1364652300559450204> <@393247551790252034> <@318869429502869504> Weekly meeting starting from 2PM.\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-17T10:29:57.587000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504090786168570049\",\n        \"content\": \"Working on surpassing the 2nd place\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T11:59:48.078000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504090746184011827\",\n        \"content\": \"3rd on PH launch…again!!\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T11:59:38.545000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504051645300998184\",\n        \"content\": \"One of the hunters did not get back to us, so we need to try harder.\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T09:24:16.168000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504051483136626709\",\n        \"content\": \"Guys, based on the comments count, I think it is abit risky.\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T09:23:37.505000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504024391720239194\",\n        \"content\": \"<@652504033105543188> Can you share the launch page to Antler channel like how I did it last time?\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T07:35:58.408000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504023236487413830\",\n        \"content\": \"Ahmad and Korivi, can you write a comment in the launch page. Anything as long as not overlapping!\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T07:31:22.979000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504001265275900054\",\n        \"content\": \"@everyone\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T06:04:04.634000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504000356252782654\",\n        \"content\": \"I will join later\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T06:00:27.906000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1504000335012692101\",\n        \"content\": \"Join first\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T06:00:22.842000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503964799799922738\",\n        \"content\": \"4 more hours!\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T03:39:10.587000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503964729947979817\",\n        \"content\": \"@everyone Get ready for the launch: https://www.producthunt.com/products/craftbot?launch=craftbot-with-living-ui\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T03:38:53.933000+00:00\",\n        \"attachments\": [],\n        \"embeds\": [\n            {\n                \"type\": \"article\",\n                \"url\": \"https://www.producthunt.com/products/craftbot?launch=craftbot-with-living-ui\",\n                \"title\": \"CraftBot | Self-hosted proactive AI assistant that lives locally | ...\",\n                \"description\": \"A self-hosted Proactive AI Assistant that lives inside your machine and works 24/7 for your daily execution. It autonomously interprets tasks, plans actions, and executes them to achieve your goals. It learns your objectives, proactively helping you plan and initiate tasks to achieve your life goals. MCPs,Skills, and external App integrations ar...\",\n                \"color\": 16777215,\n                \"provider\": {\"name\": \"Product Hunt\"},\n                \"thumbnail\": {\"url\": \"https://ph-files.imgix.net/e0857c3d-76a5-4b40-8025-5c17a11c0eb2.png?auto=format&fit=crop&frame=1&h=512&w=1024\", \"proxy_url\": \"https://images-ext-1.discordapp.net/external/XwlQr7-mdjWqgIvFuK7L9rHWMtISERAxmpA9stS2O7o/%3Fauto%3Dformat%26fit%3Dcrop%26frame%3D1%26h%3D512%26w%3D1024/https/ph-files.imgix.net/e0857c3d-76a5-4b40-8025-5c17a11c0eb2.png\", \"width\": 1024, \"height\": 512, \"content_type\": \"image/webp\", \"placeholder\": \"6LYFNIQnyIWQd4lSeJtmgGgDaA==\", \"placeholder_version\": 1, \"flags\": 0},\n                \"content_scan_version\": 4\n            }\n        ]\n    },\n    {\n        \"id\": \"1503950417061609593\",\n        \"content\": \"Is okay let me know when you are up\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:42:01.475000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503950066237444137\",\n        \"content\": \"i dont think i can join for the 3:30pm\",\n        \"author\": {\"id\": \"393247551790252034\", \"username\": \"kamisama4312\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:40:37.832000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503943080351633520\",\n        \"content\": \"<@393247551790252034> Can you join? I think there is an overlapping with your schedule ya?\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:12:52.267000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503943012743512105\",\n        \"content\": \"@everyone Weekly meeting today at 3pm JST. PH Launch 4pm\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:12:36.148000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503942882317566023\",\n        \"content\": \"Good I will upload now\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:12:05.052000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503942465621594204\",\n        \"content\": \"I like it, fast tempo video haha\",\n        \"author\": {\"id\": \"652504033105543188\", \"username\": \"koyukopan\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:10:25.704000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503940856770461786\",\n        \"content\": \"Terrible I know but this is what we have now hahahah\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:04:02.124000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503940772989243514\",\n        \"content\": \"<@652504033105543188> ok?\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:03:42.149000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503940736926879814\",\n        \"content\": \"Good?\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:03:33.551000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503940725828620378\",\n        \"content\": \"\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-13T02:03:30.905000+00:00\",\n        \"attachments\": [\n            {\n                \"id\": \"1503940726327607488\",\n                \"filename\": \"Living_UI_demo.mp4\",\n                \"size\": 8184384,\n                \"url\": \"https://cdn.discordapp.com/attachments/1451119242517807156/1503940726327607488/Living_UI_demo.mp4?ex=6a0bc4f3&is=6a0a7373&hm=cc7730150a5deb57360567e68cbbd65d516d91218bf6ee8accd8d0ea744447ca&\",\n                \"proxy_url\": \"https://media.discordapp.net/attachments/1451119242517807156/1503940726327607488/Living_UI_demo.mp4?ex=6a0bc4f3&is=6a0a7373&hm=cc7730150a5deb57360567e68cbbd65d516d91218bf6ee8accd8d0ea744447ca&\",\n                \"width\": 1280,\n                \"height\": 720,\n                \"content_type\": \"video/mp4\",\n                \"original_content_type\": \"video/mp4\",\n                \"content_scan_version\": 4,\n                \"placeholder\": \"yQcOBIBoV2d/hnZ7h4vnkHj25w==\",\n                \"placeholder_version\": 1,\n                \"title\": \"Living UI demo\"\n            }\n        ],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503346697903013888\",\n        \"content\": \"Updated this schedule, refer to it again. By the way, expect delay with the CraftBotLive\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-11T10:43:03.611000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503280161087422495\",\n        \"content\": \"Okay, thanks for letting me know\",\n        \"author\": {\"id\": \"318869429502869504\", \"username\": \"kazusa.\", \"bot\": false},\n        \"timestamp\": \"2026-05-11T06:18:39.998000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503279888319381624\",\n        \"content\": \"<@318869429502869504> By the end of the day I will add you into our Notion page, and I will dm you later\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-11T06:17:34.965000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503279750838358088\",\n        \"content\": \"Guys weekly meeting and onboarding meeting with Tobias is cancelled today. I will move that to Wed. The Antler program is a little too serious to miss. Sorry folks\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-11T06:17:02.187000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503262226424008776\",\n        \"content\": \"Will keep you guys updated\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-11T05:07:24.041000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503262178285981727\",\n        \"content\": \"Btw weekly meeting moved to 330PM JST, it also depends on whether Koyuki and I can get a meeting room hahaha\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-11T05:07:12.564000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1503262028578685060\",\n        \"content\": \"@everyone vote\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-11T05:06:36.871000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1502986225034727525\",\n        \"content\": \"Guys, time to vote:\\nWhat is a better tag line for the PH launch?\\n1. Grow your own software that is alive\\n2. The AI agent that replaces a thousand Saas tools\",\n        \"author\": {\"id\": \"325239015684964365\", \"username\": \"zfoong\", \"bot\": false},\n        \"timestamp\": \"2026-05-10T10:50:40.182000+00:00\",\n        \"attachments\": [],\n        \"embeds\": []\n    },\n    {\n        \"id\": \"1502180159799689256\",\n        \"content\": \"Important upcoming schedule:\\ntoday~15/May: CraftBotLive - CraftBot hosting service like Kimi-Claw. (Korivi, Alan, Ahmad)\\n11/May~14/June: Antler Residency Program. (Foong, Koyuki)\\n11/May: Product Hunt Launch (Foong, Koyuki, Frankie)\\n11/May: Weekly meeting at 3pm (To be confirmed), everyone MUST attend except Shane and Ahmad. If you can't make it, let me know. (Koyuki, Foong, Korivi, Alan, Frankie, Tobias)\\ | error=json error: Unterminated string starting at: line 7 column 17 (char 557); literal_eval error: unterminated string literal (detected at line 7); perhaps you escaped the end quote? (<unknown>, line 7)

After: [PARALLEL] Selected 2 action(s): ['task_update_todos', 'send_message']; the send_message INPUT DATA shows 'message': {'$ref': 'run_python#...', 'path': 'stdout'} and the chat panel receives clean formatted text.

@ahmad-ajmal ahmad-ajmal requested a review from zfoong May 20, 2026 08:25
@ahmad-ajmal ahmad-ajmal self-assigned this May 20, 2026
@ahmad-ajmal ahmad-ajmal added bug Something isn't working priority: high labels May 20, 2026
@ahmad-ajmal
Copy link
Copy Markdown
Collaborator Author

Should update for other actions too. Came across this when using write_file
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant