bug fixing

This commit is contained in:
João Moura
2024-02-20 10:40:16 -03:00
parent e24f4867df
commit 8f5d735b2f
6 changed files with 38 additions and 36 deletions

View File

@@ -13,7 +13,7 @@ from langchain_core.utils.input import get_color_mapping
from pydantic import InstanceOf from pydantic import InstanceOf
from crewai.agents.tools_handler import ToolsHandler from crewai.agents.tools_handler import ToolsHandler
from crewai.tools.tool_usage import ToolUsage from crewai.tools.tool_usage import ToolUsage, ToolUsageErrorException
from crewai.utilities import I18N from crewai.utilities import I18N
@@ -111,13 +111,19 @@ class CrewAgentExecutor(AgentExecutor):
callbacks=run_manager.get_child() if run_manager else None, callbacks=run_manager.get_child() if run_manager else None,
**inputs, **inputs,
) )
if self._should_force_answer(): if self._should_force_answer():
if isinstance(output, AgentAction) or isinstance(output, AgentFinish): if isinstance(output, AgentFinish):
yield output
return
if isinstance(output, AgentAction):
output = output output = output
else: else:
raise ValueError( raise ValueError(
f"Unexpected output type from agent: {type(output)}" f"Unexpected output type from agent: {type(output)}"
) )
yield AgentStep( yield AgentStep(
action=output, observation=self._i18n.errors("force_final_answer") action=output, observation=self._i18n.errors("force_final_answer")
) )
@@ -192,20 +198,23 @@ class CrewAgentExecutor(AgentExecutor):
) )
tool_calling = tool_usage.parse(agent_action.log) tool_calling = tool_usage.parse(agent_action.log)
if tool_calling.tool_name.lower().strip() in [ if isinstance(tool_calling, ToolUsageErrorException):
name.lower().strip() for name in name_to_tool_map observation = tool_calling.message
]:
observation = tool_usage.use(tool_calling, agent_action.log)
else: else:
tool_run_kwargs = self.agent.tool_run_logging_kwargs() if tool_calling.tool_name.lower().strip() in [
observation = InvalidTool().run( name.lower().strip() for name in name_to_tool_map
{ ]:
"requested_tool_name": tool_calling.tool_name, observation = tool_usage.use(tool_calling, agent_action.log)
"available_tool_names": list(name_to_tool_map.keys()), else:
}, tool_run_kwargs = self.agent.tool_run_logging_kwargs()
verbose=self.verbose, observation = InvalidTool().run(
color=None, {
callbacks=run_manager.get_child() if run_manager else None, "requested_tool_name": tool_calling.tool_name,
**tool_run_kwargs, "available_tool_names": list(name_to_tool_map.keys()),
) },
verbose=self.verbose,
color=None,
callbacks=run_manager.get_child() if run_manager else None,
**tool_run_kwargs,
)
yield AgentStep(action=agent_action, observation=observation) yield AgentStep(action=agent_action, observation=observation)

View File

