From 1e7d9c4635039eda0dee357d4db1a61e9a2b7126 Mon Sep 17 00:00:00 2001 From: Anugrah Date: Fri, 9 Oct 2026 02:26:34 +0530 Subject: [PATCH] Stop choice extraction matching the last letter of a parenthesized word `_extract_parenthesized_choice` searched for `\(?(\w)\)`, which also matches the final letter of any word followed by a closing parenthesis. A reply such as "I think (probably) the answer is (b)" therefore yielded "y" instead of "b". Require a word boundary before the choice character so only a standalone character such as "(b)" or "b)" is accepted. --- concordia/utils/sampling.py | 4 +++- concordia/utils/sampling_test.py | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/concordia/utils/sampling.py b/concordia/utils/sampling.py index 53a9ad4a3..92600dd6f 100644 --- a/concordia/utils/sampling.py +++ b/concordia/utils/sampling.py @@ -20,7 +20,9 @@ def _extract_parenthesized_choice(sample: str): """Given text formatted as 'lorum(a)ipsum', return 'a'.""" - match = re.search(r'\(?(\w)\)', sample) + # The word boundary stops the last letter of a parenthesized word, such as + # the 'y' in '(probably)', from being mistaken for a choice. + match = re.search(r'\(?\b(\w)\)', sample) if match: return match.group(1) else: diff --git a/concordia/utils/sampling_test.py b/concordia/utils/sampling_test.py index c3d6b3b1d..281b701de 100644 --- a/concordia/utils/sampling_test.py +++ b/concordia/utils/sampling_test.py @@ -30,6 +30,12 @@ class ExtractChoiceResponseTest(parameterized.TestCase): ('parenthesized_in_middle', 'foo(a)bar', 'a'), ('parenthesized_at_end', 'The answer is (b).', 'b'), ('letter_then_paren_in_longer_string', 'a) because', 'a'), + ( + 'parenthesized_word_before_choice', + 'I think (probably) the answer is (b)', + 'b', + ), + ('unopened_word_before_choice', 'maybe) (a)', 'a'), ) def test_extracts_choice(self, sample, expected): self.assertEqual(sampling.extract_choice_response(sample), expected) @@ -38,6 +44,7 @@ def test_extracts_choice(self, sample, expected): ('empty_string', ''), ('no_parenthesized_choice', 'no choice here'), ('word_without_closing_paren', '(abc'), + ('parenthesized_word_only', '(yes) a'), ) def test_returns_none_when_no_choice(self, sample): self.assertIsNone(sampling.extract_choice_response(sample))