Skip to content

Commit 15ddede

Browse files
committed
fix tests
1 parent 76a620b commit 15ddede

File tree

2 files changed

+371
-33
lines changed

2 files changed

+371
-33
lines changed

packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts

Lines changed: 188 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)