Skip to content
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,11 @@ const prepareAgent = async (
}
}

/** Bind a stop token to the model */
const modelWithStop = model.bind({
stop: ['\nObservation']
})
/** Bind a stop token to the model if supported */
// Avoid passing `stop` to models that reject it (e.g. gpt-5-nano)
const { modelSupportsStop } = await import('../../../src/utils')
const modelId = (model as any)?.modelName ?? (model as any)?.model ?? (model as any)?.configuredModel
const modelWithStop = modelSupportsStop(modelId) ? model.bind({ stop: ['\nObservation'] }) : model

const runnableAgent = RunnableSequence.from([
{
Expand Down
6 changes: 5 additions & 1 deletion packages/components/nodes/agents/XMLAgent/XMLAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,11 @@ const prepareAgent = async (
throw new Error(`Provided prompt is missing required input variables: ${JSON.stringify(missingVariables)}`)
}

const llmWithStop = model.bind({ stop: ['</tool_input>', '</final_answer>'] })
const { modelSupportsStop } = await import('../../../src/utils')
const modelId = (model as any)?.modelName ?? (model as any)?.model ?? (model as any)?.configuredModel
const llmWithStop = modelSupportsStop(modelId)
? (model as BaseChatModel).bind({ stop: ['</tool_input>', '</final_answer>'] })
: (model as BaseChatModel)

const messages = (await memory.getChatMessages(flowObj.sessionId, false, prependMessages)) as IMessage[]
let chatHistoryMsgTxt = ''
Expand Down
9 changes: 6 additions & 3 deletions packages/components/src/agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
} from 'langchain/agents'
import { formatLogToString } from 'langchain/agents/format_scratchpad/log'
import { IUsedTool } from './Interface'
import { modelSupportsStop } from './utils'
Copy link
Contributor

Choose a reason for hiding this comment

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

where does this come from? I dont see any changes in utils file?

Copy link
Author

Choose a reason for hiding this comment

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

I added the changes from the utils.ts file. Please check. Thanks

import { getErrorMessage } from './error'

export const SOURCE_DOCUMENTS_PREFIX = '\n\n----FLOWISE_SOURCE_DOCUMENTS----\n\n'
Expand Down Expand Up @@ -778,9 +779,11 @@ export const createReactAgent = async ({ llm, tools, prompt }: CreateReactAgentP
tool_names: toolNames.join(', ')
})
// TODO: Add .bind to core runnable interface.
const llmWithStop = (llm as BaseLanguageModel).bind({
stop: ['\nObservation:']
})
// Bind stop only when the underlying model supports it (some models like gpt-5-nano reject `stop`)
const llmModelName = (llm as any)?.modelName ?? (llm as any)?.model ?? (llm as any)?.configuredModel
const llmWithStop = modelSupportsStop(llmModelName)
? (llm as BaseLanguageModel).bind({ stop: ['\nObservation:'] })
: (llm as BaseLanguageModel)
const agent = RunnableSequence.from([
RunnablePassthrough.assign({
//@ts-ignore
Expand Down
15 changes: 15 additions & 0 deletions packages/components/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ export const defaultAllowBuiltInDep = [
'zlib'
]

/**
* Return true if the model name likely supports the `stop` parameter.
* Some newer OpenAI models (for example gpt-5-nano) do not accept the `stop` parameter
* and will return an HTTP 400 when it is provided. Add model names here as needed.
*/
export const modelSupportsStop = (modelName?: string): boolean => {
if (!modelName) return true
const lower = modelName.toLowerCase()
// Treat all gpt-5*, o1*, and o3* models as not supporting `stop`
// to avoid 400 Unsupported parameter errors.
const unsupportedPrefixes = ['gpt-5', 'o1', 'o3']
if (unsupportedPrefixes.some((prefix) => lower.startsWith(prefix))) return false
return true
}

/**
* Get base classes of components
*
Expand Down