@@ -5,19 +5,30 @@ import {
55 removeYamlFrontMatter ,
66 extractModelName ,
77 extractModelRepo ,
8+ getModelCapabilities ,
89} from '../models'
10+ import { ModelCapabilities } from '@/types/models'
911
1012// Mock the token.js module
1113vi . mock ( 'token.js' , ( ) => ( {
1214 models : {
1315 openai : {
1416 models : [ 'gpt-3.5-turbo' , 'gpt-4' ] ,
17+ supportsToolCalls : [ 'gpt-3.5-turbo' , 'gpt-4' ] ,
18+ supportsImages : [ 'gpt-4-vision-preview' ] ,
1519 } ,
1620 anthropic : {
1721 models : [ 'claude-3-sonnet' , 'claude-3-haiku' ] ,
22+ supportsToolCalls : [ 'claude-3-sonnet' ] ,
23+ supportsImages : [ 'claude-3-sonnet' , 'claude-3-haiku' ] ,
1824 } ,
1925 mistral : {
2026 models : [ 'mistral-7b' , 'mistral-8x7b' ] ,
27+ supportsToolCalls : [ 'mistral-8x7b' ] ,
28+ } ,
29+ // Provider with no capability arrays
30+ cohere : {
31+ models : [ 'command' , 'command-light' ] ,
2132 } ,
2233 } ,
2334} ) )
@@ -223,3 +234,74 @@ describe('extractModelRepo', () => {
223234 )
224235 } )
225236} )
237+
238+ describe ( 'getModelCapabilities' , ( ) => {
239+ it ( 'returns completion capability for all models' , ( ) => {
240+ const capabilities = getModelCapabilities ( 'openai' , 'gpt-3.5-turbo' )
241+ expect ( capabilities ) . toContain ( ModelCapabilities . COMPLETION )
242+ } )
243+
244+ it ( 'includes tools capability when model supports it' , ( ) => {
245+ const capabilities = getModelCapabilities ( 'openai' , 'gpt-3.5-turbo' )
246+ expect ( capabilities ) . toContain ( ModelCapabilities . TOOLS )
247+ expect ( capabilities ) . toContain ( ModelCapabilities . COMPLETION )
248+ } )
249+
250+ it ( 'excludes tools capability when model does not support it' , ( ) => {
251+ const capabilities = getModelCapabilities ( 'mistral' , 'mistral-7b' )
252+ expect ( capabilities ) . not . toContain ( ModelCapabilities . TOOLS )
253+ expect ( capabilities ) . toContain ( ModelCapabilities . COMPLETION )
254+ } )
255+
256+ it ( 'includes vision capability when model supports it' , ( ) => {
257+ const capabilities = getModelCapabilities ( 'openai' , 'gpt-4-vision-preview' )
258+ expect ( capabilities ) . toContain ( ModelCapabilities . VISION )
259+ expect ( capabilities ) . toContain ( ModelCapabilities . COMPLETION )
260+ } )
261+
262+ it ( 'excludes vision capability when model does not support it' , ( ) => {
263+ const capabilities = getModelCapabilities ( 'openai' , 'gpt-3.5-turbo' )
264+ expect ( capabilities ) . not . toContain ( ModelCapabilities . VISION )
265+ } )
266+
267+ it ( 'includes both tools and vision when model supports both' , ( ) => {
268+ const capabilities = getModelCapabilities ( 'anthropic' , 'claude-3-sonnet' )
269+ expect ( capabilities ) . toContain ( ModelCapabilities . COMPLETION )
270+ expect ( capabilities ) . toContain ( ModelCapabilities . TOOLS )
271+ expect ( capabilities ) . toContain ( ModelCapabilities . VISION )
272+ } )
273+
274+ it ( 'handles provider with no capability arrays gracefully' , ( ) => {
275+ const capabilities = getModelCapabilities ( 'cohere' , 'command' )
276+ expect ( capabilities ) . toEqual ( [ ModelCapabilities . COMPLETION ] )
277+ expect ( capabilities ) . not . toContain ( ModelCapabilities . TOOLS )
278+ expect ( capabilities ) . not . toContain ( ModelCapabilities . VISION )
279+ } )
280+
281+ it ( 'handles unknown provider gracefully' , ( ) => {
282+ const capabilities = getModelCapabilities ( 'openrouter' , 'some-model' )
283+ expect ( capabilities ) . toEqual ( [ ModelCapabilities . COMPLETION ] )
284+ expect ( capabilities ) . not . toContain ( ModelCapabilities . TOOLS )
285+ expect ( capabilities ) . not . toContain ( ModelCapabilities . VISION )
286+ } )
287+
288+ it ( 'handles model not in capability list' , ( ) => {
289+ const capabilities = getModelCapabilities ( 'anthropic' , 'claude-3-haiku' )
290+ expect ( capabilities ) . toContain ( ModelCapabilities . COMPLETION )
291+ expect ( capabilities ) . toContain ( ModelCapabilities . VISION )
292+ expect ( capabilities ) . not . toContain ( ModelCapabilities . TOOLS )
293+ } )
294+
295+ it ( 'returns only completion for provider with partial capability data' , ( ) => {
296+ // Mistral has supportsToolCalls but no supportsImages
297+ const capabilities = getModelCapabilities ( 'mistral' , 'mistral-7b' )
298+ expect ( capabilities ) . toEqual ( [ ModelCapabilities . COMPLETION ] )
299+ } )
300+
301+ it ( 'handles model that supports tools but not vision' , ( ) => {
302+ const capabilities = getModelCapabilities ( 'mistral' , 'mistral-8x7b' )
303+ expect ( capabilities ) . toContain ( ModelCapabilities . COMPLETION )
304+ expect ( capabilities ) . toContain ( ModelCapabilities . TOOLS )
305+ expect ( capabilities ) . not . toContain ( ModelCapabilities . VISION )
306+ } )
307+ } )
0 commit comments