Skip to content

Conversation

@daniel-lxs
Copy link
Member

@daniel-lxs daniel-lxs commented Sep 5, 2025

Description

This PR fixes a critical regression in the OpenAI Responses API where conversation context was lost after a continuity failure.

The Problem

When a previous_response_id becomes invalid or expired (400 error), the current code on main:

  • Removes the invalid ID and retries
  • BUT still sends only the latest message in the retry
  • This causes complete context loss and degraded responses

The Solution

This PR ensures that when previous_response_id fails:

  1. Clear the invalid response ID
  2. Remove previous_response_id from the request
  3. Re-prepare the full conversation history for the retry
  4. Send all messages to preserve context

Changes

  • Modified executeRequest() to re-prepare input with full conversation on retry
  • Modified makeGpt5ResponsesAPIRequest() with the same fix for SSE fallback
  • Added comprehensive test coverage verifying retry sends full conversation

Test Procedure

Run the tests:

cd src && npx vitest run api/providers/__tests__/openai-native.spec.ts

Expected: All 36 tests pass, including the new test that verifies:

  • First attempt with previous_response_id sends only latest message
  • On 400 error, retry sends the full conversation history
  • Context is preserved on retry

Impact

  • Fixes context loss bug that degraded response quality
  • Ensures conversation continuity is maintained even when response IDs expire
  • Backward compatible - only affects retry behavior after specific 400 errors

Important

Fixes context loss by retrying with full conversation history on invalid previous_response_id errors in OpenAI Responses API.

  • Behavior:
    • Fixes context loss by retrying with full conversation history when previous_response_id is invalid in executeRequest() and makeGpt5ResponsesAPIRequest().
    • On 400 error, clears previous_response_id and resends full conversation.
  • Tests:
    • Added tests in openai-native.spec.ts to verify retry logic sends full conversation on 400 error.
    • Tests ensure context is preserved and verify two requests are made: first with previous_response_id, second with full history.
  • Misc:
    • No changes to existing functionality, only affects retry behavior after specific 400 errors.

This description was created by Ellipsis for 8d4a77f. You can customize this summary. It will automatically update as commits are pushed.

…revious_response_id

When the OpenAI Responses API returns a 400 error due to an invalid or expired
previous_response_id, the code now properly re-prepares the full conversation
history for the retry instead of just removing the ID and sending only the
latest message.

This fixes a critical bug where conversation context was completely lost when
continuity failed, leading to degraded responses.

Changes:
- Modified executeRequest() to re-prepare input with full conversation on retry
- Modified makeGpt5ResponsesAPIRequest() with the same fix for SSE fallback
- Added comprehensive test coverage for both SDK and SSE retry paths
- Tests verify retry sends full conversation, not just latest message
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. bug Something isn't working labels Sep 5, 2025
// Clear the stored lastResponseId to prevent using it again
this.lastResponseId = undefined

// Re-prepare the full conversation without previous_response_id
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good fix: when a 400 error occurs due to an invalid previous_response_id, the code now clears it and re-prepares the full conversation. Consider extracting the duplicated logic for re-preparing the conversation (lines ~327–339 and ~517–521) into a helper method to reduce repetition and ease future maintenance.

@daniel-lxs daniel-lxs moved this from Triage to PR [Needs Review] in Roo Code Roadmap Sep 5, 2025
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Sep 5, 2025
Copy link

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this important fix! The solution correctly addresses the context loss issue when previous_response_id becomes invalid. I've reviewed the changes and have some suggestions to improve code maintainability.

// If we have the original messages, re-prepare the full conversation
if (systemPrompt && messages) {
const { formattedInput } = this.prepareStructuredInput(systemPrompt, messages, undefined)
retryRequestBody.input = formattedInput
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the existing suggestion - this duplicated logic for re-preparing the conversation (here and around line 517-521) should be extracted into a helper method. Consider something like:

Suggested change
retryRequestBody.input = formattedInput
private prepareRetryRequestBody(requestBody: any, systemPrompt?: string, messages?: Anthropic.Messages.MessageParam[]): any {
const retryRequestBody = { ...requestBody };
delete retryRequestBody.previous_response_id;
if (systemPrompt && messages) {
const { formattedInput } = this.prepareStructuredInput(systemPrompt, messages, undefined);
retryRequestBody.input = formattedInput;
}
return retryRequestBody;
}


if (is400Error && requestBody.previous_response_id && isPreviousResponseError) {
// Log the error and retry without the previous_response_id

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment mentions logging but no actual logging is implemented. Consider adding proper error logging here for debugging purposes:

Suggested change
// Log the error and retry without the previous_response_id
console.warn('Previous response ID not found, retrying with full conversation:', errorMessage);


if (response.status === 400 && requestBody.previous_response_id && isPreviousResponseError) {
// Log the error and retry without the previous_response_id

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same logging issue here - consider adding actual error logging:

Suggested change
// Log the error and retry without the previous_response_id
console.warn('Previous response ID not found (SSE path), retrying with full conversation:', errorDetails);

role: "user",
content: [{ type: "input_text", text: "What number did I ask you to remember?" }],
},
])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great test coverage! Consider adding one more test case for when both the initial request AND the retry fail, to ensure proper error propagation in that scenario.

@hannesrudolph hannesrudolph added Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. PR - Needs Review and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Sep 5, 2025
@mrubens mrubens merged commit 49b50c8 into main Sep 5, 2025
26 checks passed
@mrubens mrubens deleted the fix/openai-context-loss-on-retry branch September 5, 2025 20:09
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Sep 5, 2025
@github-project-automation github-project-automation bot moved this from PR [Needs Review] to Done in Roo Code Roadmap Sep 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working lgtm This PR has been approved by a maintainer PR - Needs Review size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants