fix(chatopenai): support stop in base options#6472
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds support for parsing and applying the stop parameter from parsedBaseOptions in the ChatOpenAI component. The reviewer identified two critical issues: potential compatibility problems with reasoning models (which do not support stop sequences) and unexpected side effects from mutating the original input object. A code suggestion was provided to resolve both issues.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (parsedBaseOptions?.stop) { | ||
| const stop = parsedBaseOptions.stop | ||
|
|
||
| if (!obj.stop) { | ||
| obj.stop = Array.isArray(stop) | ||
| ? stop.map((item) => String(item).trim()).filter(Boolean) | ||
| : String(stop) | ||
| .split(',') | ||
| .map((item) => item.trim()) | ||
| .filter(Boolean) | ||
| } | ||
|
|
||
| delete parsedBaseOptions.stop | ||
|
|
||
| if (Object.keys(parsedBaseOptions).length === 0) { | ||
| parsedBaseOptions = undefined | ||
| } | ||
| } |
There was a problem hiding this comment.
There are two issues with this implementation:
- Reasoning Models Compatibility: OpenAI's reasoning models (e.g.,
o1series) do not supportstopsequences, which is whyobj.stopis explicitly deleted on lines 266-268. However, because this new block runs after that check, anystopsequence provided inbaseOptionswill still be assigned toobj.stop, potentially causing API errors. We should ensurestopis not set for reasoning models. - Input Object Mutation: If
baseOptionsis passed as an object,parsedBaseOptionsholds a direct reference to it. Mutating it withdelete parsedBaseOptions.stopwill modify the originalnodeData.inputs.baseOptionsobject, which can cause unexpected side effects if the node is re-initialized or reused. We should shallow copy the object before deleting the property.
Here is the suggested fix to address both issues:
if (parsedBaseOptions?.stop) {
const stop = parsedBaseOptions.stop
if (!obj.stop && !isReasoningModelOpenAI(modelName)) {
obj.stop = Array.isArray(stop)
? stop.map((item) => String(item).trim()).filter(Boolean)
: String(stop)
.split(',')
.map((item) => item.trim())
.filter(Boolean)
}
if (typeof baseOptions === 'object') {
parsedBaseOptions = { ...parsedBaseOptions }
}
delete parsedBaseOptions.stop
if (Object.keys(parsedBaseOptions).length === 0) {
parsedBaseOptions = undefined
}
}|
Hi maintainers, I opened this PR to address #2499. The issue happens because Base Options are currently parsed into the OpenAI configuration/default headers path, so a stop value provided there does not reach the model invocation options. This PR extracts stop from parsed Base Options and applies it to obj.stop, while preserving the existing Stop Sequence field behavior. Please let me know if you'd prefer a different approach. |
Summary
stopwhen provided through ChatOpenAI Base Options.stopfrom parsed base options and apply it to the model options instead of sending it as a default header.Stop Sequencefield behavior by only using Base Optionsstopwhenobj.stopis not already set.Fixes #2499
Tests
git diff --check