Closed qiaolb closed 2 days ago
To resolve the TypeError: sequence item 0: expected str instance, dict found
error, you need to ensure that all items in the sequence being joined are strings. The error typically occurs when you try to join a list of dictionaries or other non-string items.
In the provided code, the issue likely arises when converting the result
to a string. Specifically, the result["output"]
might be a dictionary or a list of dictionaries instead of a string.
To fix this, you should convert the result["output"]
to a string before returning it. Here is the modified part of the run_agent
method:
async def run_agent(self) -> Message:
if "input" not in self.user_prompt:
raise ValueError("Prompt must contain 'input' key.")
messages = [
("system", self.system_prompt),
("placeholder", "{chat_history}"),
("human", self.user_prompt),
("placeholder", "{agent_scratchpad}"),
]
prompt = ChatPromptTemplate.from_messages(messages)
agent = create_tool_calling_agent(self.llm, self.tools, prompt)
runnable = AgentExecutor.from_agent_and_tools(
agent=cast(BaseSingleActionAgent, agent),
tools=self.tools,
verbose=True,
handle_parsing_errors=self.handle_parsing_errors,
)
input_dict: dict[str, str | list[Dict[str, str]]] = {"input": self.input_value}
if hasattr(self, "memory") and self.memory:
input_dict["chat_history"] = self.convert_chat_history(self.memory)
result = await runnable.ainvoke(input_dict)
self.status = result
if "output" not in result:
raise ValueError("Output key not found in result. Tried 'output'.")
# Ensure result_string is a string
result_string = str(result["output"])
return Message(text=result_string)
By converting result["output"]
to a string using str(result["output"])
, you ensure that the Message
object receives a string, thus avoiding the TypeError
[1].
Additionally, ensure that the user_prompt
contains the 'input' key as required by the ToolCallingAgentComponent
class:
async def build(
self,
input_value: str,
llm: BaseLanguageModel,
tools: List[Tool],
user_prompt: str = "{input}",
message_history: Optional[List[Record]] = None,
system_message: str = "You are a helpful assistant",
handle_parsing_errors: bool = True,
) -> Text:
if "input" not in user_prompt:
raise ValueError("Prompt must contain 'input' key.")
messages = [
("system", system_message),
("placeholder", "{chat_history}"),
("human", user_prompt),
("placeholder", "{agent_scratchpad}"),
]
prompt = ChatPromptTemplate.from_messages(messages)
agent = create_tool_calling_agent(llm, tools, prompt)
result = await self.run_agent(agent, input_value, tools, message_history, handle_parsing_errors)
self.status = result
return result
This ensures that the prompt is correctly formatted and the agent can process the input without errors [1].
In the context of using the Flow as Tool through the Tool Call Agent, ensure that the FlowToolComponent
is correctly configured and that the result["output"]
is properly handled. The FlowToolComponent
class is designed to construct a Tool from a function that runs the loaded Flow, and it includes methods to retrieve and manage flows:
class FlowToolComponent(CustomComponent):
display_name = "Flow as Tool"
description = "Construct a Tool from a function that runs the loaded Flow."
field_order = ["flow_name", "name", "description", "return_direct"]
trace_type = "tool"
beta = True
def get_flow_names(self) -> List[str]:
flow_datas = self.list_flows()
return [flow_data.data["name"] for flow_data in flow_datas]
def get_flow(self, flow_name: str) -> Optional[Data]:
flow_datas = self.list_flows()
for flow_data in flow_datas:
if flow_data.data["name"] == flow_name:
return flow_data
return None
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None):
logger.debug(f"Updating build config with field value {field_value} and field name {field_name}")
if field_name == "flow_name":
build_config["flow_name"]["options"] = self.get_flow_names()
return build_config
def build_config(self):
return {
"flow_name": {
"display_name": "Flow Name",
"info": "The name of the flow to run.",
"options": [],
"real_time_refresh": True,
"refresh_button": True,
},
"name": {
"display_name": "Name",
"description": "The name of the tool.",
},
"description": {
"display_name": "Description",
"description": "The description of the tool.",
},
"return_direct": {
"display_name": "Return Direct",
"description": "Return the result directly from the Tool.",
"advanced": True,
},
}
async def build(self, flow_name: str, name: str, description: str, return_direct: bool = False) -> Tool:
FlowTool.update_forward_refs()
flow_data = self.get_flow(flow_name)
if not flow_data:
raise ValueError("Flow not found.")
graph = Graph.from_payload(flow_data.data["data"])
inputs = get_flow_inputs(graph)
tool = FlowTool(
name=name,
description=description,
graph=graph,
return_direct=return_direct,
inputs=inputs,
flow_id=str(flow_data.id),
user_id=str(self._user_id),
)
description_repr = repr(tool.description).strip("'")
args_str = "\n".join([f"- {arg_name}: {arg_data['description']}" for arg_name, arg_data in tool.args.items()])
self.status = f"{description_repr}\nArguments:\n{args_str}"
return tool # type: ignore
Ensure that the FlowToolComponent
is properly instantiated and that the result["output"]
is correctly converted to a string before being used [1].
To continue talking to Dosu, mention @dosu.
Hi @qiaolb Could you try using the new version 1.0.10 and see if the error still occurs?
Thank you for your contribution! This issue will be closed. If you have any questions or encounter another problem, please open a new issue and we will be ready to assist you.
Describe the bug When invoking the Flow as Tool through the Tool Call Agent, the system displayed an error message:
TypeError: sequence item 0: expected str instance, dict found
Browser and Version
To Reproduce Steps to reproduce the behavior:
Additional context The issue was resolved after I made the following modifications to the code. Details are as follows:
langflow/base/flow_processing/utils.py, line 91:
Before the modification:
After the modification: