Skip to content

Commit 33230a4

Browse files
Make sure to log thoughts if verbosity_level is set to high (huggingface#964)
1 parent be94612 commit 33230a4

File tree

2 files changed

+69
-35
lines changed

2 files changed

+69
-35
lines changed

src/smolagents/agents.py

+15-6
Original file line numberDiff line numberDiff line change
@@ -1054,15 +1054,24 @@ def step(self, memory_step: ActionStep) -> Union[None, Any]:
10541054
stop_sequences=["Observation:"],
10551055
)
10561056
memory_step.model_output_message = model_message
1057-
if model_message.tool_calls is None or len(model_message.tool_calls) == 0:
1058-
raise Exception("Model did not call any tools. Call `final_answer` tool to return a final answer.")
1059-
tool_call = model_message.tool_calls[0]
1060-
tool_name, tool_call_id = tool_call.function.name, tool_call.id
1061-
tool_arguments = tool_call.function.arguments
1062-
10631057
except Exception as e:
10641058
raise AgentGenerationError(f"Error in generating tool call with model:\n{e}", self.logger) from e
10651059

1060+
self.logger.log_markdown(
1061+
content=str(model_message.raw),
1062+
title="Output message of the LLM:",
1063+
level=LogLevel.DEBUG,
1064+
)
1065+
1066+
if model_message.tool_calls is None or len(model_message.tool_calls) == 0:
1067+
raise AgentParsingError(
1068+
"Model did not call any tools. Call `final_answer` tool to return a final answer.", self.logger
1069+
)
1070+
1071+
tool_call = model_message.tool_calls[0]
1072+
tool_name, tool_call_id = tool_call.function.name, tool_call.id
1073+
tool_arguments = tool_call.function.arguments
1074+
10661075
memory_step.tool_calls = [ToolCall(name=tool_name, arguments=tool_arguments, id=tool_call_id)]
10671076

10681077
# Execute

tests/test_agents.py

+54-29
Original file line numberDiff line numberDiff line change
@@ -387,26 +387,6 @@ def test_reset_conversations(self):
387387
assert output == 7.2904
388388
assert len(agent.memory.steps) == 3
389389

390-
def test_code_agent_code_errors_show_offending_line_and_error(self):
391-
agent = CodeAgent(tools=[PythonInterpreterTool()], model=fake_code_model_error)
392-
output = agent.run("What is 2 multiplied by 3.6452?")
393-
assert isinstance(output, AgentText)
394-
assert output == "got an error"
395-
assert "Code execution failed at line 'error_function()'" in str(agent.memory.steps[1].error)
396-
assert "ValueError" in str(agent.memory.steps)
397-
398-
def test_code_agent_code_error_saves_previous_print_outputs(self):
399-
agent = CodeAgent(tools=[PythonInterpreterTool()], model=fake_code_model_error, verbosity_level=10)
400-
agent.run("What is 2 multiplied by 3.6452?")
401-
assert "Flag!" in str(agent.memory.steps[1].observations)
402-
403-
def test_code_agent_syntax_error_show_offending_lines(self):
404-
agent = CodeAgent(tools=[PythonInterpreterTool()], model=fake_code_model_syntax_error)
405-
output = agent.run("What is 2 multiplied by 3.6452?")
406-
assert isinstance(output, AgentText)
407-
assert output == "got an error"
408-
assert ' print("Failing due to unexpected indent")' in str(agent.memory.steps)
409-
410390
def test_setup_agent_with_empty_toolbox(self):
411391
ToolCallingAgent(model=FakeToolCallModel(), tools=[])
412392

@@ -496,15 +476,6 @@ def test_agent_description_gets_correctly_inserted_in_system_prompt(self):
496476
assert "{{managed_agents_descriptions}}" not in managed_agent.system_prompt
497477
assert "You can also give tasks to team members." in manager_agent.system_prompt
498478

