@@ -5,7 +5,7 @@ import { providersTraceEnrichmentMock } from '@sim/testing/mocks/providers-trace
55import { beforeEach , describe , expect , it , vi } from 'vitest'
66import type { StreamingExecution } from '@/executor/types'
77import { nebiusProvider } from '@/providers/nebius'
8- import type { ProviderResponse } from '@/providers/types'
8+ import type { ProviderResponse , ProviderToolConfig } from '@/providers/types'
99
1010vi . mock ( '@/providers' , ( ) => providersMock )
1111vi . mock ( '@/providers/trace-enrichment' , ( ) => providersTraceEnrichmentMock )
@@ -90,6 +90,50 @@ describe('Nebius Chat Completions wire contract', () => {
9090 } )
9191 } )
9292
93+ it . each ( [
94+ { model : 'nebius/deepseek-ai/DeepSeek-V4.1-Flash' , forced : false } ,
95+ { model : 'nebius/openbmb/MiniCPM-V-4_5' , forced : false } ,
96+ { model : 'nebius/openbmb/minicpm-v-4_5' , forced : false } ,
97+ { model : MODEL , forced : true } ,
98+ ] ) ( 'honors the forced-tool wire contract for $model' , async ( scenario ) => {
99+ const tools : ProviderToolConfig [ ] = [
100+ {
101+ id : 'http_request' ,
102+ description : 'Fetch a URL' ,
103+ params : { } ,
104+ parameters : { type : 'object' , properties : { } , required : [ ] } ,
105+ usageControl : 'force' ,
106+ } ,
107+ {
108+ id : 'disabled_tool' ,
109+ description : 'Disabled tool' ,
110+ params : { } ,
111+ parameters : { type : 'object' , properties : { } , required : [ ] } ,
112+ usageControl : 'none' ,
113+ } ,
114+ ]
115+ const payloads : Array < {
116+ tool_choice : unknown
117+ tools : Array < { function : { name : string } } >
118+ } > = [ ]
119+ vi . mocked ( fetch ) . mockImplementationOnce ( async ( _url , init ) => {
120+ payloads . push ( JSON . parse ( String ( init ?. body ) ) )
121+ return jsonResponse ( completion ( '42' ) )
122+ } )
123+ const result = ( await nebiusProvider . executeRequest ( {
124+ ...REQUEST ,
125+ model : scenario . model ,
126+ tools,
127+ } ) ) as ProviderResponse
128+ expect ( payloads [ 0 ] ?. tool_choice ) . toEqual (
129+ scenario . forced ? { type : 'function' , function : { name : 'http_request' } } : 'auto'
130+ )
131+ expect ( payloads [ 0 ] ?. tools . map ( ( tool ) => tool . function . name ) ) . toEqual ( [ 'http_request' ] )
132+ expect ( result . content ) . toBe ( '42' )
133+ expect ( tools [ 0 ] . usageControl ) . toBe ( 'force' )
134+ expect ( tools [ 1 ] . usageControl ) . toBe ( 'none' )
135+ } )
136+
93137 it ( 'decodes SSE reasoning and usage while retaining Nebius pricing' , async ( ) => {
94138 vi . mocked ( fetch ) . mockImplementationOnce ( async ( _url , init ) => {
95139 const payload = JSON . parse ( String ( init ?. body ) )
0 commit comments