mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-08-08 16:11:58 -07:00
maintain turn metadata and coalesce same roles.
This commit is contained in:
@@ -2363,6 +2363,30 @@ describe('GeminiChat', () => {
|
||||
expect(turns).toHaveLength(1);
|
||||
expect(turns[0].content.role).toBe('user');
|
||||
});
|
||||
|
||||
it('should coalesce consecutive user turns when an intermediate model turn is stripped', () => {
|
||||
vi.mocked(mockConfig.isContextManagementEnabled).mockReturnValue(false);
|
||||
vi.mocked(mockConfig.getModel).mockReturnValue('gemini-2.5-pro');
|
||||
|
||||
chat.setHistory([
|
||||
{ role: 'user', parts: [{ text: 'Question 1' }] },
|
||||
{
|
||||
role: 'model',
|
||||
parts: [{ text: 'thinking...', thought: true } as unknown as Part],
|
||||
},
|
||||
{ role: 'user', parts: [{ text: 'Question 2' }] },
|
||||
]);
|
||||
|
||||
const turns = chat.getHistoryTurns(true);
|
||||
|
||||
// The model turn contains only a thought part, so it is stripped.
|
||||
// The two adjacent user turns must be coalesced into one user turn.
|
||||
expect(turns).toHaveLength(1);
|
||||
expect(turns[0].content.role).toBe('user');
|
||||
expect(turns[0].content.parts).toHaveLength(2);
|
||||
expect(turns[0].content.parts![0].text).toBe('Question 1');
|
||||
expect(turns[0].content.parts![1].text).toBe('Question 2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ensureActiveLoopHasThoughtSignatures', () => {
|
||||
@@ -3341,5 +3365,30 @@ describe('GeminiChat', () => {
|
||||
const history: HistoryTurn[] = [{ id: '1', content: { role: 'user' } }];
|
||||
expect(stripThoughts(history)).toEqual(history);
|
||||
});
|
||||
|
||||
it('should preserve top-level metadata when stripping thoughts', () => {
|
||||
const history: HistoryTurn[] = [
|
||||
{
|
||||
id: '1',
|
||||
content: {
|
||||
role: 'model',
|
||||
parts: [
|
||||
{ text: 'internal monologue', thought: true } as unknown as Part,
|
||||
{ text: 'visible response' },
|
||||
],
|
||||
},
|
||||
// top-level turn metadata
|
||||
timestamp: '2026-07-23T00:00:00.000Z',
|
||||
metadata: { some: 'value' },
|
||||
} as unknown as HistoryTurn,
|
||||
];
|
||||
const stripped = stripThoughts(history);
|
||||
expect(stripped).toHaveLength(1);
|
||||
expect(stripped[0]).toHaveProperty(
|
||||
'timestamp',
|
||||
'2026-07-23T00:00:00.000Z',
|
||||
);
|
||||
expect(stripped[0]).toHaveProperty('metadata', { some: 'value' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -968,7 +968,7 @@ export class GeminiChat {
|
||||
|
||||
const model = this.context.config.getModel();
|
||||
if (isGemini2Model(model) || supportsModernFeatures(model)) {
|
||||
return stripThoughts(history);
|
||||
return coalesceConsecutiveRoles(stripThoughts(history));
|
||||
}
|
||||
|
||||
return history;
|
||||
@@ -1526,7 +1526,7 @@ export function stripThoughts(history: HistoryTurn[]): HistoryTurn[] {
|
||||
|
||||
const nonThoughtParts = turn.content.parts.filter((p) => p && !p.thought);
|
||||
return {
|
||||
id: turn.id,
|
||||
...turn,
|
||||
content: {
|
||||
...turn.content,
|
||||
parts: nonThoughtParts,
|
||||
|
||||
Reference in New Issue
Block a user