Skip to content

fix: map chat finish_reason to responses status and preserve terminal stream semantics#1995

Open
jerkeyray wants to merge 1 commit intomainfrom
fix/mux-finish-reason-status-mapping
Open

fix: map chat finish_reason to responses status and preserve terminal stream semantics#1995
jerkeyray wants to merge 1 commit intomainfrom
fix/mux-finish-reason-status-mapping

Conversation

@jerkeyray
Copy link
Contributor

@jerkeyray jerkeyray commented Mar 9, 2026

Summary

Implements proper handling of incomplete responses in the OpenAI provider by mapping length finish reasons to incomplete status and preventing duplicate finish reason forwarding in streaming responses.

Changes

  • Added logic to map length finish reason to incomplete status with max_output_tokens reason in both streaming and non-streaming responses
  • Introduced tracking to prevent forwarding finish reasons twice when they've already been sent in streaming chunks
  • Added helper functions responsesStatusFromChatFinishReason and responsesTerminalFromChatFinishReason to centralize finish reason mapping logic
  • Modified streaming response handling to emit response.incomplete events instead of response.completed when appropriate
  • Added comprehensive test coverage for finish reason mapping in both response formats

Type of change

  • Feature
  • Bug fix
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (Next.js)
  • Docs

How to test

Validate the finish reason mapping and incomplete response handling:

# Core/Transports
go version
go test ./...

# Test specific functionality
go test ./core/schemas -v -run TestToBifrostResponsesResponse_MapsLengthToIncomplete
go test ./core/schemas -v -run TestToBifrostResponsesStreamResponse_MapsLengthToIncompleteEvent

Test with OpenAI provider responses that hit token limits to verify incomplete status is properly set with max_output_tokens reason.

Screenshots/Recordings

N/A

Breaking changes

  • Yes
  • No

Related issues

Closes #1976
Closes #1821

Security considerations

No security implications - this change only affects response status mapping and metadata handling.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

🧪 Test Suite Available

This PR can be tested by a repository admin.

Run tests for PR #1995

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 9, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6ce03561-8857-4198-a0ce-b8608581b086

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/mux-finish-reason-status-mapping

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jerkeyray jerkeyray marked this pull request as ready for review March 9, 2026 12:59
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
core/schemas/mux.go (1)

1766-1950: ⚠️ Potential issue | 🟠 Major

length can still leave earlier text items marked as completed.

This only fixes the text item status when it is closed in the terminal chunk. If assistant text is closed earlier at the tool-call transition on Line 1597, that path still emits response.output_item.done with Status: "completed" on Line 1643. A stream that later ends with finish_reason == "length" will therefore produce response.incomplete while the already-closed text item says completed. Please defer that text output_item.done until the terminal chunk, or route the same terminal status through the earlier close path as well.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2caaf961-cc11-41a9-8400-4c6802182cfe

📥 Commits

Reviewing files that changed from the base of the PR and between 368aaf1 and 318fd68.

📒 Files selected for processing (3)
  • core/providers/openai/openai.go
  • core/schemas/mux.go
  • core/schemas/mux_test.go

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.

[Bug]: Chat-to-Responses mux does not map finish_reason to status [Bug]: OpenAI chat completions response missing finish_reason

1 participant