@@ -60,6 +60,101 @@ def td() -> TestData:
6060 .variation_for_all (0 )
6161 )
6262
63+ td .update (
64+ td .flag ('completion-tools-in-model-params' )
65+ .variations (
66+ {
67+ 'model' : {
68+ 'name' : 'gpt-5' ,
69+ 'parameters' : {
70+ 'temperature' : 0.5 ,
71+ 'tools' : {
72+ 'param-tool' : {
73+ 'name' : 'param-tool' ,
74+ 'type' : 'function' ,
75+ 'description' : 'A tool from model params' ,
76+ 'parameters' : {'type' : 'object' },
77+ }
78+ },
79+ },
80+ },
81+ 'messages' : [{'role' : 'user' , 'content' : 'Hello' }],
82+ '_ldMeta' : {'enabled' : True , 'variationKey' : 'v1' , 'version' : 1 },
83+ },
84+ )
85+ .variation_for_all (0 )
86+ )
87+
88+ td .update (
89+ td .flag ('completion-root-and-model-params-tools' )
90+ .variations (
91+ {
92+ 'model' : {
93+ 'name' : 'gpt-5' ,
94+ 'parameters' : {
95+ 'tools' : {
96+ 'model-param-tool' : {
97+ 'name' : 'model-param-tool' ,
98+ 'type' : 'function' ,
99+ }
100+ },
101+ },
102+ },
103+ 'messages' : [{'role' : 'user' , 'content' : 'Hello' }],
104+ 'tools' : {
105+ 'root-tool' : {
106+ 'name' : 'root-tool' ,
107+ 'type' : 'function' ,
108+ }
109+ },
110+ '_ldMeta' : {'enabled' : True , 'variationKey' : 'v1' , 'version' : 1 },
111+ },
112+ )
113+ .variation_for_all (0 )
114+ )
115+
116+ td .update (
117+ td .flag ('completion-model-params-tools-as-list' )
118+ .variations (
119+ {
120+ 'model' : {
121+ 'name' : 'gpt-5' ,
122+ 'parameters' : {
123+ 'tools' : [
124+ {'name' : 'list-tool' , 'type' : 'function' },
125+ ],
126+ },
127+ },
128+ 'messages' : [{'role' : 'user' , 'content' : 'Hello' }],
129+ '_ldMeta' : {'enabled' : True , 'variationKey' : 'v1' , 'version' : 1 },
130+ },
131+ )
132+ .variation_for_all (0 )
133+ )
134+
135+ td .update (
136+ td .flag ('completion-model-params-tools-missing-name' )
137+ .variations (
138+ {
139+ 'model' : {
140+ 'name' : 'gpt-5' ,
141+ 'parameters' : {
142+ 'tools' : {
143+ 'valid-tool' : {
144+ 'name' : 'valid-tool' ,
145+ 'type' : 'function' ,
146+ },
147+ 'bad-entry' : 'not-a-dict' ,
148+ },
149+ },
150+ },
151+ 'messages' : [{'role' : 'user' , 'content' : 'Hello' }],
152+ '_ldMeta' : {'enabled' : True , 'variationKey' : 'v1' , 'version' : 1 },
153+ },
154+ )
155+ .variation_for_all (0 )
156+ )
157+
63158 return td
64159
65160
@@ -133,3 +228,36 @@ def test_aitool_to_dict_omits_none_fields():
133228 d = tool .to_dict ()
134229
135230 assert d == {'name' : 'bare-tool' }
231+
232+
233+ def test_completion_config_tools_from_model_params_when_no_root_tools (client , context ):
234+ result = client .completion_config ('completion-tools-in-model-params' , context , AICompletionConfigDefault ())
235+
236+ assert result .tools is not None
237+ assert 'param-tool' in result .tools
238+ tool = result .tools ['param-tool' ]
239+ assert tool .name == 'param-tool'
240+ assert tool .type == 'function'
241+ assert tool .description == 'A tool from model params'
242+
243+
244+ def test_completion_config_root_tools_take_priority_over_model_params (client , context ):
245+ result = client .completion_config ('completion-root-and-model-params-tools' , context , AICompletionConfigDefault ())
246+
247+ assert result .tools is not None
248+ assert 'root-tool' in result .tools
249+ assert 'model-param-tool' not in result .tools
250+
251+
252+ def test_completion_config_model_params_tools_as_list_returns_none (client , context ):
253+ result = client .completion_config ('completion-model-params-tools-as-list' , context , AICompletionConfigDefault ())
254+
255+ assert result .tools is None
256+
257+
258+ def test_completion_config_model_params_tools_skips_bad_entries_silently (client , context ):
259+ result = client .completion_config ('completion-model-params-tools-missing-name' , context , AICompletionConfigDefault ())
260+
261+ assert result .tools is not None
262+ assert 'valid-tool' in result .tools
263+ assert 'bad-entry' not in result .tools
0 commit comments