From b88a6f626174e5fa3868aa8e7ab4dfd275830453 Mon Sep 17 00:00:00 2001 From: Juniper Alanna <201364921+juniper-shopify@users.noreply.github.com> Date: Fri, 27 Mar 2026 15:06:43 -0400 Subject: [PATCH] Fix number parsing order --- lib/roast/cog/output.rb | 3 +- test/roast/cog/output_test.rb | 72 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/lib/roast/cog/output.rb b/lib/roast/cog/output.rb index e4815fcc..e4e7b257 100644 --- a/lib/roast/cog/output.rb +++ b/lib/roast/cog/output.rb @@ -241,8 +241,9 @@ def extract_number_candidates(input) lines.reverse.each do |line| # Look for numbers with various separators, formats, and currency symbols (very permissive) # Matches: 123, 1,234, 1_234, 1 234, 1.23, -1.23, 1.23e10, 1.23e-10 + # Reversed so that the last number on the line is tried first (matching the bottom-up line order) matches = line.scan(/-?[\d\s$¢£€¥.,_]+(?:[eE][+-]?\d+)?/) #: as Array[String] - candidates.concat(matches.map(&:strip)) + candidates.concat(matches.map(&:strip).reverse) end candidates.compact.uniq diff --git a/test/roast/cog/output_test.rb b/test/roast/cog/output_test.rb index e0dc0b73..e3efb4de 100644 --- a/test/roast/cog/output_test.rb +++ b/test/roast/cog/output_test.rb @@ -209,6 +209,78 @@ def raw_text assert_equal 42.50, number_output.float! end + test "output with number support extracts last number from a line with multiple numbers" do + number_output = Class.new(Output) do + include Output::WithNumber + + def raw_text + "12 - 5 = 7" + end + end.new + + assert_equal 7, number_output.integer! + end + + test "output with number support extracts last number from arithmetic expression" do + number_output = Class.new(Output) do + include Output::WithNumber + + def raw_text + "2 + 2 = 4" + end + end.new + + assert_equal 4, number_output.integer! + end + + test "output with number support extracts last number from multi-line response" do + number_output = Class.new(Output) do + include Output::WithNumber + + def raw_text + "First I calculated 2 + 2 = 4\nThen I multiplied 4 * 3 = 12\nFinally 12 - 5 = 7" + end + end.new + + assert_equal 7, number_output.integer! + end + + test "output with number support extracts last number from sentence with embedded numbers" do + number_output = Class.new(Output) do + include Output::WithNumber + + def raw_text + "The answer to 100 divided by 4 is 25" + end + end.new + + assert_equal 25, number_output.integer! + end + + test "output with number support extracts last float from a line with multiple numbers" do + number_output = Class.new(Output) do + include Output::WithNumber + + def raw_text + "3.14 * 2 = 6.28" + end + end.new + + assert_in_delta 6.28, number_output.float! + end + + test "output with number support prefers last line last number over earlier lines" do + number_output = Class.new(Output) do + include Output::WithNumber + + def raw_text + "Step 1: 100\nStep 2: 50\nResult: 42" + end + end.new + + assert_equal 42, number_output.integer! + end + # Test Output subclasses with text formatting capabilities test "output with text support returns stripped text" do text_output = Class.new(Output) do