feat(core): remove history pruning to restore agent memory and improve efficiency

Analysis of Experiment 2 vs 3 showed that pruning grep_search results
caused the agent to lose context and enter redundant tool loops,
increasing turn counts by ~28%. This change restores full history
retention while keeping the readCache improvements.
This commit is contained in:
Christian Gunderman
2026-02-19 06:17:49 +00:00
parent 85ae41535f
commit 45e7ed1ed2

View File

@@ -161,37 +161,6 @@ function validateHistory(history: Content[]) {
* Prunes the history to remove large tool outputs (like Greedy Grep context)
* after they have been seen by the model for one turn.
*/
function pruneHistory(history: Content[]): Content[] {
if (!history || history.length < 3) return history;
return history.map((content, index) => {
// Only prune user messages (which contain tool responses) that are older than the most recent one.
// Index < length - 2 ensures we keep the very latest tool response and the latest model thought.
if (content.role === 'user' && index < history.length - 2 && content.parts) {
const newParts = content.parts.map(part => {
if (part.functionResponse && part.functionResponse.name === 'grep_search') {
const output = (part.functionResponse.response as any)?.output || '';
if (output.includes('Match at line') && (output.includes('L') && output.includes('-'))) {
// This is a Greedy Grep output. Prune it.
const lines = output.split('\n');
const preservedLines = lines.filter((l: string) => l.startsWith('Found') || l.startsWith('File:') || l.includes('> L'));
const prunedOutput = preservedLines.join('\n') + '\n[... context pruned for token efficiency ...]';
return {
...part,
functionResponse: {
...part.functionResponse,
response: { output: prunedOutput }
}
};
}
}
return part;
});
return { ...content, parts: newParts };
}
return content;
});
}
function extractCuratedHistory(comprehensiveHistory: Content[]): Content[] {
if (comprehensiveHistory === undefined || comprehensiveHistory.length === 0) {
return [];
@@ -720,12 +689,7 @@ export class GeminiChat {
* chat session.
*/
getHistory(curated: boolean = false): Content[] {
let history = curated
? extractCuratedHistory(this.history)
: this.history;
// Prune history to remove large tool outputs after 1 turn
history = pruneHistory(history);
const history = curated ? extractCuratedHistory(this.history) : this.history;
// Deep copy the history to avoid mutating the history outside of the
// chat session.