fix: resolve "function response turn must come immediately after function call" error (#26691)

Co-authored-by: Tommaso Sciortino <sciortino@gmail.com>
This commit is contained in:
Daniel Weis
2026-05-08 15:01:24 -04:00
committed by GitHub
parent f86e0ee418
commit 6b9b778d82
2 changed files with 76 additions and 1 deletions
+67
View File
@@ -2796,4 +2796,71 @@ describe('GeminiChat', () => {
]);
});
});
describe('getHistory with curated: true', () => {
it('should not drop model turns with function calls and empty text', () => {
const history: Content[] = [
{ role: 'user', parts: [{ text: 'Hello' }] },
{
role: 'model',
parts: [{ functionCall: { name: 'test_tool', args: {} }, text: '' }],
},
{
role: 'user',
parts: [{ functionResponse: { name: 'test_tool', response: {} } }],
},
];
const chatWithHistory = new GeminiChat(mockConfig, '', [], history);
const curatedHistory = chatWithHistory.getHistory(true);
expect(curatedHistory.length).toBe(3);
expect(curatedHistory[1].role).toBe('model');
expect(curatedHistory[1].parts![0].functionCall).toBeDefined();
});
it('should not drop model turns with inlineData and empty text', () => {
const history: Content[] = [
{ role: 'user', parts: [{ text: 'Hello' }] },
{
role: 'model',
parts: [
{
inlineData: { mimeType: 'image/jpeg', data: 'base64...' },
text: '',
},
],
},
];
const chatWithHistory = new GeminiChat(mockConfig, '', [], history);
const curatedHistory = chatWithHistory.getHistory(true);
expect(curatedHistory.length).toBe(2);
expect(curatedHistory[1].role).toBe('model');
expect(curatedHistory[1].parts![0].inlineData).toBeDefined();
});
it('should not drop model turns with fileData and empty text', () => {
const history: Content[] = [
{ role: 'user', parts: [{ text: 'Hello' }] },
{
role: 'model',
parts: [
{
fileData: { mimeType: 'image/jpeg', fileUri: 'https://...' },
text: '',
},
],
},
];
const chatWithHistory = new GeminiChat(mockConfig, '', [], history);
const curatedHistory = chatWithHistory.getHistory(true);
expect(curatedHistory.length).toBe(2);
expect(curatedHistory[1].role).toBe('model');
expect(curatedHistory[1].parts![0].fileData).toBeDefined();
});
});
});
+9 -1
View File
@@ -146,7 +146,15 @@ function isValidContent(content: Content): boolean {
if (part === undefined || Object.keys(part).length === 0) {
return false;
}
if (!part.thought && part.text !== undefined && part.text === '') {
if (
!part.thought &&
!part.functionCall &&
!part.functionResponse &&
!part.inlineData &&
!part.fileData &&
part.text !== undefined &&
part.text === ''
) {
return false;
}
}