bugfix(tool call ebnf): Fix EBNF generation for optional function parameters (#7283)

This commit is contained in:
Chang Su
2025-06-17 13:36:07 -07:00
committed by GitHub
parent 8c16da334e
commit e726131523
4 changed files with 320 additions and 10 deletions

View File

@@ -1,8 +1,10 @@
"""
python3 -m unittest test_ebnf_constrained.TestEBNFConstrained.test_ebnf_generate_email
python3 -m unittest test_ebnf_constrained.TestEBNFConstrained.test_ebnf_generate_greeting
python3 -m unittest test_ebnf_constrained.TestEBNFConstrained.test_ebnf_generate_all_optional_function_params
python3 -m unittest test_ebnf_constrained.TestEBNFConstrainedLLGuidance.test_ebnf_generate_email
python3 -m unittest test_ebnf_constrained.TestEBNFConstrainedLLGuidance.test_ebnf_generate_greeting
python3 -m unittest test_ebnf_constrained.TestEBNFConstrainedLLGuidance.test_ebnf_generate_all_optional_function_params
"""
import json
@@ -237,6 +239,38 @@ class TestEBNFConstrained(CustomTestCase):
n=3,
)
def test_ebnf_generate_all_optional_function_params(self):
"""Test function call with all optional parameters - verifies flexible ordering."""
self.__class__.ebnf_grammar = """
root ::= function_call
function_call ::= call_config_service
call_config_service ::= "{" "\\"name\\"" ":" "\\"config_service\\"" ", " "\\"arguments\\"" ":" arguments_config_service "}"
arguments_config_service ::= "{" ( "\\"theme\\"" ":" ("\\"light\\"" | "\\"dark\\"") ( "," "\\"language\\"" ":" ("\\"en\\"" | "\\"es\\"" | "\\"fr\\"") )? ( "," "\\"notifications\\"" ":" ("true" | "false") )? | "\\"language\\"" ":" ("\\"en\\"" | "\\"es\\"" | "\\"fr\\"") ( "," "\\"notifications\\"" ":" ("true" | "false") )? | "\\"notifications\\"" ":" ("true" | "false") )? "}"
"""
# Test patterns that should match - flexible ordering of optional parameters
allowed_patterns = [
# Empty arguments
r'^\{"name":"config_service", "arguments":\{\}\}$',
# Single optional parameters (any can appear first)
r'^\{"name":"config_service", "arguments":\{"theme":"(light|dark)"\}\}$',
r'^\{"name":"config_service", "arguments":\{"language":"(en|es|fr)"\}\}$',
r'^\{"name":"config_service", "arguments":\{"notifications":(true|false)\}\}$',
# Two optional parameters (in any order)
r'^\{"name":"config_service", "arguments":\{"theme":"(light|dark)", "language":"(en|es|fr)"\}\}$',
r'^\{"name":"config_service", "arguments":\{"theme":"(light|dark)", "notifications":(true|false)\}\}$',
r'^\{"name":"config_service", "arguments":\{"language":"(en|es|fr)", "notifications":(true|false)\}\}$',
# All three optional parameters
r'^\{"name":"config_service", "arguments":\{"theme":"(light|dark)", "language":"(en|es|fr)", "notifications":(true|false)\}\}$',
]
prompt = "Configure the service with optional settings:"
self.run_decode(
ebnf=self.__class__.ebnf_grammar,
expected_patterns=allowed_patterns,
prompt=prompt,
n=5,
)
class TestEBNFConstrainedLLGuidance(TestEBNFConstrained):
@classmethod