Skip to content

Commit 6b9b778

Browse files
fix: resolve "function response turn must come immediately after function call" error (google-gemini#26691)
Co-authored-by: Tommaso Sciortino <[email protected]>
1 parent f86e0ee commit 6b9b778

2 files changed

Lines changed: 76 additions & 1 deletion

File tree

‎packages/core/src/core/geminiChat.test.ts‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,4 +2796,71 @@ describe('GeminiChat', () => {
27962796
]);
27972797
});
27982798
});
2799+
2800+
describe('getHistory with curated: true', () => {
2801+
it('should not drop model turns with function calls and empty text', () => {
2802+
const history: Content[] = [
2803+
{ role: 'user', parts: [{ text: 'Hello' }] },
2804+
{
2805+
role: 'model',
2806+
parts: [{ functionCall: { name: 'test_tool', args: {} }, text: '' }],
2807+
},
2808+
{
2809+
role: 'user',
2810+
parts: [{ functionResponse: { name: 'test_tool', response: {} } }],
2811+
},
2812+
];
2813+
const chatWithHistory = new GeminiChat(mockConfig, '', [], history);
2814+
2815+
const curatedHistory = chatWithHistory.getHistory(true);
2816+
2817+
expect(curatedHistory.length).toBe(3);
2818+
expect(curatedHistory[1].role).toBe('model');
2819+
expect(curatedHistory[1].parts![0].functionCall).toBeDefined();
2820+
});
2821+
2822+
it('should not drop model turns with inlineData and empty text', () => {
2823+
const history: Content[] = [
2824+
{ role: 'user', parts: [{ text: 'Hello' }] },
2825+
{
2826+
role: 'model',
2827+
parts: [
2828+
{
2829+
inlineData: { mimeType: 'image/jpeg', data: 'base64...' },
2830+
text: '',
2831+
},
2832+
],
2833+
},
2834+
];
2835+
const chatWithHistory = new GeminiChat(mockConfig, '', [], history);
2836+
2837+
const curatedHistory = chatWithHistory.getHistory(true);
2838+
2839+
expect(curatedHistory.length).toBe(2);
2840+
expect(curatedHistory[1].role).toBe('model');
2841+
expect(curatedHistory[1].parts![0].inlineData).toBeDefined();
2842+
});
2843+
2844+
it('should not drop model turns with fileData and empty text', () => {
2845+
const history: Content[] = [
2846+
{ role: 'user', parts: [{ text: 'Hello' }] },
2847+
{
2848+
role: 'model',
2849+
parts: [
2850+
{
2851+
fileData: { mimeType: 'image/jpeg', fileUri: 'https://...' },
2852+
text: '',
2853+
},
2854+
],
2855+
},
2856+
];
2857+
const chatWithHistory = new GeminiChat(mockConfig, '', [], history);
2858+
2859+
const curatedHistory = chatWithHistory.getHistory(true);
2860+
2861+
expect(curatedHistory.length).toBe(2);
2862+
expect(curatedHistory[1].role).toBe('model');
2863+
expect(curatedHistory[1].parts![0].fileData).toBeDefined();
2864+
});
2865+
});
27992866
});

‎packages/core/src/core/geminiChat.ts‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,15 @@ function isValidContent(content: Content): boolean {
146146
if (part === undefined || Object.keys(part).length === 0) {
147147
return false;
148148
}
149-
if (!part.thought && part.text !== undefined && part.text === '') {
149+
if (
150+
!part.thought &&
151+
!part.functionCall &&
152+
!part.functionResponse &&
153+
!part.inlineData &&
154+
!part.fileData &&
155+
part.text !== undefined &&
156+
part.text === ''
157+
) {
150158
return false;
151159
}
152160
}

0 commit comments

Comments
 (0)