mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-06-16 14:27:24 -07:00
67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2026 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import type { Content } from '@google/genai';
|
|
import type { ConcreteNode } from './types.js';
|
|
import { debugLogger } from '../../utils/debugLogger.js';
|
|
import type { NodeIdService } from './nodeIdService.js';
|
|
import type { HistoryTurn } from '../../core/agentChatHistory.js';
|
|
|
|
/**
|
|
* Reconstructs a list of HistoryTurns from a list of Concrete Nodes.
|
|
* This process is "role-alternation-aware" and uses turnId to
|
|
* preserve original turn boundaries and IDs.
|
|
*/
|
|
export function fromGraph(
|
|
nodes: readonly ConcreteNode[],
|
|
idService?: NodeIdService,
|
|
): HistoryTurn[] {
|
|
debugLogger.log(
|
|
`[fromGraph] Reconstructing history from ${nodes.length} nodes`,
|
|
);
|
|
|
|
const history: HistoryTurn[] = [];
|
|
let currentTurn: { id: string; content: Content } | null = null;
|
|
|
|
for (const node of nodes) {
|
|
const turnId = node.turnId || 'orphan'; debugLogger.log("[ID-TRACK] fromGraph converting node:", node.id, "turnId:", turnId);
|
|
const durableId = turnId.startsWith('turn_') ? turnId.slice(5) : turnId;
|
|
|
|
// Register the payload in the identity service to ensure stability
|
|
// even if the turn content changes (e.g. after GC backstop).
|
|
if (idService) {
|
|
idService.set(node.payload, node.id);
|
|
}
|
|
|
|
// We start a new turn if:
|
|
// 1. We don't have a current turn.
|
|
// 2. The role changes (Standard alternation).
|
|
// 3. The turnId changes (Preserving distinct turns of the same role).
|
|
if (
|
|
!currentTurn ||
|
|
currentTurn.content.role !== node.role ||
|
|
currentTurn.id !== durableId
|
|
) {
|
|
currentTurn = {
|
|
id: durableId,
|
|
content: {
|
|
role: node.role,
|
|
parts: [node.payload],
|
|
},
|
|
};
|
|
history.push(currentTurn);
|
|
} else {
|
|
currentTurn.content.parts = [
|
|
...(currentTurn.content.parts || []),
|
|
node.payload,
|
|
];
|
|
}
|
|
}
|
|
|
|
debugLogger.log(`[fromGraph] Reconstructed ${history.length} turns`);
|
|
return history;
|
|
}
|