@@ -114,6 +114,123 @@ describe("Ollama Fetcher", () => {
114114 expect ( parsedModel ! . supportsImages ) . toBe ( true )
115115 expect ( parsedModel ! . contextWindow ) . toBeGreaterThan ( 0 )
116116 } )
117+
118+ it ( "should detect vision via details.families when capabilities omits vision" , ( ) => {
119+ const modelData = {
120+ ...ollamaModelsData [ "qwen3-2to16:latest" ] ,
121+ details : {
122+ ...ollamaModelsData [ "qwen3-2to16:latest" ] . details ,
123+ families : [ "gemma4" , "clip" ] ,
124+ } ,
125+ capabilities : [ "completion" , "tools" ] , // no "vision"
126+ }
127+
128+ const parsedModel = parseOllamaModel ( modelData as any )
129+
130+ expect ( parsedModel ) . not . toBeNull ( )
131+ expect ( parsedModel ! . supportsImages ) . toBe ( true )
132+ } )
133+
134+ it ( "should detect vision via model_info keys when capabilities and families lack vision indicators" , ( ) => {
135+ const modelData = {
136+ ...ollamaModelsData [ "qwen3-2to16:latest" ] ,
137+ details : {
138+ ...ollamaModelsData [ "qwen3-2to16:latest" ] . details ,
139+ families : [ "gemma4" ] ,
140+ } ,
141+ model_info : {
142+ ...ollamaModelsData [ "qwen3-2to16:latest" ] . model_info ,
143+ "gemma4_vision_encoder.block_count" : 27 ,
144+ "gemma4_vision_encoder.embedding_length" : 1152 ,
145+ } ,
146+ capabilities : [ "completion" , "tools" ] , // no "vision"
147+ }
148+
149+ const parsedModel = parseOllamaModel ( modelData as any )
150+
151+ expect ( parsedModel ) . not . toBeNull ( )
152+ expect ( parsedModel ! . supportsImages ) . toBe ( true )
153+ } )
154+
155+ it ( "should detect vision via siglip family in details.families" , ( ) => {
156+ const modelData = {
157+ ...ollamaModelsData [ "qwen3-2to16:latest" ] ,
158+ details : {
159+ ...ollamaModelsData [ "qwen3-2to16:latest" ] . details ,
160+ families : [ "gemma4" , "siglip" ] ,
161+ } ,
162+ capabilities : [ "completion" , "tools" ] ,
163+ }
164+
165+ const parsedModel = parseOllamaModel ( modelData as any )
166+
167+ expect ( parsedModel ) . not . toBeNull ( )
168+ expect ( parsedModel ! . supportsImages ) . toBe ( true )
169+ } )
170+
171+ it ( "should detect vision via mmproj family in details.families" , ( ) => {
172+ const modelData = {
173+ ...ollamaModelsData [ "qwen3-2to16:latest" ] ,
174+ details : {
175+ ...ollamaModelsData [ "qwen3-2to16:latest" ] . details ,
176+ families : [ "llama" , "mmproj" ] ,
177+ } ,
178+ capabilities : [ "completion" , "tools" ] ,
179+ }
180+
181+ const parsedModel = parseOllamaModel ( modelData as any )
182+
183+ expect ( parsedModel ) . not . toBeNull ( )
184+ expect ( parsedModel ! . supportsImages ) . toBe ( true )
185+ } )
186+
187+ it ( "should detect vision via mllama family in details.families" , ( ) => {
188+ const modelData = {
189+ ...ollamaModelsData [ "qwen3-2to16:latest" ] ,
190+ details : {
191+ ...ollamaModelsData [ "qwen3-2to16:latest" ] . details ,
192+ families : [ "llama" , "mllama" ] ,
193+ } ,
194+ capabilities : [ "completion" , "tools" ] ,
195+ }
196+
197+ const parsedModel = parseOllamaModel ( modelData as any )
198+
199+ expect ( parsedModel ) . not . toBeNull ( )
200+ expect ( parsedModel ! . supportsImages ) . toBe ( true )
201+ } )
202+
203+ it ( "should not detect vision when no indicators are present" , ( ) => {
204+ const modelData = {
205+ ...ollamaModelsData [ "qwen3-2to16:latest" ] ,
206+ details : {
207+ ...ollamaModelsData [ "qwen3-2to16:latest" ] . details ,
208+ families : [ "qwen3" ] ,
209+ } ,
210+ capabilities : [ "completion" , "tools" ] ,
211+ }
212+
213+ const parsedModel = parseOllamaModel ( modelData as any )
214+
215+ expect ( parsedModel ) . not . toBeNull ( )
216+ expect ( parsedModel ! . supportsImages ) . toBe ( false )
217+ } )
218+
219+ it ( "should handle case-insensitive family matching for vision detection" , ( ) => {
220+ const modelData = {
221+ ...ollamaModelsData [ "qwen3-2to16:latest" ] ,
222+ details : {
223+ ...ollamaModelsData [ "qwen3-2to16:latest" ] . details ,
224+ families : [ "gemma4" , "CLIP" ] ,
225+ } ,
226+ capabilities : [ "completion" , "tools" ] ,
227+ }
228+
229+ const parsedModel = parseOllamaModel ( modelData as any )
230+
231+ expect ( parsedModel ) . not . toBeNull ( )
232+ expect ( parsedModel ! . supportsImages ) . toBe ( true )
233+ } )
117234 } )
118235
119236 describe ( "getOllamaModels" , ( ) => {
0 commit comments