Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions packages/components/nodes/chatmodels/ChatOpenAI/ChatOpenAI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,25 @@ class ChatOpenAI_ChatModels implements INode {
}
}

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
}
}
Comment on lines +289 to +306
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

There are two issues with this implementation:

  1. Reasoning Models Compatibility: OpenAI's reasoning models (e.g., o1 series) do not support stop sequences, which is why obj.stop is explicitly deleted on lines 266-268. However, because this new block runs after that check, any stop sequence provided in baseOptions will still be assigned to obj.stop, potentially causing API errors. We should ensure stop is not set for reasoning models.
  2. Input Object Mutation: If baseOptions is passed as an object, parsedBaseOptions holds a direct reference to it. Mutating it with delete parsedBaseOptions.stop will modify the original nodeData.inputs.baseOptions object, 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
            }
        }


if (basePath || parsedBaseOptions) {
obj.configuration = {
baseURL: basePath,
Expand Down