@@ -41,6 +41,7 @@ def default_kwargs(self):
4141 "system" : "" ,
4242 "tool_model_enabled" : True ,
4343 "template" : "" ,
44+ "enable_structured_output" : True
4445 }
4546
4647 @pytest .fixture
@@ -1037,3 +1038,119 @@ def test_build_model_cloud_with_v1_suffix_stripped(self, mock_chat_ollama):
10371038 assert call_args ["base_url" ] == DEFAULT_OLLAMA_API_URL
10381039 assert "/v1" not in call_args ["base_url" ]
10391040 assert model == mock_model
1041+
1042+ @patch ("lfx.components.ollama.ollama.ChatOllama" )
1043+ def test_build_model_with_structured_output_disabled (self , mock_chat_ollama , component_class , default_kwargs ):
1044+ """Test that format field is NOT passed when enable_structured_output is False (default)."""
1045+ mock_instance = MagicMock ()
1046+ mock_chat_ollama .return_value = mock_instance
1047+
1048+ # Remove enable_structured_output to use default (False)
1049+ kwargs = default_kwargs .copy ()
1050+ kwargs .pop ("enable_structured_output" , None )
1051+ kwargs ["format" ] = "json" # Set format but it should be ignored
1052+
1053+ component = component_class (** kwargs )
1054+ model = component .build_model ()
1055+
1056+ # Verify ChatOllama was called WITHOUT format parameter
1057+ call_args = mock_chat_ollama .call_args [1 ]
1058+ assert "format" not in call_args , "format should not be passed when enable_structured_output is False"
1059+ assert model == mock_instance
1060+
1061+
1062+ @patch ("lfx.components.ollama.ollama.ChatOllama" )
1063+ def test_build_model_with_structured_output_enabled_string_format (self , mock_chat_ollama , component_class , default_kwargs ):
1064+ """Test that format field IS passed when enable_structured_output is True with string format."""
1065+ mock_instance = MagicMock ()
1066+ mock_chat_ollama .return_value = mock_instance
1067+
1068+ kwargs = default_kwargs .copy ()
1069+ kwargs ["enable_structured_output" ] = True
1070+ kwargs ["format" ] = "json"
1071+
1072+ component = component_class (** kwargs )
1073+ model = component .build_model ()
1074+
1075+ # Verify ChatOllama was called WITH format parameter
1076+ call_args = mock_chat_ollama .call_args [1 ]
1077+ assert "format" in call_args , "format should be passed when enable_structured_output is True"
1078+ assert call_args ["format" ] == "json"
1079+ assert model == mock_instance
1080+
1081+
1082+ @patch ("lfx.components.ollama.ollama.ChatOllama" )
1083+ def test_build_model_with_structured_output_enabled_dict_format (self , mock_chat_ollama , component_class , default_kwargs ):
1084+ """Test that JSON schema format IS passed when enable_structured_output is True."""
1085+ mock_instance = MagicMock ()
1086+ mock_chat_ollama .return_value = mock_instance
1087+
1088+ json_schema = {
1089+ "type" : "object" ,
1090+ "properties" : {"name" : {"type" : "string" }},
1091+ "required" : ["name" ],
1092+ }
1093+
1094+ kwargs = default_kwargs .copy ()
1095+ kwargs ["enable_structured_output" ] = True
1096+ kwargs ["format" ] = json_schema
1097+
1098+ component = component_class (** kwargs )
1099+ model = component .build_model ()
1100+
1101+ # Verify ChatOllama was called WITH format parameter as dict
1102+ call_args = mock_chat_ollama .call_args [1 ]
1103+ assert "format" in call_args
1104+ assert call_args ["format" ] == json_schema
1105+ assert call_args ["format" ]["type" ] == "object"
1106+ assert model == mock_instance
1107+
1108+
1109+ @patch ("lfx.components.ollama.ollama.ChatOllama" )
1110+ def test_build_model_with_structured_output_enabled_no_format (self , mock_chat_ollama , component_class , default_kwargs ):
1111+ """Test that format is not passed when enable_structured_output is True but format is None/empty."""
1112+ mock_instance = MagicMock ()
1113+ mock_chat_ollama .return_value = mock_instance
1114+
1115+ kwargs = default_kwargs .copy ()
1116+ kwargs ["enable_structured_output" ] = True
1117+ kwargs ["format" ] = None # No format specified
1118+
1119+ component = component_class (** kwargs )
1120+ model = component .build_model ()
1121+
1122+ # Verify ChatOllama was called WITHOUT format parameter
1123+ call_args = mock_chat_ollama .call_args [1 ]
1124+ assert "format" not in call_args , "format should not be passed when it's None"
1125+ assert model == mock_instance
1126+
1127+
1128+ @patch ("lfx.components.ollama.ollama.ChatOllama" )
1129+ def test_build_model_structured_output_toggle_behavior (self , mock_chat_ollama , component_class , default_kwargs ):
1130+ """Test toggling enable_structured_output affects format parameter passing."""
1131+ mock_instance = MagicMock ()
1132+ mock_chat_ollama .return_value = mock_instance
1133+
1134+ # First: Test with structured output disabled
1135+ kwargs = default_kwargs .copy ()
1136+ kwargs ["enable_structured_output" ] = False
1137+ kwargs ["format" ] = "json"
1138+
1139+ component = component_class (** kwargs )
1140+ model = component .build_model ()
1141+
1142+ call_args = mock_chat_ollama .call_args [1 ]
1143+ assert "format" not in call_args , "format should not be in call when disabled"
1144+
1145+ # Reset mock
1146+ mock_chat_ollama .reset_mock ()
1147+
1148+ # Second: Test with structured output enabled
1149+ kwargs ["enable_structured_output" ] = True
1150+ component = component_class (** kwargs )
1151+ model = component .build_model ()
1152+
1153+ call_args = mock_chat_ollama .call_args [1 ]
1154+ assert "format" in call_args , "format should be in call when enabled"
1155+ assert call_args ["format" ] == "json"
1156+ assert model == mock_instance
0 commit comments