mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 15:00:57 +03:00
Refactor/Update code execution sandbox implementation across components (#4904)
refactor: Update code execution sandbox implementation across components - Replaced NodeVM usage with a new createCodeExecutionSandbox function for improved sandbox management. - Enhanced JavaScript code execution with executeJavaScriptCode function, allowing for better handling of libraries and output streaming. - Updated multiple components to utilize the new sandboxing approach, ensuring consistent execution environment. - Added validation for UUIDs and URLs in various tools to enhance input safety. - Refactored input handling in CustomFunction and IfElseFunction to streamline variable management.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { get } from 'lodash'
|
||||
import { z } from 'zod'
|
||||
import { DataSource } from 'typeorm'
|
||||
import { NodeVM } from '@flowiseai/nodevm'
|
||||
import { StructuredTool } from '@langchain/core/tools'
|
||||
import { ChatMistralAI } from '@langchain/mistralai'
|
||||
import { ChatAnthropic } from '@langchain/anthropic'
|
||||
@@ -17,7 +16,7 @@ import {
|
||||
IVisionChatModal,
|
||||
ConversationHistorySelection
|
||||
} from '../../src/Interface'
|
||||
import { availableDependencies, defaultAllowBuiltInDep, getVars, prepareSandboxVars } from '../../src/utils'
|
||||
import { getVars, executeJavaScriptCode, createCodeExecutionSandbox } from '../../src/utils'
|
||||
import { ChatPromptTemplate, BaseMessagePromptTemplateLike } from '@langchain/core/prompts'
|
||||
|
||||
export const checkCondition = (input: string | number | undefined, condition: string, value: string | number = ''): boolean => {
|
||||
@@ -150,46 +149,6 @@ export const processImageMessage = async (llm: BaseChatModel, nodeData: INodeDat
|
||||
return multiModalMessageContent
|
||||
}
|
||||
|
||||
export const getVM = async (
|
||||
appDataSource: DataSource,
|
||||
databaseEntities: IDatabaseEntity,
|
||||
nodeData: INodeData,
|
||||
options: ICommonObject,
|
||||
flow: ICommonObject
|
||||
) => {
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
|
||||
let sandbox: any = {
|
||||
util: undefined,
|
||||
Symbol: undefined,
|
||||
child_process: undefined,
|
||||
fs: undefined,
|
||||
process: undefined
|
||||
}
|
||||
sandbox['$vars'] = prepareSandboxVars(variables)
|
||||
sandbox['$flow'] = flow
|
||||
|
||||
const builtinDeps = process.env.TOOL_FUNCTION_BUILTIN_DEP
|
||||
? defaultAllowBuiltInDep.concat(process.env.TOOL_FUNCTION_BUILTIN_DEP.split(','))
|
||||
: defaultAllowBuiltInDep
|
||||
const externalDeps = process.env.TOOL_FUNCTION_EXTERNAL_DEP ? process.env.TOOL_FUNCTION_EXTERNAL_DEP.split(',') : []
|
||||
const deps = availableDependencies.concat(externalDeps)
|
||||
|
||||
const nodeVMOptions = {
|
||||
console: 'inherit',
|
||||
sandbox,
|
||||
require: {
|
||||
external: { modules: deps },
|
||||
builtin: builtinDeps
|
||||
},
|
||||
eval: false,
|
||||
wasm: false,
|
||||
timeout: 10000
|
||||
} as any
|
||||
|
||||
return new NodeVM(nodeVMOptions)
|
||||
}
|
||||
|
||||
export const customGet = (obj: any, path: string) => {
|
||||
if (path.includes('[-1]')) {
|
||||
const parts = path.split('.')
|
||||
@@ -426,9 +385,21 @@ export const checkMessageHistory = async (
|
||||
if (messageHistory) {
|
||||
const appDataSource = options.appDataSource as DataSource
|
||||
const databaseEntities = options.databaseEntities as IDatabaseEntity
|
||||
const vm = await getVM(appDataSource, databaseEntities, nodeData, options, {})
|
||||
|
||||
const variables = await getVars(appDataSource, databaseEntities, nodeData, options)
|
||||
const flow = {
|
||||
chatflowId: options.chatflowid,
|
||||
sessionId: options.sessionId,
|
||||
chatId: options.chatId
|
||||
}
|
||||
|
||||
const sandbox = createCodeExecutionSandbox('', variables, flow)
|
||||
|
||||
try {
|
||||
const response = await vm.run(`module.exports = async function() {${messageHistory}}()`, __dirname)
|
||||
const response = await executeJavaScriptCode(messageHistory, sandbox, {
|
||||
timeout: 10000
|
||||
})
|
||||
|
||||
if (!Array.isArray(response)) throw new Error('Returned message history must be an array')
|
||||
if (sysPrompt) {
|
||||
// insert at index 1
|
||||
|
||||
Reference in New Issue
Block a user