Skip to content

fix: honor stop option for ChatOpenAI Custom BaseOptions#6531

Draft
Alaxise wants to merge 1 commit into
FlowiseAI:mainfrom
Alaxise:bugfix/chatopenai-custom-base-options-stop
Draft

fix: honor stop option for ChatOpenAI Custom BaseOptions#6531
Alaxise wants to merge 1 commit into
FlowiseAI:mainfrom
Alaxise:bugfix/chatopenai-custom-base-options-stop

Conversation

@Alaxise

@Alaxise Alaxise commented Jun 18, 2026

Copy link
Copy Markdown

Summary

  • Fixes ChatOpenAI Custom so BaseOptions.stop is passed to LangChain ChatOpenAI as a model option instead of being sent as an HTTP default header.
  • Keeps client configuration behavior intact for baseURL and defaultHeaders.
  • Adds a focused regression test for the reported issue path.

Submission convention followed

Problem

Issue #2499 reports that Additional Parameters did not take effect for ChatOpenAI Custom when a user entered:

{
  "stop": ["<|im_end|>"]
}

The current node parsed baseOptions and assigned the entire object to obj.configuration.defaultHeaders. That meant stop became a request header and never reached ChatOpenAIFields.stop.

Why this matters

Flowise is positioned as a visual AI-agent builder. Chat model configuration is a core user path, especially for custom or OpenAI-compatible models. When advanced model parameters are accepted by the node UI but silently routed to the wrong place, users cannot reliably control model output and maintainers get support reports that are hard to diagnose.

The change is meaningful because it fixes a concrete user-reported bug with a small, reviewable diff and a regression test.

Roadmap / mission alignment

The repository README describes Flowise as "Build AI Agents, Visually." This fix supports that mission by making one of the visual chat model nodes honor a model-control parameter that users configure through the node.

Issue alignment is direct: #2499 is open and labeled enhancement, good first issue, and help wanted. Maintainer/community discussion also points at this area of the ChatOpenAI nodes.

What changed

  • packages/components/nodes/chatmodels/ChatOpenAICustom/ChatOpenAICustom.ts: parses BaseOptions into model options and client configuration instead of treating every key as a default header.
  • packages/components/nodes/chatmodels/ChatOpenAICustom/ChatOpenAICustom.test.ts: adds regression coverage for stop, baseURL, and defaultHeaders.

How it works

baseOptions is still parsed the same way as before. After parsing:

  • stop is assigned to obj.stop, which is the LangChain ChatOpenAIFields path.
  • baseURL and defaultHeaders are preserved under obj.configuration.
  • Unknown keys remain in the default-header bucket for backward compatibility.

This keeps the reported fix narrow. It does not attempt to promote every arbitrary BaseOptions key into model fields.

Local deployment evidence

  • Command or script used: pnpm.cmd install --frozen-lockfile, pnpm.cmd build, PORT=3000 pnpm.cmd start
  • URL, endpoint, CLI invocation, or service checked: http://localhost:3000, http://localhost:3000/api/v1/ping
  • Before behavior: focused regression test failed because model.fields.stop was undefined.
  • After behavior: local server started successfully, root returned HTTP 200, /api/v1/ping returned pong, and the focused regression test passed.
  • Blockers or substitutes: protected node metadata routes returned HTTP 401 without an authenticated session, so the exact node behavior is verified with a constructor-level Jest test instead of an authenticated UI node-edit flow.

Verification

  • pnpm.cmd --filter flowise-components test -- ChatOpenAICustom.test.ts --runInBand: 2 tests passed.
  • pnpm.cmd --filter flowise-components exec tsc --noEmit --pretty false: passed.
  • pnpm.cmd --filter flowise-components exec eslint nodes/chatmodels/ChatOpenAICustom/ChatOpenAICustom.ts nodes/chatmodels/ChatOpenAICustom/ChatOpenAICustom.test.ts --ext ts --report-unused-disable-directives --max-warnings 0: passed.
  • pnpm.cmd --filter flowise-components build: passed.
  • pnpm.cmd build: passed.
  • PORT=3000 pnpm.cmd start: server started and responded locally.
  • git diff --check: passed before commit.
  • Authenticated UI node-edit flow: not run because local API/UI auth was not configured for this verification pass.
  • Live OpenAI-compatible API request: not run because the fix can be proven without external secrets or network calls to a model provider.

