Chore/Add base options to azure chat openai (#3886)

* add base options to azure chat openai

* add base options to embeddings
This commit is contained in:
Henry Heng
2025-01-20 18:29:27 +00:00
committed by GitHub
parent 9c2203be62
commit 320eab65d6
3 changed files with 65 additions and 8 deletions
@@ -1,10 +1,11 @@
import { AzureOpenAIInput, ChatOpenAI as LangchainChatOpenAI, OpenAIChatInput } from '@langchain/openai' import { AzureOpenAIInput, ChatOpenAI as LangchainChatOpenAI, OpenAIChatInput, ClientOptions, LegacyOpenAIInput } from '@langchain/openai'
import { BaseCache } from '@langchain/core/caches' import { BaseCache } from '@langchain/core/caches'
import { BaseLLMParams } from '@langchain/core/language_models/llms' import { BaseLLMParams } from '@langchain/core/language_models/llms'
import { ICommonObject, IMultiModalOption, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../src/Interface' import { ICommonObject, IMultiModalOption, INode, INodeData, INodeOptionsValue, INodeParams } from '../../../src/Interface'
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { ChatOpenAI } from '../ChatOpenAI/FlowiseChatOpenAI' import { ChatOpenAI } from '../ChatOpenAI/FlowiseChatOpenAI'
import { getModels, MODEL_TYPE } from '../../../src/modelLoader' import { getModels, MODEL_TYPE } from '../../../src/modelLoader'
import { BaseChatModelParams } from '@langchain/core/language_models/chat_models'
const serverCredentialsExists = const serverCredentialsExists =
!!process.env.AZURE_OPENAI_API_KEY && !!process.env.AZURE_OPENAI_API_KEY &&
@@ -27,7 +28,7 @@ class AzureChatOpenAI_ChatModels implements INode {
constructor() { constructor() {
this.label = 'Azure ChatOpenAI' this.label = 'Azure ChatOpenAI'
this.name = 'azureChatOpenAI' this.name = 'azureChatOpenAI'
this.version = 6.0 this.version = 7.0
this.type = 'AzureChatOpenAI' this.type = 'AzureChatOpenAI'
this.icon = 'Azure.svg' this.icon = 'Azure.svg'
this.category = 'Chat Models' this.category = 'Chat Models'
@@ -116,6 +117,13 @@ class AzureChatOpenAI_ChatModels implements INode {
optional: true, optional: true,
additionalParams: true additionalParams: true
}, },
{
label: 'BaseOptions',
name: 'baseOptions',
type: 'json',
optional: true,
additionalParams: true
},
{ {
label: 'Allow Image Uploads', label: 'Allow Image Uploads',
name: 'allowImageUploads', name: 'allowImageUploads',
@@ -169,6 +177,7 @@ class AzureChatOpenAI_ChatModels implements INode {
const cache = nodeData.inputs?.cache as BaseCache const cache = nodeData.inputs?.cache as BaseCache
const topP = nodeData.inputs?.topP as string const topP = nodeData.inputs?.topP as string
const basePath = nodeData.inputs?.basepath as string const basePath = nodeData.inputs?.basepath as string
const baseOptions = nodeData.inputs?.baseOptions
const credentialData = await getCredentialData(nodeData.credential ?? '', options) const credentialData = await getCredentialData(nodeData.credential ?? '', options)
const azureOpenAIApiKey = getCredentialParam('azureOpenAIApiKey', credentialData, nodeData) const azureOpenAIApiKey = getCredentialParam('azureOpenAIApiKey', credentialData, nodeData)
@@ -179,7 +188,10 @@ class AzureChatOpenAI_ChatModels implements INode {
const allowImageUploads = nodeData.inputs?.allowImageUploads as boolean const allowImageUploads = nodeData.inputs?.allowImageUploads as boolean
const imageResolution = nodeData.inputs?.imageResolution as string const imageResolution = nodeData.inputs?.imageResolution as string
const obj: Partial<AzureOpenAIInput> & BaseLLMParams & Partial<OpenAIChatInput> = { const obj: Partial<AzureOpenAIInput> &
BaseLLMParams &
Partial<OpenAIChatInput> &
BaseChatModelParams & { configuration?: ClientOptions & LegacyOpenAIInput } = {
temperature: parseFloat(temperature), temperature: parseFloat(temperature),
modelName, modelName,
azureOpenAIApiKey, azureOpenAIApiKey,
@@ -196,6 +208,16 @@ class AzureChatOpenAI_ChatModels implements INode {
if (cache) obj.cache = cache if (cache) obj.cache = cache
if (topP) obj.topP = parseFloat(topP) if (topP) obj.topP = parseFloat(topP)
if (basePath) obj.azureOpenAIBasePath = basePath if (basePath) obj.azureOpenAIBasePath = basePath
if (baseOptions) {
try {
const parsedBaseOptions = typeof baseOptions === 'object' ? baseOptions : JSON.parse(baseOptions)
obj.configuration = {
defaultHeaders: parsedBaseOptions
}
} catch (exception) {
console.error('Error parsing base options', exception)
}
}
const multiModalOption: IMultiModalOption = { const multiModalOption: IMultiModalOption = {
image: { image: {
@@ -1,4 +1,4 @@
import { AzureOpenAIInput, OpenAIEmbeddings, OpenAIEmbeddingsParams } from '@langchain/openai' import { AzureOpenAIInput, ClientOptions, LegacyOpenAIInput, OpenAIEmbeddings, OpenAIEmbeddingsParams } from '@langchain/openai'
import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface' import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface'
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
@@ -23,7 +23,7 @@ class AzureOpenAIEmbedding_Embeddings implements INode {
constructor() { constructor() {
this.label = 'Azure OpenAI Embeddings' this.label = 'Azure OpenAI Embeddings'
this.name = 'azureOpenAIEmbeddings' this.name = 'azureOpenAIEmbeddings'
this.version = 1.0 this.version = 2.0
this.type = 'AzureOpenAIEmbeddings' this.type = 'AzureOpenAIEmbeddings'
this.icon = 'Azure.svg' this.icon = 'Azure.svg'
this.category = 'Embeddings' this.category = 'Embeddings'
@@ -58,6 +58,13 @@ class AzureOpenAIEmbedding_Embeddings implements INode {
type: 'string', type: 'string',
optional: true, optional: true,
additionalParams: true additionalParams: true
},
{
label: 'BaseOptions',
name: 'baseOptions',
type: 'json',
optional: true,
additionalParams: true
} }
] ]
} }
@@ -66,6 +73,7 @@ class AzureOpenAIEmbedding_Embeddings implements INode {
const batchSize = nodeData.inputs?.batchSize as string const batchSize = nodeData.inputs?.batchSize as string
const timeout = nodeData.inputs?.timeout as string const timeout = nodeData.inputs?.timeout as string
const basePath = nodeData.inputs?.basepath as string const basePath = nodeData.inputs?.basepath as string
const baseOptions = nodeData.inputs?.baseOptions
const credentialData = await getCredentialData(nodeData.credential ?? '', options) const credentialData = await getCredentialData(nodeData.credential ?? '', options)
const azureOpenAIApiKey = getCredentialParam('azureOpenAIApiKey', credentialData, nodeData) const azureOpenAIApiKey = getCredentialParam('azureOpenAIApiKey', credentialData, nodeData)
@@ -73,7 +81,7 @@ class AzureOpenAIEmbedding_Embeddings implements INode {
const azureOpenAIApiDeploymentName = getCredentialParam('azureOpenAIApiDeploymentName', credentialData, nodeData) const azureOpenAIApiDeploymentName = getCredentialParam('azureOpenAIApiDeploymentName', credentialData, nodeData)
const azureOpenAIApiVersion = getCredentialParam('azureOpenAIApiVersion', credentialData, nodeData) const azureOpenAIApiVersion = getCredentialParam('azureOpenAIApiVersion', credentialData, nodeData)
const obj: Partial<OpenAIEmbeddingsParams> & Partial<AzureOpenAIInput> = { const obj: Partial<OpenAIEmbeddingsParams> & Partial<AzureOpenAIInput> & { configuration?: ClientOptions & LegacyOpenAIInput } = {
azureOpenAIApiKey, azureOpenAIApiKey,
azureOpenAIApiInstanceName, azureOpenAIApiInstanceName,
azureOpenAIApiDeploymentName, azureOpenAIApiDeploymentName,
@@ -83,6 +91,16 @@ class AzureOpenAIEmbedding_Embeddings implements INode {
if (batchSize) obj.batchSize = parseInt(batchSize, 10) if (batchSize) obj.batchSize = parseInt(batchSize, 10)
if (timeout) obj.timeout = parseInt(timeout, 10) if (timeout) obj.timeout = parseInt(timeout, 10)
if (baseOptions) {
try {
const parsedBaseOptions = typeof baseOptions === 'object' ? baseOptions : JSON.parse(baseOptions)
obj.configuration = {
defaultHeaders: parsedBaseOptions
}
} catch (exception) {
console.error('Error parsing base options', exception)
}
}
const model = new OpenAIEmbeddings(obj) const model = new OpenAIEmbeddings(obj)
return model return model
@@ -17,7 +17,7 @@ class OpenAIEmbeddingCustom_Embeddings implements INode {
constructor() { constructor() {
this.label = 'OpenAI Embeddings Custom' this.label = 'OpenAI Embeddings Custom'
this.name = 'openAIEmbeddingsCustom' this.name = 'openAIEmbeddingsCustom'
this.version = 2.0 this.version = 3.0
this.type = 'OpenAIEmbeddingsCustom' this.type = 'OpenAIEmbeddingsCustom'
this.icon = 'openai.svg' this.icon = 'openai.svg'
this.category = 'Embeddings' this.category = 'Embeddings'
@@ -58,6 +58,13 @@ class OpenAIEmbeddingCustom_Embeddings implements INode {
optional: true, optional: true,
additionalParams: true additionalParams: true
}, },
{
label: 'BaseOptions',
name: 'baseOptions',
type: 'json',
optional: true,
additionalParams: true
},
{ {
label: 'Model Name', label: 'Model Name',
name: 'modelName', name: 'modelName',
@@ -81,6 +88,7 @@ class OpenAIEmbeddingCustom_Embeddings implements INode {
const basePath = nodeData.inputs?.basepath as string const basePath = nodeData.inputs?.basepath as string
const modelName = nodeData.inputs?.modelName as string const modelName = nodeData.inputs?.modelName as string
const dimensions = nodeData.inputs?.dimensions as string const dimensions = nodeData.inputs?.dimensions as string
const baseOptions = nodeData.inputs?.baseOptions
const credentialData = await getCredentialData(nodeData.credential ?? '', options) const credentialData = await getCredentialData(nodeData.credential ?? '', options)
const openAIApiKey = getCredentialParam('openAIApiKey', credentialData, nodeData) const openAIApiKey = getCredentialParam('openAIApiKey', credentialData, nodeData)
@@ -95,7 +103,16 @@ class OpenAIEmbeddingCustom_Embeddings implements INode {
if (modelName) obj.modelName = modelName if (modelName) obj.modelName = modelName
if (dimensions) obj.dimensions = parseInt(dimensions, 10) if (dimensions) obj.dimensions = parseInt(dimensions, 10)
const model = new OpenAIEmbeddings(obj, { basePath }) 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 ChatOpenAI's BaseOptions: " + exception)
}
}
const model = new OpenAIEmbeddings(obj, { baseURL: basePath, defaultHeaders: parsedBaseOptions })
return model return model
} }
} }