mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-27 22:54:59 +00:00
feat: foundation for subagent trajectories (Stage 1)
This commit is contained in:
@@ -194,12 +194,7 @@ describe('chatCommand', () => {
|
||||
]);
|
||||
result = await saveCommand?.action?.(mockContext, tag);
|
||||
expect(mockSaveCheckpoint).toHaveBeenCalledWith(
|
||||
{
|
||||
history: expect.any(Array),
|
||||
authType: AuthType.LOGIN_WITH_GOOGLE,
|
||||
trajectories: {},
|
||||
messages: [],
|
||||
},
|
||||
{ history: expect.any(Array), authType: AuthType.LOGIN_WITH_GOOGLE },
|
||||
tag,
|
||||
);
|
||||
expect(result).toEqual({
|
||||
@@ -241,12 +236,7 @@ describe('chatCommand', () => {
|
||||
|
||||
expect(mockCheckpointExists).not.toHaveBeenCalled(); // Should skip existence check
|
||||
expect(mockSaveCheckpoint).toHaveBeenCalledWith(
|
||||
{
|
||||
history,
|
||||
authType: AuthType.LOGIN_WITH_GOOGLE,
|
||||
trajectories: {},
|
||||
messages: [],
|
||||
},
|
||||
{ history, authType: AuthType.LOGIN_WITH_GOOGLE },
|
||||
tag,
|
||||
);
|
||||
expect(result).toEqual({
|
||||
@@ -483,10 +473,8 @@ describe('chatCommand', () => {
|
||||
'gemini-conversation-1234567890.json',
|
||||
);
|
||||
expect(mockExport).toHaveBeenCalledWith({
|
||||
messages: [],
|
||||
filePath: expectedPath,
|
||||
trajectories: {},
|
||||
history: mockHistory,
|
||||
filePath: expectedPath,
|
||||
});
|
||||
expect(result).toEqual({
|
||||
type: 'message',
|
||||
@@ -500,10 +488,8 @@ describe('chatCommand', () => {
|
||||
const result = await shareCommand?.action?.(mockContext, filePath);
|
||||
const expectedPath = path.join(process.cwd(), 'my-chat.json');
|
||||
expect(mockExport).toHaveBeenCalledWith({
|
||||
messages: [],
|
||||
filePath: expectedPath,
|
||||
trajectories: {},
|
||||
history: mockHistory,
|
||||
filePath: expectedPath,
|
||||
});
|
||||
expect(result).toEqual({
|
||||
type: 'message',
|
||||
@@ -517,10 +503,8 @@ describe('chatCommand', () => {
|
||||
const result = await shareCommand?.action?.(mockContext, filePath);
|
||||
const expectedPath = path.join(process.cwd(), 'my-chat.md');
|
||||
expect(mockExport).toHaveBeenCalledWith({
|
||||
messages: [],
|
||||
filePath: expectedPath,
|
||||
trajectories: {},
|
||||
history: mockHistory,
|
||||
filePath: expectedPath,
|
||||
});
|
||||
expect(result).toEqual({
|
||||
type: 'message',
|
||||
@@ -569,10 +553,8 @@ describe('chatCommand', () => {
|
||||
await shareCommand?.action?.(mockContext, filePath);
|
||||
const expectedPath = path.join(process.cwd(), 'my-chat.json');
|
||||
expect(mockExport).toHaveBeenCalledWith({
|
||||
messages: [],
|
||||
filePath: expectedPath,
|
||||
trajectories: {},
|
||||
history: mockHistory,
|
||||
filePath: expectedPath,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -581,10 +563,8 @@ describe('chatCommand', () => {
|
||||
await shareCommand?.action?.(mockContext, filePath);
|
||||
const expectedPath = path.join(process.cwd(), 'my-chat.md');
|
||||
expect(mockExport).toHaveBeenCalledWith({
|
||||
messages: [],
|
||||
filePath: expectedPath,
|
||||
trajectories: {},
|
||||
history: mockHistory,
|
||||
filePath: expectedPath,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -57,10 +57,18 @@ export function serializeHistoryToMarkdown(
|
||||
*/
|
||||
export interface ExportHistoryOptions {
|
||||
/**
|
||||
<<<<<<< HEAD
|
||||
* Optional full message records which contain metadata like agentId for tool calls,
|
||||
* providing the link between history and trajectories.
|
||||
*/
|
||||
messages?: MessageRecord[];
|
||||
=======
|
||||
* Full message records which contain metadata like agentId for tool calls,
|
||||
* providing the link between history and trajectories.
|
||||
* This is the primary source of truth.
|
||||
*/
|
||||
messages: MessageRecord[];
|
||||
>>>>>>> 0e381108e (feat: foundation for subagent trajectories (Stage 1))
|
||||
/** The file path to export to. */
|
||||
filePath: string;
|
||||
/** Optional subagent trajectories to include. */
|
||||
@@ -81,18 +89,38 @@ export async function exportHistoryToFile(
|
||||
const {
|
||||
messages,
|
||||
filePath,
|
||||
<<<<<<< HEAD
|
||||
trajectories: _trajectories, // Collected but not yet included in Stage 1 JSON output
|
||||
=======
|
||||
trajectories,
|
||||
>>>>>>> 0e381108e (feat: foundation for subagent trajectories (Stage 1))
|
||||
history: providedHistory,
|
||||
} = options;
|
||||
const extension = path.extname(filePath).toLowerCase();
|
||||
|
||||
let content: string;
|
||||
if (extension === '.json') {
|
||||
<<<<<<< HEAD
|
||||
// Stage 1 & 2: Maintain legacy behavior - only export the raw history array.
|
||||
// Trajectories and messages are collected but not yet included in Stage 2 JSON output.
|
||||
content = JSON.stringify(providedHistory ?? [], null, 2);
|
||||
} else if (extension === '.md') {
|
||||
const history = providedHistory ?? reconstructHistory(messages ?? []);
|
||||
=======
|
||||
// In Stage 1, we still save the raw history if provided, for backward compatibility
|
||||
// with existing parsers, but we also include messages and trajectories.
|
||||
if (trajectories && Object.keys(trajectories).length > 0) {
|
||||
content = JSON.stringify(
|
||||
{ history: providedHistory, messages, trajectories },
|
||||
null,
|
||||
2,
|
||||
);
|
||||
} else {
|
||||
content = JSON.stringify(providedHistory ?? messages, null, 2);
|
||||
}
|
||||
} else if (extension === '.md') {
|
||||
const history = providedHistory ?? reconstructHistory(messages);
|
||||
>>>>>>> 0e381108e (feat: foundation for subagent trajectories (Stage 1))
|
||||
content = serializeHistoryToMarkdown(history);
|
||||
} else {
|
||||
throw new Error(
|
||||
|
||||
Reference in New Issue
Block a user