mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-06-25 18:56:48 -07:00
Add Claude Vertex content generator
This commit is contained in:
@@ -1043,6 +1043,72 @@ describe('convertSessionToHistoryFormats', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not render inline thought parts as message text', () => {
|
||||
const messages: MessageRecord[] = [
|
||||
{
|
||||
id: '1',
|
||||
timestamp: new Date().toISOString(),
|
||||
type: 'gemini',
|
||||
content: [
|
||||
{ text: '**Planning** I should inspect the files.', thought: true },
|
||||
{ text: 'I found the issue.' },
|
||||
],
|
||||
thoughts: [
|
||||
{
|
||||
subject: 'Planning',
|
||||
description: 'I should inspect the files.',
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const result = convertSessionToHistoryFormats(messages);
|
||||
|
||||
expect(result.uiHistory).toHaveLength(2);
|
||||
expect(result.uiHistory[0]).toEqual({
|
||||
type: 'thinking',
|
||||
thought: {
|
||||
subject: 'Planning',
|
||||
description: 'I should inspect the files.',
|
||||
},
|
||||
});
|
||||
expect(result.uiHistory[1]).toEqual({
|
||||
type: 'gemini',
|
||||
text: 'I found the issue.',
|
||||
});
|
||||
expect(JSON.stringify(result.uiHistory)).not.toContain('[Thought: true]');
|
||||
});
|
||||
|
||||
it('should convert inline thought parts to thinking items without metadata', () => {
|
||||
const messages: MessageRecord[] = [
|
||||
{
|
||||
id: '1',
|
||||
timestamp: new Date().toISOString(),
|
||||
type: 'gemini',
|
||||
content: [
|
||||
{ text: '**Planning** I should inspect the files.', thought: true },
|
||||
{ text: 'I found the issue.' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const result = convertSessionToHistoryFormats(messages);
|
||||
|
||||
expect(result.uiHistory).toHaveLength(2);
|
||||
expect(result.uiHistory[0]).toEqual({
|
||||
type: 'thinking',
|
||||
thought: {
|
||||
subject: 'Planning',
|
||||
description: 'I should inspect the files.',
|
||||
},
|
||||
});
|
||||
expect(result.uiHistory[1]).toEqual({
|
||||
type: 'gemini',
|
||||
text: 'I found the issue.',
|
||||
});
|
||||
});
|
||||
|
||||
it('should filter out <session_context> from UI history', () => {
|
||||
const messages: MessageRecord[] = [
|
||||
{
|
||||
|
||||
@@ -7,13 +7,16 @@
|
||||
import {
|
||||
checkExhaustive,
|
||||
partListUnionToString,
|
||||
parseThought,
|
||||
SESSION_FILE_PREFIX,
|
||||
CoreToolCallStatus,
|
||||
type Storage,
|
||||
type ConversationRecord,
|
||||
type MessageRecord,
|
||||
type ThoughtSummary,
|
||||
loadConversationRecord,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { type Part, type PartListUnion } from '@google/genai';
|
||||
import * as fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { stripUnsafeCharacters } from '../ui/utils/textUtils.js';
|
||||
@@ -139,6 +142,58 @@ export interface SessionSelectionResult {
|
||||
displayInfo: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a session has at least one user or assistant (gemini) message.
|
||||
* Sessions with only system messages (info, error, warning) are considered empty.
|
||||
* @param messages - The array of message records to check
|
||||
* @returns true if the session has meaningful content
|
||||
*/
|
||||
export const hasUserOrAssistantMessage = (messages: MessageRecord[]): boolean =>
|
||||
messages.some((msg) => msg.type === 'user' || msg.type === 'gemini');
|
||||
|
||||
function ensurePartArray(content: PartListUnion): Part[] {
|
||||
if (Array.isArray(content)) {
|
||||
return content.map((part) =>
|
||||
typeof part === 'string' ? { text: part } : part,
|
||||
);
|
||||
}
|
||||
if (typeof content === 'string') {
|
||||
return [{ text: content }];
|
||||
}
|
||||
return [content];
|
||||
}
|
||||
|
||||
function inlineThoughtText(part: Part): string | undefined {
|
||||
const thoughtValue = (part as { thought?: unknown }).thought;
|
||||
if (!thoughtValue) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof part.text === 'string' && part.text.trim()) {
|
||||
return part.text;
|
||||
}
|
||||
if (typeof thoughtValue === 'string' && thoughtValue.trim()) {
|
||||
return thoughtValue;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function inlineThoughtSummaries(content: PartListUnion): ThoughtSummary[] {
|
||||
return ensurePartArray(content)
|
||||
.map(inlineThoughtText)
|
||||
.filter((text): text is string => text !== undefined)
|
||||
.map(parseThought);
|
||||
}
|
||||
|
||||
function visibleContentString(content: PartListUnion): string {
|
||||
const visibleParts = ensurePartArray(content).filter(
|
||||
(part) => !(part as { thought?: unknown }).thought,
|
||||
);
|
||||
if (visibleParts.length === 0) {
|
||||
return '';
|
||||
}
|
||||
return partListUnionToString(visibleParts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans and sanitizes message content for display by:
|
||||
* - Converting newlines to spaces
|
||||
@@ -579,9 +634,13 @@ export function convertSessionToHistoryFormats(
|
||||
const uiHistory: HistoryItemWithoutId[] = [];
|
||||
|
||||
for (const msg of messages) {
|
||||
// Add thoughts if present
|
||||
if (msg.type === 'gemini' && msg.thoughts && msg.thoughts.length > 0) {
|
||||
for (const thought of msg.thoughts) {
|
||||
if (msg.type === 'gemini') {
|
||||
const thoughts =
|
||||
msg.thoughts && msg.thoughts.length > 0
|
||||
? msg.thoughts
|
||||
: inlineThoughtSummaries(msg.content);
|
||||
|
||||
for (const thought of thoughts) {
|
||||
uiHistory.push({
|
||||
type: 'thinking',
|
||||
thought: {
|
||||
@@ -594,9 +653,9 @@ export function convertSessionToHistoryFormats(
|
||||
|
||||
// Add the message only if it has content
|
||||
const displayContentString = msg.displayContent
|
||||
? partListUnionToString(msg.displayContent)
|
||||
? visibleContentString(msg.displayContent)
|
||||
: undefined;
|
||||
const contentString = partListUnionToString(msg.content);
|
||||
const contentString = visibleContentString(msg.content);
|
||||
const uiText = displayContentString || contentString;
|
||||
|
||||
// Skip internal context messages in the UI history
|
||||
|
||||
Reference in New Issue
Block a user