Skip to content

Commit f1b4eca

Browse files
committed
fix(agent): stop writing the tool schemas into the conversation
tool_handling() appended tools_list_dictionary to short_memory under role=self.agent_name. The same schemas already reach the provider through the API's tools parameter (LLMManager.build passes tools_list_dictionary to LiteLLM), so every request carried them twice, attributed to an assistant turn the assistant never produced, and stored as a list where every other entry is a string. Closes kyegomez#1989
1 parent 8db8662 commit f1b4eca

2 files changed

Lines changed: 29 additions & 9 deletions

File tree

swarms/structs/agent.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,6 @@ def tool_handling(self):
897897
2. Initializes tools_list_dictionary if None
898898
3. Tracks existing tool names to prevent duplicates
899899
4. Adds new tools that don't already exist
900-
5. Adds tools to conversation memory for LLM context
901900
902901
**Tool Schema Format:**
903902
Tools are converted to OpenAI function calling format:
@@ -923,16 +922,16 @@ def tool_handling(self):
923922
None: Uses self.tools and self.tools_list_dictionary from instance.
924923
925924
Returns:
926-
None: Modifies self.tools_list_dictionary and self.short_memory.
925+
None: Modifies self.tools_list_dictionary.
927926
928927
Note:
929928
- This method is called automatically during agent initialization if tools are provided
930-
- Tools are added to conversation memory so the LLM knows what tools are available
929+
- Schemas reach the model through the API's `tools` parameter, not the conversation
931930
- The method preserves existing tools in tools_list_dictionary (e.g., handoff tools)
932931
- Tool names are case-sensitive for duplicate detection
933932
934933
Raises:
935-
Exception: If tool conversion fails or tools cannot be added to memory.
934+
Exception: If tool conversion fails.
936935
937936
Examples:
938937
>>> def my_tool(query: str) -> str:
@@ -967,11 +966,6 @@ def tool_handling(self):
967966
self.tools_list_dictionary.append(tool)
968967
existing_tool_names.add(tool_name)
969968

970-
self.short_memory.add(
971-
role=self.agent_name,
972-
content=self.tools_list_dictionary,
973-
)
974-
975969
def short_memory_init(self):
976970
# Compactly assemble initial prompt as a string with available fields
977971
prompt = self.system_prompt

tests/structs/test_agent.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,32 @@ def test_default_is_per_instance(self):
862862
)
863863

864864

865+
class TestToolSchemasStayOutOfTheConversation:
866+
"""Schemas reach the model as the API's `tools` parameter, not as a turn."""
867+
868+
def test_no_conversation_turn_carries_the_tool_schemas(self):
869+
# dynamic_tools=False is the branch that reaches tool_handling().
870+
agent = _patched_agent(
871+
"SchemaAgent",
872+
model_name="gpt-5.4",
873+
dynamic_tools=False,
874+
tools=[_math_tool],
875+
)
876+
877+
assert any(
878+
schema["function"]["name"] == "_math_tool"
879+
for schema in agent.tools_list_dictionary
880+
)
881+
assert [
882+
m
883+
for m in agent.short_memory.conversation_history
884+
if not isinstance(m["content"], str)
885+
] == []
886+
assert [
887+
m["role"] for m in agent.short_memory.conversation_history
888+
] == ["System"]
889+
890+
865891
class TestAutonomousAgentLoop:
866892
"""The ``max_loops="auto"`` loop lives in ``AutonomousAgentLoop``, not on
867893
``Agent``. These pin the seam: the loop is wired up, it reads and writes

0 commit comments

Comments
 (0)