feat(cli): overhaul thinking UI (#18725)

This commit is contained in:
Keith Guerin
2026-03-06 20:20:27 -08:00
committed by GitHub
parent 9455ecd78c
commit e5d58c2b5a
29 changed files with 763 additions and 184 deletions
@@ -33,6 +33,43 @@ describe('convertSessionToClientHistory', () => {
]);
});
it('should convert thinking tokens (thoughts) to model parts', () => {
const messages: ConversationRecord['messages'] = [
{
id: '1',
type: 'user',
timestamp: '2024-01-01T10:00:00Z',
content: 'Hello',
},
{
id: '2',
type: 'gemini',
timestamp: '2024-01-01T10:01:00Z',
content: 'Hi there',
thoughts: [
{
subject: 'Thinking',
description: 'I should be polite.',
timestamp: '2024-01-01T10:00:50Z',
},
],
},
];
const history = convertSessionToClientHistory(messages);
expect(history).toEqual([
{ role: 'user', parts: [{ text: 'Hello' }] },
{
role: 'model',
parts: [
{ text: '**Thinking** I should be polite.', thought: true },
{ text: 'Hi there' },
],
},
]);
});
it('should ignore info, error, and slash commands', () => {
const messages: ConversationRecord['messages'] = [
{
+22 -13
View File
@@ -51,15 +51,24 @@ export function convertSessionToClientHistory(
parts: ensurePartArray(msg.content),
});
} else if (msg.type === 'gemini') {
const modelParts: Part[] = [];
// Add thoughts if present
if (msg.thoughts && msg.thoughts.length > 0) {
for (const thought of msg.thoughts) {
const thoughtText = thought.subject
? `**${thought.subject}** ${thought.description}`
: thought.description;
modelParts.push({
text: thoughtText,
thought: true,
} as Part);
}
}
const hasToolCalls = msg.toolCalls && msg.toolCalls.length > 0;
if (hasToolCalls) {
const modelParts: Part[] = [];
// TODO: Revisit if we should preserve more than just Part metadata (e.g. thoughtSignatures)
// currently those are only required within an active loop turn which resume clears
// by forcing a new user text prompt.
// Preserve original parts to maintain multimodal integrity
if (msg.content) {
modelParts.push(...ensurePartArray(msg.content));
@@ -114,14 +123,14 @@ export function convertSessionToClientHistory(
}
} else {
if (msg.content) {
const parts = ensurePartArray(msg.content);
modelParts.push(...ensurePartArray(msg.content));
}
if (parts.length > 0) {
clientHistory.push({
role: 'model',
parts,
});
}
if (modelParts.length > 0) {
clientHistory.push({
role: 'model',
parts: modelParts,
});
}
}
}