@@ -1308,6 +1308,83 @@ func TestAnthropicToolChoiceParallelDisabled(t *testing.T) {
13081308 }
13091309}
13101310
1311+ // TestChatCompletionsParallelToolCallsDisabled verifies that parallel_tool_calls
1312+ // is set to false only when injectable MCP tools are present and the request
1313+ // includes tools.
1314+ func TestChatCompletionsParallelToolCallsDisabled (t * testing.T ) {
1315+ t .Parallel ()
1316+
1317+ cases := []struct {
1318+ name string
1319+ streaming bool
1320+ withInjectedTools bool
1321+ expectParallelToolCalls bool
1322+ }{
1323+ // Streaming with injected tools: parallel_tool_calls should be forced false.
1324+ {
1325+ name : "streaming/with_injected_tools" ,
1326+ streaming : true ,
1327+ withInjectedTools : true ,
1328+ expectParallelToolCalls : false ,
1329+ },
1330+ // Streaming without injected tools: parallel_tool_calls preserved.
1331+ {
1332+ name : "streaming/no_injected_tools" ,
1333+ streaming : true ,
1334+ withInjectedTools : false ,
1335+ expectParallelToolCalls : true ,
1336+ },
1337+ // Blocking with injected tools: parallel_tool_calls should be forced false.
1338+ {
1339+ name : "blocking/with_injected_tools" ,
1340+ streaming : false ,
1341+ withInjectedTools : true ,
1342+ expectParallelToolCalls : false ,
1343+ },
1344+ {
1345+ name : "blocking/no_injected_tools" ,
1346+ streaming : false ,
1347+ withInjectedTools : false ,
1348+ expectParallelToolCalls : true ,
1349+ },
1350+ }
1351+
1352+ for _ , tc := range cases {
1353+ t .Run (tc .name , func (t * testing.T ) {
1354+ t .Parallel ()
1355+
1356+ ctx , cancel := context .WithTimeout (t .Context (), time .Second * 30 )
1357+ t .Cleanup (cancel )
1358+
1359+ fix := fixtures .Parse (t , fixtures .OaiChatSingleBuiltinTool )
1360+ upstream := newMockUpstream (t , ctx , newFixtureResponse (fix ))
1361+
1362+ var opts []bridgeOption
1363+ if tc .withInjectedTools {
1364+ opts = append (opts , withMCP (setupMCPForTest (t , defaultTracer )))
1365+ }
1366+ bridgeServer := newBridgeTestServer (t , ctx , upstream .URL , opts ... )
1367+
1368+ reqBody , err := sjson .SetBytes (fix .Request (), "stream" , tc .streaming )
1369+ require .NoError (t , err )
1370+
1371+ resp := bridgeServer .makeRequest (t , http .MethodPost , pathOpenAIChatCompletions , reqBody )
1372+ _ , err = io .ReadAll (resp .Body )
1373+ require .NoError (t , err )
1374+
1375+ received := upstream .receivedRequests ()
1376+ require .Len (t , received , 1 )
1377+
1378+ var upstreamReq map [string ]any
1379+ require .NoError (t , json .Unmarshal (received [0 ].Body , & upstreamReq ))
1380+
1381+ ptc , ok := upstreamReq ["parallel_tool_calls" ].(bool )
1382+ require .True (t , ok , "parallel_tool_calls should be present in upstream request" )
1383+ assert .Equal (t , tc .expectParallelToolCalls , ptc )
1384+ })
1385+ }
1386+ }
1387+
13111388func TestThinkingAdaptiveIsPreserved (t * testing.T ) {
13121389 t .Parallel ()
13131390
0 commit comments