-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat: add strict tool message ordering setting for OpenAI Compatible providers #10598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…providers Adds a new setting `openAiStrictToolMessageOrdering` to OpenAI Compatible providers that enables merging text content after tool results into the last tool message. This fixes "Unexpected role user after role tool" errors with NVIDIA NIM, OpenRouter, and other strict OpenAI-compatible APIs. When enabled, environment_details and other text content that follows tool_result messages are merged into the last tool message instead of being sent as a separate user message. Fixes #10540
All issues have been resolved. The latest commit adds comprehensive regression tests for multi-turn conversation support with the
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
…providers Adds a new setting `openAiStrictToolMessageOrdering` for OpenAI-compatible providers that, when enabled, merges text content after tool results into the last tool message instead of creating a separate user message. This fixes the "Unexpected role user after role tool" error that occurs with providers like NVIDIA NIM and Devstral that enforce strict message ordering rules. Fixes #10540
| "openAiStrictToolMessageOrdering": { | ||
| "label": "Strict tool message ordering", | ||
| "description": "Enable for providers like NVIDIA NIM and Devstral that require strict message ordering. When enabled, text content after tool results is merged into the last tool message instead of creating a separate user message." | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This addition creates duplicate keys in the JSON file. There are older flat format entries at lines 539-541 ("openAiStrictToolMessageOrdering": "Strict tool message ordering" and "openAiStrictToolMessageOrderingDescription": "...") that were not removed. Since JSON parsers typically use the last value for duplicate keys, the flat format at line 539 will take precedence, causing t("settings:providers.openAiStrictToolMessageOrdering.label") to return undefined. Remove the old flat format entries at lines 539-541.
Fix it with Roo Code or mention @roomote and request a fix.
|
@roomote I found after running the branch locally that if "Enable R1 model parameters" is enabled at the same time it will still produce the 400 error. Why would that happen? |
Fixed the issue where "Strict tool message ordering" was not applied when "Enable R1 model parameters" was also enabled. The |
…e is enabled When both "Enable R1 model parameters" and "Strict tool message ordering" are enabled, the mergeToolResultText option was not being passed to convertToR1Format, causing the 400 error to still occur. This fix ensures the strictToolMessageOrdering setting is respected in both the streaming and non-streaming code paths when using R1 format.
Removed duplicate translation keys in settings.json. All local checks passed. |
|
@roomote After more testing, if I have the option checked and an image is added to the chat it does not merge the text. So when handling images it needs to take that into account to merge the text. |
Fixed the reported issue. Text content is now merged into the last tool message even when images are present. All local checks passed. |
When mergeToolResultText is enabled and both text and images are present after tool results, the text content is now merged into the last tool message while images are sent as a separate user message. This fixes the issue where strict tool message ordering would not work when images were added to the chat, causing "Unexpected role user after role tool" errors on providers like NVIDIA NIM.
|
@roomote The fix works for the first message but after the first response the text content is NOT merged into the last tool message. |
I investigated the reported issue and added multi-turn conversation tests to verify the Findings: All 27 tests pass, including new tests that specifically verify text is merged into tool messages for ALL tool_result messages in a conversation (not just the first one). The If the issue persists, please verify:
|
Add regression tests to verify that the mergeToolResultText option works correctly for ALL tool_result messages in a conversation, not just the first one. Tests added: - Multi-turn conversation with multiple tool calls - Verification that no user messages appear after tool messages when mergeToolResultText is enabled All 27 tests pass.
Related GitHub Issue
Closes: #10540
Description
This PR attempts to address Issue #10540. Feedback and guidance are welcome.
This PR adds a new setting
openAiStrictToolMessageOrderingfor OpenAI Compatible providers that fixes the "Unexpected role 'user' after role 'tool'" error occurring with NVIDIA NIM, OpenRouter, and other strict OpenAI-compatible APIs.Implementation approach (Option 1 from issue analysis):
openAiStrictToolMessageOrderingto the provider settings schemamergeToolResultText: truetoconvertToOpenAiMessages(), which merges text content (like environment_details) into the last tool message instead of creating a separate user messageFiles modified:
packages/types/src/provider-settings.ts- Added the new setting to openAiSchemasrc/api/providers/openai.ts- Use the setting when calling convertToOpenAiMessages()webview-ui/src/components/settings/providers/OpenAICompatible.tsx- Added UI checkboxwebview-ui/src/i18n/locales/en/settings.json- Added translation keysTest Procedure
cd src && npx vitest run api/transform/__tests__/openai-format.spec.ts(all 24 tests pass)Pre-Submission Checklist
Documentation Updates
Additional Notes
This implementation uses the same approach already proven by DeepSeek (for thinking models), Z.ai provider, and MiniMax. The codebase already had the
mergeToolResultTextoption inconvertToOpenAiMessages()- this PR simply exposes it as a user-facing setting for OpenAI Compatible providers.Important
Adds
openAiStrictToolMessageOrderingsetting for strict message ordering in OpenAI Compatible providers, preventing specific errors and updating UI and tests.openAiStrictToolMessageOrderingsetting to handle strict message ordering for OpenAI Compatible providers, preventing "Unexpected role 'user' after role 'tool'" errors.mergeToolResultTextinconvertToOpenAiMessages().openAiStrictToolMessageOrderinginOpenAICompatible.tsxwith description insettings.json.provider-settings.ts: Adds new setting toopenAiSchema.openai.ts: Implements setting in message conversion logic.openai-format.spec.ts: Adds tests formergeToolResultTextbehavior.This description was created by
for 3661e54. You can customize this summary. It will automatically update as commits are pushed.