499-
def test_code_agent_missing_import_triggers_advice_in_error_log(self):
500-
# Set explicit verbosity level to 1 to override the default verbosity level of -1 set in CI fixture
501-
agent = CodeAgent(tools=[], model=fake_code_model_import, verbosity_level=1)
502-
503-
with agent.logger.console.capture() as capture:
504-
agent.run("Count to 3")
505-
str_output = capture.get()
506-
assert "`additional_authorized_imports`" in str_output.replace("\n", "")
507-
508479
def test_replay_shows_logs(self):
509480
agent = CodeAgent(
510481
tools=[], model=fake_code_model_import, verbosity_level=0, additional_authorized_imports=["numpy"]
@@ -630,6 +601,31 @@ def test_instantiation_with_final_answer_tool(self, tools, expected_final_answer
630601
assert "final_answer" in agent.tools
631602
assert isinstance(agent.tools["final_answer"], expected_final_answer_tool)
632603

604+
def test_logs_display_thoughts_even_if_error(self):
605+
def fake_json_model_no_call(messages, stop_sequences=None, tools_to_call_from=None):
606+
return ChatMessage(
607+
role="assistant",
608+
content="""I don't want to call tools today""",
609+
tool_calls=None,
610+
raw="""I don't want to call tools today""",
611+
)
612+
613+
agent_toolcalling = ToolCallingAgent(model=fake_json_model_no_call, tools=[], max_steps=1, verbosity_level=10)
614+
with agent_toolcalling.logger.console.capture() as capture:
615+
agent_toolcalling.run("Dummy task")
616+
assert "don't" in capture.get() and "want" in capture.get()
617+
618+
def fake_code_model_no_call(messages, stop_sequences=None):
619+
return ChatMessage(
620+
role="assistant",
621+
content="""I don't want to write an action today""",
622+
)
623+
624+
agent_code = CodeAgent(model=fake_code_model_no_call, tools=[], max_steps=1, verbosity_level=10)
625+
with agent_code.logger.console.capture() as capture:
626+
agent_code.run("Dummy task")
627+
assert "don't" in capture.get() and "want" in capture.get()
628+
633629
def test_step_number(self):
634630
fake_model = MagicMock()
635631
fake_model.last_input_token_count = 10
@@ -892,6 +888,35 @@ def fake_code_model(messages, stop_sequences=None, grammar=None) -> str:
892888
agent.run("Test request")
893889
assert "secret\\\\" in repr(capture.get())
894890

891+
def test_missing_import_triggers_advice_in_error_log(self):
892+
# Set explicit verbosity level to 1 to override the default verbosity level of -1 set in CI fixture
893+
agent = CodeAgent(tools=[], model=fake_code_model_import, verbosity_level=1)
894+
895+
with agent.logger.console.capture() as capture:
896+
agent.run("Count to 3")
897+
str_output = capture.get()
898+
assert "`additional_authorized_imports`" in str_output.replace("\n", "")
899+
900+
def test_errors_show_offending_line_and_error(self):
901+
agent = CodeAgent(tools=[PythonInterpreterTool()], model=fake_code_model_error)
902+
output = agent.run("What is 2 multiplied by 3.6452?")
903+
assert isinstance(output, AgentText)
904+
assert output == "got an error"
905+
assert "Code execution failed at line 'error_function()'" in str(agent.memory.steps[1].error)
906+
assert "ValueError" in str(agent.memory.steps)
907+
908+
def test_error_saves_previous_print_outputs(self):
909+
agent = CodeAgent(tools=[PythonInterpreterTool()], model=fake_code_model_error, verbosity_level=10)
910+
agent.run("What is 2 multiplied by 3.6452?")
911+
assert "Flag!" in str(agent.memory.steps[1].observations)
912+
913+
def test_syntax_error_show_offending_lines(self):
914+
agent = CodeAgent(tools=[PythonInterpreterTool()], model=fake_code_model_syntax_error)
915+
output = agent.run("What is 2 multiplied by 3.6452?")
916+
assert isinstance(output, AgentText)
917+
assert output == "got an error"
918+
assert ' print("Failing due to unexpected indent")' in str(agent.memory.steps)
919+
895920
def test_change_tools_after_init(self):
896921
from smolagents import tool
897922

0 commit comments

Comments
 (0)