-
-
Notifications
You must be signed in to change notification settings - Fork 24.7k
feat(components): add Requesty chat model node #6616
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { INodeParams, INodeCredential } from '../src/Interface' | ||
|
|
||
| class RequestyAPIAuth implements INodeCredential { | ||
| label: string | ||
| name: string | ||
| version: number | ||
| description: string | ||
| inputs: INodeParams[] | ||
|
|
||
| constructor() { | ||
| this.label = 'Requesty API Key' | ||
| this.name = 'requestyApi' | ||
| this.version = 1.0 | ||
| this.inputs = [ | ||
| { | ||
| label: 'Requesty API Key', | ||
| name: 'requestyApiKey', | ||
| type: 'password', | ||
| description: 'API Key' | ||
| } | ||
| ] | ||
| } | ||
| } | ||
|
|
||
| module.exports = { credClass: RequestyAPIAuth } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,194 @@ | ||||||||||||||||||||||||||||||||
| import { ChatOpenAI as LangchainChatOpenAI, ChatOpenAIFields } from '@langchain/openai' | ||||||||||||||||||||||||||||||||
| import { BaseCache } from '@langchain/core/caches' | ||||||||||||||||||||||||||||||||
| import { ICommonObject, IMultiModalOption, INode, INodeData, INodeParams } from '../../../src/Interface' | ||||||||||||||||||||||||||||||||
| import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' | ||||||||||||||||||||||||||||||||
| import { ChatRequesty } from './FlowiseChatRequesty' | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| class ChatRequesty_ChatModels implements INode { | ||||||||||||||||||||||||||||||||
| label: string | ||||||||||||||||||||||||||||||||
| name: string | ||||||||||||||||||||||||||||||||
| version: number | ||||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||||
| icon: string | ||||||||||||||||||||||||||||||||
| category: string | ||||||||||||||||||||||||||||||||
| description: string | ||||||||||||||||||||||||||||||||
| baseClasses: string[] | ||||||||||||||||||||||||||||||||
| credential: INodeParams | ||||||||||||||||||||||||||||||||
| inputs: INodeParams[] | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| constructor() { | ||||||||||||||||||||||||||||||||
| this.label = 'Requesty' | ||||||||||||||||||||||||||||||||
| this.name = 'chatRequesty' | ||||||||||||||||||||||||||||||||
| this.version = 1.0 | ||||||||||||||||||||||||||||||||
| this.type = 'ChatRequesty' | ||||||||||||||||||||||||||||||||
| this.icon = 'requesty.svg' | ||||||||||||||||||||||||||||||||
| this.category = 'Chat Models' | ||||||||||||||||||||||||||||||||
| this.description = 'Wrapper around Requesty Inference API' | ||||||||||||||||||||||||||||||||
| this.baseClasses = [this.type, ...getBaseClasses(LangchainChatOpenAI)] | ||||||||||||||||||||||||||||||||
| this.credential = { | ||||||||||||||||||||||||||||||||
| label: 'Connect Credential', | ||||||||||||||||||||||||||||||||
| name: 'credential', | ||||||||||||||||||||||||||||||||
| type: 'credential', | ||||||||||||||||||||||||||||||||
| credentialNames: ['requestyApi'], | ||||||||||||||||||||||||||||||||
| optional: true | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+28
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The credential for Requesty is currently marked as this.credential = {
label: 'Connect Credential',
name: 'credential',
type: 'credential',
credentialNames: ['requestyApi']
}References
Comment on lines
+28
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since To prevent this, the credential should be required by removing this.credential = {
label: 'Connect Credential',
name: 'credential',
type: 'credential',
credentialNames: ['requestyApi']
}References
|
||||||||||||||||||||||||||||||||
| this.inputs = [ | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Cache', | ||||||||||||||||||||||||||||||||
| name: 'cache', | ||||||||||||||||||||||||||||||||
| type: 'BaseCache', | ||||||||||||||||||||||||||||||||
| optional: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Model Name', | ||||||||||||||||||||||||||||||||
| name: 'modelName', | ||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||
| placeholder: 'openai/gpt-4o-mini' | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Temperature', | ||||||||||||||||||||||||||||||||
| name: 'temperature', | ||||||||||||||||||||||||||||||||
| type: 'number', | ||||||||||||||||||||||||||||||||
| step: 0.1, | ||||||||||||||||||||||||||||||||
| default: 0.9, | ||||||||||||||||||||||||||||||||
| optional: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Streaming', | ||||||||||||||||||||||||||||||||
| name: 'streaming', | ||||||||||||||||||||||||||||||||
| type: 'boolean', | ||||||||||||||||||||||||||||||||
| default: true, | ||||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||||
| additionalParams: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Allow Image Uploads', | ||||||||||||||||||||||||||||||||
| name: 'allowImageUploads', | ||||||||||||||||||||||||||||||||
| type: 'boolean', | ||||||||||||||||||||||||||||||||
| description: | ||||||||||||||||||||||||||||||||
| 'Allow image input. Refer to the <a href="https://docs.flowiseai.com/using-flowise/uploads#image" target="_blank">docs</a> for more details.', | ||||||||||||||||||||||||||||||||
| default: false, | ||||||||||||||||||||||||||||||||
| optional: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Max Tokens', | ||||||||||||||||||||||||||||||||
| name: 'maxTokens', | ||||||||||||||||||||||||||||||||
| type: 'number', | ||||||||||||||||||||||||||||||||
| step: 1, | ||||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||||
| additionalParams: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Top Probability', | ||||||||||||||||||||||||||||||||
| name: 'topP', | ||||||||||||||||||||||||||||||||
| type: 'number', | ||||||||||||||||||||||||||||||||
| step: 0.1, | ||||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||||
| additionalParams: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Frequency Penalty', | ||||||||||||||||||||||||||||||||
| name: 'frequencyPenalty', | ||||||||||||||||||||||||||||||||
| type: 'number', | ||||||||||||||||||||||||||||||||
| step: 0.1, | ||||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||||
| additionalParams: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Presence Penalty', | ||||||||||||||||||||||||||||||||
| name: 'presencePenalty', | ||||||||||||||||||||||||||||||||
| type: 'number', | ||||||||||||||||||||||||||||||||
| step: 0.1, | ||||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||||
| additionalParams: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Timeout', | ||||||||||||||||||||||||||||||||
| name: 'timeout', | ||||||||||||||||||||||||||||||||
| type: 'number', | ||||||||||||||||||||||||||||||||
| step: 1, | ||||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||||
| additionalParams: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Base Path', | ||||||||||||||||||||||||||||||||
| name: 'basepath', | ||||||||||||||||||||||||||||||||
| type: 'string', | ||||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||||
| default: 'https://router.requesty.ai/v1', | ||||||||||||||||||||||||||||||||
| description: 'Override the default base URL for the API, e.g., "https://api.example.com/v2/', | ||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a missing closing double quote in the description string of the
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||||||||||
| additionalParams: true | ||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||
| label: 'Base Options', | ||||||||||||||||||||||||||||||||
| name: 'baseOptions', | ||||||||||||||||||||||||||||||||
| type: 'json', | ||||||||||||||||||||||||||||||||
| optional: true, | ||||||||||||||||||||||||||||||||
| description: 'Default headers to include with every request to the API.', | ||||||||||||||||||||||||||||||||
| additionalParams: true | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> { | ||||||||||||||||||||||||||||||||
| const temperature = nodeData.inputs?.temperature as string | ||||||||||||||||||||||||||||||||
| const modelName = nodeData.inputs?.modelName as string | ||||||||||||||||||||||||||||||||
| const maxTokens = nodeData.inputs?.maxTokens as string | ||||||||||||||||||||||||||||||||
| const topP = nodeData.inputs?.topP as string | ||||||||||||||||||||||||||||||||
| const frequencyPenalty = nodeData.inputs?.frequencyPenalty as string | ||||||||||||||||||||||||||||||||
| const presencePenalty = nodeData.inputs?.presencePenalty as string | ||||||||||||||||||||||||||||||||
| const timeout = nodeData.inputs?.timeout as string | ||||||||||||||||||||||||||||||||
| const streaming = nodeData.inputs?.streaming as boolean | ||||||||||||||||||||||||||||||||
| const basePath = (nodeData.inputs?.basepath as string) || 'https://router.requesty.ai/v1' | ||||||||||||||||||||||||||||||||
| const baseOptions = nodeData.inputs?.baseOptions | ||||||||||||||||||||||||||||||||
| const cache = nodeData.inputs?.cache as BaseCache | ||||||||||||||||||||||||||||||||
| const allowImageUploads = nodeData.inputs?.allowImageUploads as boolean | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const credentialData = await getCredentialData(nodeData.credential ?? '', options) | ||||||||||||||||||||||||||||||||
| const requestyApiKey = getCredentialParam('requestyApiKey', credentialData, nodeData) | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const obj: ChatOpenAIFields = { | ||||||||||||||||||||||||||||||||
| temperature: parseFloat(temperature), | ||||||||||||||||||||||||||||||||
| modelName, | ||||||||||||||||||||||||||||||||
| openAIApiKey: requestyApiKey, | ||||||||||||||||||||||||||||||||
| apiKey: requestyApiKey, | ||||||||||||||||||||||||||||||||
| streaming: streaming ?? true | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
Comment on lines
+150
to
+156
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If To prevent this, only set the
Suggested change
|
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (maxTokens) obj.maxTokens = parseInt(maxTokens, 10) | ||||||||||||||||||||||||||||||||
| if (topP) obj.topP = parseFloat(topP) | ||||||||||||||||||||||||||||||||
| if (frequencyPenalty) obj.frequencyPenalty = parseFloat(frequencyPenalty) | ||||||||||||||||||||||||||||||||
| if (presencePenalty) obj.presencePenalty = parseFloat(presencePenalty) | ||||||||||||||||||||||||||||||||
| if (timeout) obj.timeout = parseInt(timeout, 10) | ||||||||||||||||||||||||||||||||
| if (cache) obj.cache = cache | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| let parsedBaseOptions: any | undefined = undefined | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (baseOptions) { | ||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||
| parsedBaseOptions = typeof baseOptions === 'object' ? baseOptions : JSON.parse(baseOptions) | ||||||||||||||||||||||||||||||||
| } catch (exception) { | ||||||||||||||||||||||||||||||||
| throw new Error("Invalid JSON in the ChatRequesty's BaseOptions: " + exception) | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (basePath || parsedBaseOptions) { | ||||||||||||||||||||||||||||||||
| obj.configuration = { | ||||||||||||||||||||||||||||||||
| baseURL: basePath, | ||||||||||||||||||||||||||||||||
| defaultHeaders: parsedBaseOptions | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const multiModalOption: IMultiModalOption = { | ||||||||||||||||||||||||||||||||
| image: { | ||||||||||||||||||||||||||||||||
| allowImageUploads: allowImageUploads ?? false | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const model = new ChatRequesty(nodeData.id, obj) | ||||||||||||||||||||||||||||||||
| model.setMultiModalOption(multiModalOption) | ||||||||||||||||||||||||||||||||
| return model | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| module.exports = { nodeClass: ChatRequesty_ChatModels } | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import { ChatOpenAI as LangchainChatOpenAI, ChatOpenAIFields } from '@langchain/openai' | ||
| import { IMultiModalOption, IVisionChatModal } from '../../../src' | ||
|
|
||
| export class ChatRequesty extends LangchainChatOpenAI implements IVisionChatModal { | ||
| configuredModel: string | ||
| configuredMaxToken?: number | ||
| multiModalOption: IMultiModalOption | ||
| id: string | ||
|
|
||
| constructor(id: string, fields?: ChatOpenAIFields) { | ||
| super(fields) | ||
| this.id = id | ||
| this.configuredModel = fields?.modelName ?? '' | ||
| this.configuredMaxToken = fields?.maxTokens | ||
| } | ||
|
|
||
| setMultiModalOption(multiModalOption: IMultiModalOption): void { | ||
| this.multiModalOption = multiModalOption | ||
| } | ||
| } |
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.
The
descriptionproperty is declared on theRequestyAPIAuthclass but is never initialized in the constructor. This can lead toundefinedvalues at runtime or potential TypeScript issues. It is recommended to initialize it with a brief description of the credential.