Skip to content

Commit d389190

Browse files
committed
fix: restore session history when responses compaction replacement fails
1 parent a8712b7 commit d389190

3 files changed

Lines changed: 379 additions & 6 deletions

File tree

.changeset/quiet-lamps-restore.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@openai/agents-openai': patch
3+
---
4+
5+
fix: restore session history when responses compaction replacement fails

packages/agents-openai/src/memory/openaiResponsesCompactionSession.ts

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,11 @@ export class OpenAIResponsesCompactionSession
204204
const compacted = await this.client.responses.compact(compactRequest);
205205

206206
const outputItems = normalizeCompactionOutputItems(compacted.output ?? []);
207-
await this.underlyingSession.clearSession();
208-
if (outputItems.length > 0) {
209-
await this.underlyingSession.addItems(outputItems);
210-
}
207+
const previousItems = await this.getAllUnderlyingSessionItems();
208+
await this.replaceUnderlyingSessionItems({
209+
outputItems,
210+
previousItems,
211+
});
211212
this.compactionCandidateItems = selectCompactionCandidateItems(outputItems);
212213
this.sessionItems = outputItems;
213214

@@ -287,6 +288,87 @@ export class OpenAIResponsesCompactionSession
287288
this.sessionItems = [];
288289
}
289290

291+
private async getAllUnderlyingSessionItems(): Promise<AgentInputItem[]> {
292+
return this.underlyingSession.getItems();
293+
}
294+
295+
private async replaceUnderlyingSessionItems({
296+
outputItems,
297+
previousItems,
298+
}: {
299+
outputItems: AgentInputItem[];
300+
previousItems: AgentInputItem[];
301+
}): Promise<void> {
302+
try {
303+
await this.underlyingSession.clearSession();
304+
} catch (error) {
305+
await this.restoreUnderlyingSessionItemsAfterFailedClear(
306+
previousItems,
307+
error,
308+
);
309+
throw error;
310+
}
311+
312+
try {
313+
if (outputItems.length > 0) {
314+
await this.underlyingSession.addItems(outputItems);
315+
}
316+
} catch (error) {
317+
await this.restoreUnderlyingSessionItems(previousItems, error);
318+
throw error;
319+
}
320+
}
321+
322+
private async restoreUnderlyingSessionItemsAfterFailedClear(
323+
previousItems: AgentInputItem[],
324+
error: unknown,
325+
): Promise<void> {
326+
let currentItems: AgentInputItem[];
327+
try {
328+
currentItems = await this.getAllUnderlyingSessionItems();
329+
} catch (inspectionError) {
330+
logger.warn(
331+
'Failed to inspect session history after compaction replacement clear failed.',
332+
inspectionError,
333+
);
334+
return;
335+
}
336+
337+
if (areAgentItemsEqual(currentItems, previousItems)) {
338+
return;
339+
}
340+
341+
await this.restoreUnderlyingSessionItems(previousItems, error, {
342+
clearExistingItems: false,
343+
});
344+
}
345+
346+
private async restoreUnderlyingSessionItems(
347+
previousItems: AgentInputItem[],
348+
error: unknown,
349+
options: { clearExistingItems?: boolean } = {},
350+
): Promise<void> {
351+
try {
352+
if (options.clearExistingItems !== false) {
353+
await this.underlyingSession.clearSession();
354+
}
355+
if (previousItems.length > 0) {
356+
await this.underlyingSession.addItems(previousItems);
357+
}
358+
} catch (restoreError) {
359+
logger.warn(
360+
'Failed to restore session history after compaction replacement failed.',
361+
restoreError,
362+
);
363+
return;
364+
}
365+
366+
logger.warn(
367+
'Restored previous session history after compaction replacement failed.',
368+
error,
369+
);
370+
}
371+
290372
private async ensureCompactionCandidates(): Promise<{
291373
compactionCandidateItems: AgentInputItem[];
292374
sessionItems: AgentInputItem[];
@@ -525,3 +607,10 @@ function isOpenAIConversationsSessionDelegate(
525607
] === 'conversations'
526608
);
527609
}
610+
611+
function areAgentItemsEqual(
612+
left: AgentInputItem[],
613+
right: AgentInputItem[],
614+
): boolean {
615+
return JSON.stringify(left) === JSON.stringify(right);
616+
}

0 commit comments

Comments
 (0)