diff --git a/libs/langchain/langchain/output_parsers/boolean.py b/libs/langchain/langchain/output_parsers/boolean.py index d670d155a34..c9e6dc615b1 100644 --- a/libs/langchain/langchain/output_parsers/boolean.py +++ b/libs/langchain/langchain/output_parsers/boolean.py @@ -19,13 +19,24 @@ class BooleanOutputParser(BaseOutputParser[bool]): boolean """ - cleaned_text = text.strip() - if cleaned_text.upper() not in (self.true_val.upper(), self.false_val.upper()): + cleaned_upper_text = text.strip().upper() + if ( + self.true_val.upper() in cleaned_upper_text + and self.false_val.upper() in cleaned_upper_text + ): raise ValueError( - f"BooleanOutputParser expected output value to either be " - f"{self.true_val} or {self.false_val}. Received {cleaned_text}." + f"Ambiguous response. Both {self.true_val} and {self.false_val} in " + f"received: {text}." + ) + elif self.true_val.upper() in cleaned_upper_text: + return True + elif self.false_val.upper() in cleaned_upper_text: + return False + else: + raise ValueError( + f"BooleanOutputParser expected output value to include either " + f"{self.true_val} or {self.false_val}. Received {text}." ) - return cleaned_text.upper() == self.true_val.upper() @property def _type(self) -> str: diff --git a/libs/langchain/tests/unit_tests/output_parsers/test_boolean_parser.py b/libs/langchain/tests/unit_tests/output_parsers/test_boolean_parser.py index 8804c36338e..60cad855be6 100644 --- a/libs/langchain/tests/unit_tests/output_parsers/test_boolean_parser.py +++ b/libs/langchain/tests/unit_tests/output_parsers/test_boolean_parser.py @@ -20,6 +20,17 @@ def test_boolean_output_parser_parse() -> None: result = parser.parse("no") assert result is False + # Test valid input + result = parser.parse("Not relevant (NO)") + assert result is False + + # Test ambiguous input + try: + parser.parse("yes and no") + assert False, "Should have raised ValueError" + except ValueError: + pass + # Test invalid input try: parser.parse("INVALID")