Risks considered

  • Backward compatibility for custom headers: unknown BaseOptions keys remain request headers.
  • Scope creep: only stop is promoted as a model option because it is the reported parameter.
  • Duplicate solution risk: there is another open PR discussing a Stop Sequence input. This PR intentionally targets the reported BaseOptions path and avoids a UI schema change.

Risks not fully covered

  • Other model options in BaseOptions may still not be promoted. That is intentional to avoid changing more behavior than the issue requires.
  • Authenticated UI flow was not tested, so reviewers may still want to confirm the node form serialization path in a local account-enabled setup.
  • A live OpenAI-compatible request was not sent, so provider-specific handling of stop should still be covered by existing LangChain/OpenAI behavior.

Review focus

  • Whether promoting stop from BaseOptions is acceptable without adding a dedicated Stop Sequence field to ChatOpenAI Custom.
  • Whether preserving unknown keys as default headers is the right compatibility choice.
  • Whether the wording of the Base Options description is clear enough for users.

Follow-ups intentionally left out

  • Adding a dedicated Stop Sequence UI input to ChatOpenAI Custom.
  • Promoting additional OpenAI model options from BaseOptions.
  • Refactoring shared BaseOptions parsing across all OpenAI-compatible chat model nodes.

Ownership report

Generated locally for contributor handoff and intentionally not linked from this public PR because it is not part of the repository diff.

Fixes #2499

ChatOpenAI Custom accepted BaseOptions JSON but forwarded every key as defaultHeaders. That made issue FlowiseAI#2499's stop parameter become an HTTP header instead of a ChatOpenAI model option, so the model never received the configured stop sequence.

This keeps the change narrow: stop is promoted to ChatOpenAI fields, baseURL/defaultHeaders remain client configuration, and unknown BaseOptions keys continue to act as request headers for compatibility.

Constraint: Flowise issue FlowiseAI#2499 reports stop supplied through ChatOpenAI Custom BaseOptions.

Rejected: Add a new Stop Sequence input | an existing open PR explores that UI path, but it does not directly preserve the reported BaseOptions workflow.

Rejected: Promote every BaseOptions key to model fields | too broad for a bugfix and could break users relying on custom headers.

Confidence: high

Scope-risk: narrow

Reversibility: clean

Directive: Do not broaden BaseOptions model-option promotion without explicit compatibility tests for request headers.

Tested: pnpm.cmd --filter flowise-components test -- ChatOpenAICustom.test.ts --runInBand

Tested: pnpm.cmd --filter flowise-components exec tsc --noEmit --pretty false

Tested: pnpm.cmd --filter flowise-components exec eslint nodes/chatmodels/ChatOpenAICustom/ChatOpenAICustom.ts nodes/chatmodels/ChatOpenAICustom/ChatOpenAICustom.test.ts --ext ts --report-unused-disable-directives --max-warnings 0

Tested: pnpm.cmd --filter flowise-components build

Tested: pnpm.cmd build; PORT=3000 pnpm.cmd start; GET / returned 200; GET /api/v1/ping returned pong

Not-tested: Authenticated UI node-edit flow and live OpenAI-compatible API request.

Related: FlowiseAI#2499

@gemini-code-assist gemini-code-assist Bot left a comment

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.

Code Review

This pull request refactors the ChatOpenAICustom node to properly parse and extract stop, baseURL, and defaultHeaders from baseOptions, and adds corresponding unit tests. Feedback suggests adding validation to ensure parsedBaseOptions is a plain object before destructuring, which prevents potential runtime errors when handling invalid JSON inputs.

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.

let baseOptionsBaseURL: string | undefined
let baseOptionsDefaultHeaders: ICommonObject | undefined

if (parsedBaseOptions) {

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.

medium

If parsedBaseOptions is parsed as a non-object JSON value (such as a string or an array), destructuring it directly or using Object.keys on it can lead to unexpected behavior. To promote fail-fast behavior when handling potentially invalid data from external sources, we should throw an error if the input type is invalid, rather than silently skipping or returning a default value.

if (!parsedBaseOptions || typeof parsedBaseOptions !== 'object' || Array.isArray(parsedBaseOptions)) {
    throw new Error('Invalid base options: expected a plain object');
}
References
  1. When handling potentially invalid data from external sources (like an API response), prefer throwing an error for invalid input types rather than silently returning a default or empty value. This promotes fail-fast behavior.

@Alaxise Alaxise changed the title Honor stop option for ChatOpenAI Custom BaseOptions fix: honor stop option for ChatOpenAI Custom BaseOptions Jun 18, 2026
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] Additional Parameters did not take effect.

2 participants