I’m trying to run the Lesson 8 chaining code (I’ve successfully done 1-7). I get this error:
File "/Users/donohoe/work/python/.venv/lib/python3.11/site-packages/smolagents/models.py", line 291, in get_clean_message_list
role = message.role
^^^^^^^^^^^^
AttributeError: 'dict' object has no attribute 'role'
The issue turns out to be that the fastacp.py
code is passing in a dict
where the agent code is expecting ChatMessage
data class. I had to add some verbose debug logging to figure this out:
except Exception as e:
self.logger.log(f"Error in step {step_num + 1}: {str(e)}", level=LogLevel.ERROR)
# JDD-debugging
import traceback
# Print the full traceback to see the original error
print("=== FULL EXCEPTION CHAIN ===")
traceback.print_exc()
# Also check for chained exceptions
if hasattr(e, '__cause__') and e.__cause__:
print("\n=== ORIGINAL CAUSE ===")
traceback.print_exception(type(e.__cause__), e.__cause__, e.__cause__.__traceback__)
if hasattr(e, '__context__') and e.__context__:
print("\n=== EXCEPTION CONTEXT ===")
traceback.print_exception(type(e.__context__), e.__context__, e.__context__.__traceback__)
# JDD-debugging-end
So to get around this I added this converter:
from smolagents.models import ChatMessage as SmolChatMessage
def convert_to_chat_message(msg_dict):
if isinstance(msg_dict, dict):
return SmolChatMessage(
role=msg_dict['role'],
content=msg_dict.get('content'),
tool_calls=msg_dict.get('tool_calls'),
raw=msg_dict.get('raw'),
token_usage=msg_dict.get('token_usage')
)
return msg_dict # Already a ChatMessage
And used it here to convert memory_messages
from a list of dict
to smolagent’s ChatMessage
.
try:
# JDD: convert to actual type API expects (sigh)
chat_messages = [convert_to_chat_message(msg) for msg in memory_messages]
model_message: ChatMessage = self.model(
chat_messages,
tools_to_call_from=list(self.tools.values())[:-1],
stop_sequences=["Observation:", "Calling agents:"],
)
memory_step.model_output_message = model_message
This moves things along, and I see the agents getting called and answers getting returned, but it just runs through the 10 loops, ending with:
Final result: I wasn't able to complete this task within the maximum number of steps.
I’ve run out of patience trying to understand the code in fastacp.py
. This class is frustrating because there is no real recourse for when things go wrong. It all assumes a happy path. The fastacp.py
is 600+ lines of code that is hard to decipher.
This feels like the end state for any vibe coding experimentation. When things go wrong, I, the programmer, don’t really understand everything that is going on because I didn’t build it up piece by piece. Sure, I have now been introduced to some libraries and concepts but I haven’t internalized it at all, so debugging is a slog.
Anyhow, I’ve found this course a bit lacking, and sorry to say, the video explainers add very little value.