Skip to content

Conversation

@mjschock
Copy link

Fix: Duplicate function_call items in session history after resuming from interruption

Fixes #701

Problem

When using OpenAIConversationsSession with human-in-the-loop (HITL) tool approval, function_call items were being duplicated in conversation history. This occurred because _currentTurnPersistedItemCount was incorrectly reset to 0 after resolveInterruptedTurn, undoing the rewind logic that had already adjusted the counter.

Root Cause

After resolveInterruptedTurn returned next_step_run_again, the code was resetting the counter to 0 in multiple places (non-streaming and streaming paths), which caused saveToSession to save all items again, including the already-persisted function_call item.

Flow:

  1. Initial run: Counter = 2, tool_call_item saved to session
  2. Resume after approval: resolveInterruptedTurn rewinds counter (2 → 1) ✓
  3. Counter reset to 0 ❌ (bug)
  4. saveToSession with counter=0 saves all items again → duplicate created

Solution

  1. Removed counter resets after resolveInterruptedTurn: Removed all instances where _currentTurnPersistedItemCount was reset to 0 immediately after resolveInterruptedTurn returns next_step_run_again (lines 735, 870, 1025, 1210 in run.ts).

  2. Preserve rewound counter value: When continuing from interruption with next_step_run_again, only reset the counter if it's already 0 (indicating a new turn). If the counter is non-zero (was rewound), preserve the rewound value to prevent duplicates.

  3. Added handoff filtering: Added logic in resolveInterruptedTurn to filter out already-executed handoffs by callId to prevent re-execution when resuming from interruption.

Changes

  • packages/agents-core/src/run.ts:

    • Removed counter resets after resolveInterruptedTurn in non-streaming path (lines 735, 870)
    • Removed counter resets after resolveInterruptedTurn in streaming path (lines 1025, 1210)
    • Modified counter reset logic to only reset when counter is already 0 (preserving rewound values)
  • packages/agents-core/src/runImplementation.ts:

    • Added handoff filtering in resolveInterruptedTurn to prevent re-execution of already-executed handoffs

Testing

  • All existing tests continue to pass

Impact

  • ✅ Fixes duplicate function_call items in session history
  • ✅ No breaking changes
  • ✅ Backward compatible
  • ✅ Affects all users using OpenAIConversationsSession with HITL

@changeset-bot
Copy link

changeset-bot bot commented Nov 27, 2025

⚠️ No Changeset found

Latest commit: 9948f97

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate function_call items in session history after resuming from interruption

1 participant