mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-08 15:48:29 +00:00
fix: re-raise OutputParserError in format_answer for retry logic
This commit is contained in:
@@ -157,7 +157,7 @@ def handle_max_iterations_exceeded(
|
||||
|
||||
# Perform one more LLM call to get the final answer
|
||||
answer = llm.call(
|
||||
messages, # type: ignore[arg-type]
|
||||
messages,
|
||||
callbacks=callbacks,
|
||||
)
|
||||
|
||||
@@ -197,9 +197,14 @@ def format_answer(answer: str) -> AgentAction | AgentFinish:
|
||||
|
||||
Returns:
|
||||
Either an AgentAction or AgentFinish
|
||||
|
||||
Raises:
|
||||
OutputParserError: When the LLM response format is invalid, allowing retry logic
|
||||
"""
|
||||
try:
|
||||
return parse(answer)
|
||||
except OutputParserError:
|
||||
raise
|
||||
except Exception:
|
||||
return AgentFinish(
|
||||
thought="Failed to parse LLM response",
|
||||
@@ -249,10 +254,10 @@ def get_llm_response(
|
||||
"""
|
||||
try:
|
||||
answer = llm.call(
|
||||
messages, # type: ignore[arg-type]
|
||||
messages,
|
||||
callbacks=callbacks,
|
||||
from_task=from_task,
|
||||
from_agent=from_agent,
|
||||
from_agent=from_agent, # type: ignore[arg-type]
|
||||
response_model=response_model,
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -294,8 +299,8 @@ def handle_agent_action_core(
|
||||
formatted_answer: AgentAction,
|
||||
tool_result: ToolResult,
|
||||
messages: list[LLMMessage] | None = None,
|
||||
step_callback: Callable | None = None,
|
||||
show_logs: Callable | None = None,
|
||||
step_callback: Callable[[Any], Any] | None = None,
|
||||
show_logs: Callable[[Any], Any] | None = None,
|
||||
) -> AgentAction | AgentFinish:
|
||||
"""Core logic for handling agent actions and tool results.
|
||||
|
||||
@@ -481,7 +486,7 @@ def summarize_messages(
|
||||
),
|
||||
]
|
||||
summary = llm.call(
|
||||
messages, # type: ignore[arg-type]
|
||||
messages,
|
||||
callbacks=callbacks,
|
||||
)
|
||||
summarized_contents.append({"content": str(summary)})
|
||||
|
||||
69
lib/crewai/tests/utilities/test_agent_utils.py
Normal file
69
lib/crewai/tests/utilities/test_agent_utils.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""Tests for agent_utils module."""
|
||||
|
||||
import pytest
|
||||
|
||||
from crewai.agents.parser import AgentFinish, OutputParserError
|
||||
from crewai.utilities.agent_utils import format_answer
|
||||
|
||||
|
||||
class TestFormatAnswer:
|
||||
"""Tests for the format_answer function."""
|
||||
|
||||
def test_format_answer_with_valid_final_answer(self) -> None:
|
||||
"""Test that format_answer correctly parses a valid final answer."""
|
||||
answer = """Thought: I have completed the task.
|
||||
Final Answer: The result is 42."""
|
||||
|
||||
result = format_answer(answer)
|
||||
|
||||
assert isinstance(result, AgentFinish)
|
||||
assert result.output == "The result is 42."
|
||||
|
||||
def test_format_answer_reraises_output_parser_error(self) -> None:
|
||||
"""Test that format_answer re-raises OutputParserError for retry logic."""
|
||||
# Malformed output missing colons after "Thought", "Action", and "Action Input"
|
||||
malformed_answer = """Thought
|
||||
The user wants to verify something.
|
||||
Action
|
||||
Video Analysis Tool
|
||||
Action Input:
|
||||
{"query": "Is there something?"}"""
|
||||
|
||||
with pytest.raises(OutputParserError) as exc_info:
|
||||
format_answer(malformed_answer)
|
||||
|
||||
# Verify that the error message contains helpful information
|
||||
assert exc_info.value.error is not None
|
||||
|
||||
def test_format_answer_with_missing_action_colon(self) -> None:
|
||||
"""Test that format_answer raises OutputParserError when Action colon is missing."""
|
||||
malformed_answer = """Thought: I need to search for information.
|
||||
Action
|
||||
Search Tool
|
||||
Action Input: {"query": "test"}"""
|
||||
|
||||
with pytest.raises(OutputParserError):
|
||||
format_answer(malformed_answer)
|
||||
|
||||
def test_format_answer_with_missing_action_input_colon(self) -> None:
|
||||
"""Test that format_answer raises OutputParserError when Action Input colon is missing."""
|
||||
malformed_answer = """Thought: I need to search for information.
|
||||
Action: Search Tool
|
||||
Action Input
|
||||
{"query": "test"}"""
|
||||
|
||||
with pytest.raises(OutputParserError):
|
||||
format_answer(malformed_answer)
|
||||
|
||||
def test_format_answer_with_valid_action(self) -> None:
|
||||
"""Test that format_answer correctly parses a valid action format."""
|
||||
valid_action = """Thought: I need to search for information.
|
||||
Action: Search Tool
|
||||
Action Input: {"query": "test"}"""
|
||||
|
||||
# This should parse successfully without raising an exception
|
||||
result = format_answer(valid_action)
|
||||
|
||||
# The result should be an AgentAction (not AgentFinish)
|
||||
assert result is not None
|
||||
assert not isinstance(result, AgentFinish)
|
||||
Reference in New Issue
Block a user