From 4831ba4d1cedcf5a27f07375eadae878b331ca14 Mon Sep 17 00:00:00 2001 From: Deimos AI Date: Sun, 28 Dec 2025 16:34:58 +0000 Subject: [PATCH 1/2] Fix: Preserve profile when loading subordinate agent settings Follows up on PR #788 (Subordinate agents settings override). When subordinate agents have a settings.json in their profile directory, the profile was getting reset to 'agent0' instead of preserving the intended profile. Root cause: initialize_agent() creates a new config with default profile, and while memory_subdir was preserved, the profile was not. Fix: Apply the same preservation pattern used for memory_subdir to profile. --- .../agent_init/_15_load_profile_settings.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/python/extensions/agent_init/_15_load_profile_settings.py b/python/extensions/agent_init/_15_load_profile_settings.py index d4c9b5ab42..562f404b77 100644 --- a/python/extensions/agent_init/_15_load_profile_settings.py +++ b/python/extensions/agent_init/_15_load_profile_settings.py @@ -4,7 +4,7 @@ class LoadProfileSettings(Extension): - + async def execute(self, **kwargs) -> None: if not self.agent or not self.agent.config.profile: @@ -36,18 +36,18 @@ async def execute(self, **kwargs) -> None: if settings_override: # Preserve the original memory_subdir unless it's explicitly overridden current_memory_subdir = self.agent.config.memory_subdir + # FIX: Also preserve the original profile + original_profile = self.agent.config.profile + new_config = initialize_agent(override_settings=settings_override) + if ( "agent_memory_subdir" not in settings_override and current_memory_subdir != "default" ): new_config.memory_subdir = current_memory_subdir + + # FIX: Restore the original profile + new_config.profile = original_profile + self.agent.config = new_config - # self.agent.context.log.log( - # type="info", - # content=( - # "Loaded custom settings for agent " - # f"{self.agent.number} with profile '{self.agent.config.profile}'." - # ), - # ) - From 5848abea0eb6c15a2ff05e801764822047776e75 Mon Sep 17 00:00:00 2001 From: Deimos AI Date: Wed, 31 Dec 2025 22:58:16 +0000 Subject: [PATCH 2/2] Fix: Auto-correct 'args'/'Args' to 'tool_args' in tool calls Fixes issue where models occasionally use 'args' or 'Args' (capitalized) instead of 'tool_args' in tool call JSON structure due to cognitive interference from API conventions. Changes: - Add auto-correction in json_parse_dirty() to transparently rename 'args' or 'Args' to 'tool_args' when 'tool_args' is missing - Add negative examples to communication prompt showing incorrect plain-text output vs correct JSON format This prevents tool execution failures without breaking existing code. --- prompts/agent.system.main.communication.md | 18 ++++++++++++++++++ python/helpers/extract_tools.py | 9 ++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/prompts/agent.system.main.communication.md b/prompts/agent.system.main.communication.md index 329677b0f1..579d3f70b3 100644 --- a/prompts/agent.system.main.communication.md +++ b/prompts/agent.system.main.communication.md @@ -28,4 +28,22 @@ no text allowed before or after json } ~~~ +### ❌ WRONG - Do NOT output thoughts as plain text +I need to: +1. Read all files +2. Analyze the data +3. Create a report + +### ✅ CORRECT - Always use JSON format +{ + "thoughts": [ + "I need to read all files", + "Then analyze the data", + "Finally create a report" + ], + "headline": "Reading and analyzing files", + "tool_name": "code_execution_tool", + "tool_args": {"code": "..."} +} + {{ include "agent.system.main.communication_additions.md" }} diff --git a/python/helpers/extract_tools.py b/python/helpers/extract_tools.py index 334a42b1b2..68a442eda1 100644 --- a/python/helpers/extract_tools.py +++ b/python/helpers/extract_tools.py @@ -14,7 +14,14 @@ def json_parse_dirty(json:str) -> dict[str,Any] | None: if ext_json: try: data = DirtyJson.parse_string(ext_json) - if isinstance(data,dict): return data + if isinstance(data,dict): + # Auto-correct common error: models sometimes use 'args' or 'Args' instead of 'tool_args' + # Check for both lowercase 'args' and capitalized 'Args' + if 'args' in data and 'tool_args' not in data: + data['tool_args'] = data.pop('args') + elif 'Args' in data and 'tool_args' not in data: + data['tool_args'] = data.pop('Args') + return data except Exception: # If parsing fails, return None instead of crashing return None