Environment Variables: injection of variables ($env) into the custom tool and addition of ($flow) object

This commit is contained in:
vinodkiran
2023-12-12 12:19:35 +05:30
parent 0bf5536095
commit bfa870e56b
5 changed files with 69 additions and 12 deletions
@@ -80,7 +80,32 @@ class CustomTool_Tools implements INode {
code: tool.func code: tool.func
} }
if (customToolFunc) obj.code = customToolFunc if (customToolFunc) obj.code = customToolFunc
return new DynamicStructuredTool(obj)
const variables = await appDataSource.getRepository(databaseEntities['Variable']).find()
// override variables defined in overrideConfig
// nodeData.inputs.variables is an Object, check each property and override the variable
if (nodeData?.inputs?.variables) {
for (const propertyName of Object.getOwnPropertyNames(nodeData.inputs.variables)) {
const foundVar = variables.find((v) => v.name === propertyName)
if (foundVar) {
// even if the variable was defined as runtime, we override it with static value
foundVar.type = 'static'
foundVar.value = nodeData.inputs.variables[propertyName]
} else {
// add it the variables, if not found locally in the db
variables.push({ name: propertyName, type: 'static', value: nodeData.inputs.variables[propertyName] })
}
}
}
const flow = {
chatId: options.chatId, // id is uppercase (I)
chatflowId: options.chatflowid // id is lowercase (i)
}
let dynamicStructuredTool = new DynamicStructuredTool(obj)
dynamicStructuredTool.setVariables(variables)
dynamicStructuredTool.setFlowObject(flow)
return dynamicStructuredTool
} catch (e) { } catch (e) {
throw new Error(e) throw new Error(e)
} }
@@ -2,6 +2,7 @@ import { z } from 'zod'
import { CallbackManagerForToolRun } from 'langchain/callbacks' import { CallbackManagerForToolRun } from 'langchain/callbacks'
import { StructuredTool, ToolParams } from 'langchain/tools' import { StructuredTool, ToolParams } from 'langchain/tools'
import { NodeVM } from 'vm2' import { NodeVM } from 'vm2'
import { logger } from "@zilliz/milvus2-sdk-node";
/* /*
* List of dependencies allowed to be import in vm2 * List of dependencies allowed to be import in vm2
@@ -62,6 +63,8 @@ export class DynamicStructuredTool<
func: DynamicStructuredToolInput['func'] func: DynamicStructuredToolInput['func']
schema: T schema: T
private variables: any[]
private flowObj: any
constructor(fields: DynamicStructuredToolInput<T>) { constructor(fields: DynamicStructuredToolInput<T>) {
super(fields) super(fields)
@@ -80,8 +83,26 @@ export class DynamicStructuredTool<
sandbox[`$${item}`] = arg[item] sandbox[`$${item}`] = arg[item]
} }
} }
sandbox['$env'] = { USER: 'VINOD' } //inject variables
console.log('sandbox === ' + JSON.stringify(sandbox)) let env = {}
if (this.variables) {
for (const item of this.variables) {
let value = item.value
if (item.type === 'runtime') {
value = process.env[item.name]
}
Object.defineProperty(env, item.name, {
enumerable: true,
configurable: true,
writable: true,
value: value
})
}
}
sandbox['$env'] = env
if (this.flowObj) {
sandbox['$flow'] = this.flowObj
}
const defaultAllowBuiltInDep = [ const defaultAllowBuiltInDep = [
'assert', 'assert',
'buffer', 'buffer',
@@ -118,4 +139,12 @@ export class DynamicStructuredTool<
return response return response
} }
setVariables(variables: any[]) {
this.variables = variables
}
setFlowObject(flow: any) {
this.flowObj = flow
}
} }
+1
View File
@@ -73,6 +73,7 @@ export interface INodeParams {
additionalParams?: boolean additionalParams?: boolean
loadMethod?: string loadMethod?: string
hidden?: boolean hidden?: boolean
variables?: ICommonObject[]
} }
export interface INodeExecutionData { export interface INodeExecutionData {
+3 -1
View File
@@ -37,6 +37,7 @@ import { Tool } from '../database/entities/Tool'
import { Assistant } from '../database/entities/Assistant' import { Assistant } from '../database/entities/Assistant'
import { DataSource } from 'typeorm' import { DataSource } from 'typeorm'
import { CachePool } from '../CachePool' import { CachePool } from '../CachePool'
import { Variable } from '../database/entities/Variable'
const QUESTION_VAR_PREFIX = 'question' const QUESTION_VAR_PREFIX = 'question'
const CHAT_HISTORY_VAR_PREFIX = 'chat_history' const CHAT_HISTORY_VAR_PREFIX = 'chat_history'
@@ -47,7 +48,8 @@ export const databaseEntities: IDatabaseEntity = {
ChatMessage: ChatMessage, ChatMessage: ChatMessage,
Tool: Tool, Tool: Tool,
Credential: Credential, Credential: Credential,
Assistant: Assistant Assistant: Assistant,
Variable: Variable
} }
/** /**
@@ -62,13 +62,13 @@ const AddEditVariableDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
setName(dialogProps.data.name) setName(dialogProps.data.name)
setValue(dialogProps.data.value) setValue(dialogProps.data.value)
setType(dialogProps.data.type) setType(dialogProps.data.type)
//setVariable(dialogProps.data) setVariable(dialogProps.data)
} else if (dialogProps.type === 'ADD' && dialogProps.data) { } else if (dialogProps.type === 'ADD' && dialogProps.data) {
// When variable dialog is to add a new variable // When variable dialog is to add a new variable
setName('') setName('')
setValue('') setValue('')
setType('static') setType('static')
//setVariable({ name: '', value: '', type: 'static' }) setVariable({ name: '', value: '', type: 'static' })
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -83,9 +83,9 @@ const AddEditVariableDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
const addNewVariable = async () => { const addNewVariable = async () => {
try { try {
const obj = { const obj = {
name, name: name,
value, value: value,
type type: type
} }
const createResp = await variablesApi.createVariable(obj) const createResp = await variablesApi.createVariable(obj)
if (createResp.data) { if (createResp.data) {
@@ -125,9 +125,9 @@ const AddEditVariableDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
const saveVariable = async () => { const saveVariable = async () => {
try { try {
const saveObj = { const saveObj = {
name, name: name,
value, value: value,
type type: type
} }
const saveResp = await variablesApi.updateVariable(variable.id, saveObj) const saveResp = await variablesApi.updateVariable(variable.id, saveObj)