@@ -1857,6 +1857,185 @@ describe('LobeOpenAICompatibleFactory', () => {
18571857 } ) ;
18581858 } ) ;
18591859
1860+ describe ( 'tools parameter support' , ( ) => {
1861+ it ( 'should handle tools parameter with multiple tools' , async ( ) => {
1862+ const mockResponse = {
1863+ choices : [
1864+ {
1865+ message : {
1866+ tool_calls : [
1867+ {
1868+ type : 'function' as const ,
1869+ function : {
1870+ name : 'get_weather' ,
1871+ arguments : '{"city":"Tokyo","unit":"celsius"}' ,
1872+ } ,
1873+ } ,
1874+ {
1875+ type : 'function' as const ,
1876+ function : {
1877+ name : 'get_time' ,
1878+ arguments : '{"timezone":"Asia/Tokyo"}' ,
1879+ } ,
1880+ } ,
1881+ ] ,
1882+ } ,
1883+ } ,
1884+ ] ,
1885+ } ;
1886+
1887+ vi . spyOn ( instance [ 'client' ] . chat . completions , 'create' ) . mockResolvedValue (
1888+ mockResponse as any ,
1889+ ) ;
1890+
1891+ const payload = {
1892+ messages : [ { content : 'What is the weather and time in Tokyo?' , role : 'user' as const } ] ,
1893+ tools : [
1894+ {
1895+ name : 'get_weather' ,
1896+ description : 'Get weather information' ,
1897+ parameters : {
1898+ type : 'object' as const ,
1899+ properties : {
1900+ city : { type : 'string' } ,
1901+ unit : { type : 'string' } ,
1902+ } ,
1903+ required : [ 'city' ] ,
1904+ } ,
1905+ } ,
1906+ {
1907+ name : 'get_time' ,
1908+ description : 'Get current time' ,
1909+ parameters : {
1910+ type : 'object' as const ,
1911+ properties : {
1912+ timezone : { type : 'string' } ,
1913+ } ,
1914+ required : [ 'timezone' ] ,
1915+ } ,
1916+ } ,
1917+ ] ,
1918+ model : 'gpt-4o' ,
1919+ } ;
1920+
1921+ const result = await instance . generateObject ( payload ) ;
1922+
1923+ expect ( instance [ 'client' ] . chat . completions . create ) . toHaveBeenCalledWith (
1924+ {
1925+ messages : payload . messages ,
1926+ model : payload . model ,
1927+ tool_choice : 'required' ,
1928+ tools : [
1929+ {
1930+ type : 'function' ,
1931+ function : {
1932+ name : 'get_weather' ,
1933+ description : 'Get weather information' ,
1934+ parameters : {
1935+ type : 'object' ,
1936+ properties : {
1937+ city : { type : 'string' } ,
1938+ unit : { type : 'string' } ,
1939+ } ,
1940+ required : [ 'city' ] ,
1941+ } ,
1942+ } ,
1943+ } ,
1944+ {
1945+ type : 'function' ,
1946+ function : {
1947+ name : 'get_time' ,
1948+ description : 'Get current time' ,
1949+ parameters : {
1950+ type : 'object' ,
1951+ properties : {
1952+ timezone : { type : 'string' } ,
1953+ } ,
1954+ required : [ 'timezone' ] ,
1955+ } ,
1956+ } ,
1957+ } ,
1958+ ] ,
1959+ user : undefined ,
1960+ } ,
1961+ { headers : undefined , signal : undefined } ,
1962+ ) ;
1963+
1964+ expect ( result ) . toEqual ( [
1965+ { arguments : { city : 'Tokyo' , unit : 'celsius' } , name : 'get_weather' } ,
1966+ { arguments : { timezone : 'Asia/Tokyo' } , name : 'get_time' } ,
1967+ ] ) ;
1968+ } ) ;
1969+
1970+ it ( 'should handle tools parameter with systemRole' , async ( ) => {
1971+ const mockResponse = {
1972+ choices : [
1973+ {
1974+ message : {
1975+ tool_calls : [
1976+ {
1977+ type : 'function' as const ,
1978+ function : {
1979+ name : 'calculate' ,
1980+ arguments : '{"result":8}' ,
1981+ } ,
1982+ } ,
1983+ ] ,
1984+ } ,
1985+ } ,
1986+ ] ,
1987+ } ;
1988+
1989+ vi . spyOn ( instance [ 'client' ] . chat . completions , 'create' ) . mockResolvedValue (
1990+ mockResponse as any ,
1991+ ) ;
1992+
1993+ const payload = {
1994+ messages : [ { content : 'Add 5 and 3' , role : 'user' as const } ] ,
1995+ tools : [
1996+ {
1997+ name : 'calculate' ,
1998+ description : 'Perform calculation' ,
1999+ parameters : {
2000+ type : 'object' as const ,
2001+ properties : {
2002+ result : { type : 'number' } ,
2003+ } ,
2004+ required : [ 'result' ] ,
2005+ } ,
2006+ } ,
2007+ ] ,
2008+ systemRole : 'You are a helpful calculator' ,
2009+ model : 'gpt-4o' ,
2010+ } ;
2011+
2012+ const result = await instance . generateObject ( payload ) ;
2013+
2014+ expect ( instance [ 'client' ] . chat . completions . create ) . toHaveBeenCalledWith (
2015+ expect . objectContaining ( {
2016+ messages : [
2017+ { content : 'Add 5 and 3' , role : 'user' } ,
2018+ { content : 'You are a helpful calculator' , role : 'system' } ,
2019+ ] ,
2020+ } ) ,
2021+ expect . any ( Object ) ,
2022+ ) ;
2023+
2024+ expect ( result ) . toEqual ( [ { arguments : { result : 8 } , name : 'calculate' } ] ) ;
2025+ } ) ;
2026+
2027+ it ( 'should throw error when neither tools nor schema is provided' , async ( ) => {
2028+ const payload = {
2029+ messages : [ { content : 'Generate data' , role : 'user' as const } ] ,
2030+ model : 'gpt-4o' ,
2031+ } ;
2032+
2033+ await expect ( instance . generateObject ( payload as any ) ) . rejects . toThrow (
2034+ 'tools or schema is required' ,
2035+ ) ;
2036+ } ) ;
2037+ } ) ;
2038+
18602039 describe ( 'tool calling fallback' , ( ) => {
18612040 let instanceWithToolCalling : any ;
18622041
@@ -1930,7 +2109,9 @@ describe('LobeOpenAICompatibleFactory', () => {
19302109 { headers : undefined , signal : undefined } ,
19312110 ) ;
19322111
1933- expect ( result ) . toEqual ( { name : 'Alice' , age : 28 } ) ;
2112+ expect ( result ) . toEqual ( [
2113+ { arguments : { name : 'Alice' , age : 28 } , name : 'person_extractor' } ,
2114+ ] ) ;
19342115 } ) ;
19352116
19362117 it ( 'should return undefined when no tool call found' , async ( ) => {
@@ -1960,7 +2141,7 @@ describe('LobeOpenAICompatibleFactory', () => {
19602141
19612142 const result = await instanceWithToolCalling . generateObject ( payload ) ;
19622143
1963- expect ( consoleSpy ) . toHaveBeenCalledWith ( 'No tool call found in response' ) ;
2144+ expect ( consoleSpy ) . toHaveBeenCalledWith ( 'parse tool call arguments error:' , undefined ) ;
19642145 expect ( result ) . toBeUndefined ( ) ;
19652146
19662147 consoleSpy . mockRestore ( ) ;
@@ -2001,7 +2182,10 @@ describe('LobeOpenAICompatibleFactory', () => {
20012182
20022183 const result = await instanceWithToolCalling . generateObject ( payload ) ;
20032184
2004- expect ( consoleSpy ) . toHaveBeenCalledWith ( 'parse tool call arguments error:' , 'invalid json' ) ;
2185+ expect ( consoleSpy ) . toHaveBeenCalledWith (
2186+ 'parse tool call arguments error:' ,
2187+ mockResponse . choices [ 0 ] . message . tool_calls ,
2188+ ) ;
20052189 expect ( result ) . toBeUndefined ( ) ;
20062190
20072191 consoleSpy . mockRestore ( ) ;
@@ -2052,7 +2236,7 @@ describe('LobeOpenAICompatibleFactory', () => {
20522236 { headers : options . headers , signal : options . signal } ,
20532237 ) ;
20542238
2055- expect ( result ) . toEqual ( { data : 'test' } ) ;
2239+ expect ( result ) . toEqual ( [ { arguments : { data : 'test' } , name : 'data_extractor' } ] ) ;
20562240 } ) ;
20572241 } ) ;
20582242 } ) ;
0 commit comments