@@ -18,7 +18,6 @@ class ToolsHandler:
def on_tool_use(self, calling: ToolCalling, output: str) -> Any: def on_tool_use(self, calling: ToolCalling, output: str) -> Any:
"""Run when tool ends running.""" """Run when tool ends running."""
print(f"Tool {calling.tool_name} has been used.")
self.last_used_tool = calling self.last_used_tool = calling
if calling.tool_name != CacheTools().name: if calling.tool_name != CacheTools().name:
self.cache.add( self.cache.add(

View File

@@ -114,7 +114,7 @@ class Task(BaseModel):
for task in self.context: for task in self.context:
if task.async_execution: if task.async_execution:
task.thread.join() task.thread.join()
context.append(task.output.result) context.append(task.output.raw_output)
context = "\n".join(context) context = "\n".join(context)
tools = tools or self.tools tools = tools or self.tools

View File

@@ -1,4 +1,4 @@
from typing import Any, Dict from typing import Any, Dict, Optional
from pydantic import BaseModel as PydanticBaseModel from pydantic import BaseModel as PydanticBaseModel
from pydantic import Field as PydanticField from pydantic import Field as PydanticField
@@ -7,7 +7,7 @@ from pydantic.v1 import BaseModel, Field
class ToolCalling(BaseModel): class ToolCalling(BaseModel):
tool_name: str = Field(..., description="The name of the tool to be called.") tool_name: str = Field(..., description="The name of the tool to be called.")
arguments: Dict[str, Any] = Field( arguments: Optional[Dict[str, Any]] = Field(
..., description="A dictinary of arguments to be passed to the tool." ..., description="A dictinary of arguments to be passed to the tool."
) )
@@ -16,6 +16,6 @@ class InstructorToolCalling(PydanticBaseModel):
tool_name: str = PydanticField( tool_name: str = PydanticField(
..., description="The name of the tool to be called." ..., description="The name of the tool to be called."
) )
arguments: Dict = PydanticField( arguments: Optional[Dict[str, Any]] = PydanticField(
..., description="A dictinary of arguments to be passed to the tool." ..., description="A dictinary of arguments to be passed to the tool."
) )

View File

@@ -113,7 +113,10 @@ class ToolUsage:
if not result: if not result:
try: try:
result = tool._run(**calling.arguments) if calling.arguments:
result = tool._run(**calling.arguments)
else:
result = tool._run()
except Exception as e: except Exception as e:
self._run_attempts += 1 self._run_attempts += 1
if self._run_attempts > self._max_parsing_attempts: if self._run_attempts > self._max_parsing_attempts:
@@ -206,6 +209,7 @@ class ToolUsage:
), ),
) )
calling = instructor.to_pydantic() calling = instructor.to_pydantic()
else: else:
parser = ToolOutputParser(pydantic_object=ToolCalling) parser = ToolOutputParser(pydantic_object=ToolCalling)
prompt = PromptTemplate( prompt = PromptTemplate(
@@ -234,7 +238,7 @@ class ToolUsage:
self._telemetry.tool_usage_error(llm=self.llm) self._telemetry.tool_usage_error(llm=self.llm)
self._printer.print(content=f"\n\n{e}\n", color="red") self._printer.print(content=f"\n\n{e}\n", color="red")
return ToolUsageErrorException( return ToolUsageErrorException(
f'{self._i18n.errors("tool_usage_error")}.\n{self._i18n.slice("format").format(tool_names=self.tools_names)}' f'{self._i18n.errors("tool_usage_error")}\n{self._i18n.slice("format").format(tool_names=self.tools_names)}'
) )
return self._tool_calling(tool_string) return self._tool_calling(tool_string)

View File

@@ -15,12 +15,7 @@ class Prompts(BaseModel):
def task_execution_with_memory(self) -> BasePromptTemplate: def task_execution_with_memory(self) -> BasePromptTemplate:
"""Generate a prompt for task execution with memory components.""" """Generate a prompt for task execution with memory components."""
slices = ["role_playing"] slices = ["role_playing", "tools", "memory", "task"]
if len(self.tools) > 0:
slices.append("tools")
else:
slices.append("no_tools")
slices.extend(["memory", "task"])
return self._build_prompt(slices) return self._build_prompt(slices)
def task_execution_without_tools(self) -> BasePromptTemplate: def task_execution_without_tools(self) -> BasePromptTemplate:
@@ -29,12 +24,7 @@ class Prompts(BaseModel):
def task_execution(self) -> BasePromptTemplate: def task_execution(self) -> BasePromptTemplate:
"""Generate a standard prompt for task execution.""" """Generate a standard prompt for task execution."""
slices = ["role_playing"] slices = ["role_playing", "tools", "task"]
if len(self.tools) > 0:
slices.append("tools")
else:
slices.append("no_tools")
slices.append("task")
return self._build_prompt(slices) return self._build_prompt(slices)
def _build_prompt(self, components: list[str]) -> BasePromptTemplate: def _build_prompt(self, components: list[str]) -> BasePromptTemplate: