update ui changes

This commit is contained in:
Henry 2023-12-21 17:28:25 +00:00
parent a2d4a3b8d0
commit f0cdf48d54
10 changed files with 223 additions and 42 deletions

View File

@ -85,26 +85,29 @@ class CustomTool_Tools implements INode {
// override variables defined in overrideConfig
// nodeData.inputs.variables is an Object, check each property and override the variable
if (nodeData?.inputs?.envVars) {
for (const propertyName of Object.getOwnPropertyNames(nodeData.inputs.envVars)) {
if (nodeData?.inputs?.vars) {
for (const propertyName of Object.getOwnPropertyNames(nodeData.inputs.vars)) {
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.envVars[propertyName]
foundVar.value = nodeData.inputs.vars[propertyName]
} else {
// add it the variables, if not found locally in the db
variables.push({ name: propertyName, type: 'static', value: nodeData.inputs.envVars[propertyName] })
variables.push({ name: propertyName, type: 'static', value: nodeData.inputs.vars[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) {
throw new Error(e)

View File

@ -102,15 +102,19 @@ export class DynamicStructuredTool<
sandbox[`$${item}`] = arg[item]
}
}
//inject variables
let env = {}
// inject variables
let vars = {}
if (this.variables) {
for (const item of this.variables) {
let value = item.value
// read from .env file
if (item.type === 'runtime') {
value = process.env[item.name]
}
Object.defineProperty(env, item.name, {
Object.defineProperty(vars, item.name, {
enumerable: true,
configurable: true,
writable: true,
@ -118,10 +122,13 @@ export class DynamicStructuredTool<
})
}
}
sandbox['$env'] = env
sandbox['$vars'] = vars
// inject flow properties
if (this.flowObj) {
sandbox['$flow'] = { ...this.flowObj, sessionId: overrideSessionId }
}
const defaultAllowBuiltInDep = [
'assert',
'buffer',

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -53,7 +53,7 @@ const dashboard = {
},
{
id: 'variables',
title: 'Environment Variables',
title: 'Variables',
type: 'item',
url: '/variables',
icon: icons.IconVariable,

View File

@ -369,7 +369,12 @@ const NodeInputHandler = ({ inputAnchor, inputParam, data, disabled = false, isA
{inputParam?.acceptVariable && (
<>
<Button
sx={{ borderRadius: 25, width: '100%', mb: 0, mt: 2 }}
sx={{
borderRadius: 25,
width: '100%',
mb: 0,
mt: 2
}}
variant='outlined'
disabled={disabled}
onClick={() => onEditJSONClicked(data.inputs[inputParam.name] ?? '', inputParam)}

View File

@ -0,0 +1,65 @@
import { createPortal } from 'react-dom'
import PropTypes from 'prop-types'
import { Dialog, DialogContent, DialogTitle } from '@mui/material'
const HowToUseFunctionDialog = ({ show, onCancel }) => {
const portalElement = document.getElementById('portal')
const component = show ? (
<Dialog
onClose={onCancel}
open={show}
fullWidth
maxWidth='sm'
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle sx={{ fontSize: '1rem' }} id='alert-dialog-title'>
How To Use Function
</DialogTitle>
<DialogContent>
<ul>
<li style={{ marginTop: 10 }}>You can use any libraries imported in Flowise</li>
<li style={{ marginTop: 10 }}>
You can use properties specified in Output Schema as variables with prefix $:
<ul style={{ marginTop: 10 }}>
<li>
Property = <code>userid</code>
</li>
<li>
Variable = <code>$userid</code>
</li>
</ul>
</li>
<li style={{ marginTop: 10 }}>
You can get default flow config:
<ul style={{ marginTop: 10 }}>
<li>
<code>$flow.sessionId</code>
</li>
<li>
<code>$flow.chatId</code>
</li>
<li>
<code>$flow.chatflowId</code>
</li>
</ul>
</li>
<li style={{ marginTop: 10 }}>
You can get custom variables:&nbsp;<code>{`$vars.<variable-name>`}</code>
</li>
<li style={{ marginTop: 10 }}>Must return a string value at the end of function</li>
</ul>
</DialogContent>
</Dialog>
) : null
return createPortal(component, portalElement)
}
HowToUseFunctionDialog.propTypes = {
show: PropTypes.bool,
onCancel: PropTypes.func
}
export default HowToUseFunctionDialog

View File

@ -13,6 +13,7 @@ import { GridActionsCellItem } from '@mui/x-data-grid'
import DeleteIcon from '@mui/icons-material/Delete'
import ConfirmDialog from 'ui-component/dialog/ConfirmDialog'
import { CodeEditor } from 'ui-component/editor/CodeEditor'
import HowToUseFunctionDialog from './HowToUseFunctionDialog'
// Icons
import { IconX, IconFileExport } from '@tabler/icons'
@ -32,6 +33,8 @@ import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
const exampleAPIFunc = `/*
* You can use any libraries imported in Flowise
* You can use properties specified in Output Schema as variables. Ex: Property = userid, Variable = $userid
* You can get default flow config: $flow.sessionId, $flow.chatId, $flow.chatflowId
* You can get custom variables: $vars.<variable-name>
* Must return a string value at the end of function
*/
@ -74,6 +77,7 @@ const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) =
const [toolIcon, setToolIcon] = useState('')
const [toolSchema, setToolSchema] = useState([])
const [toolFunc, setToolFunc] = useState('')
const [showHowToDialog, setShowHowToDialog] = useState(false)
const deleteItem = useCallback(
(id) => () => {
@ -482,6 +486,14 @@ const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) =
/>
</Typography>
</Stack>
<Button
style={{ marginBottom: 10, marginRight: 10 }}
color='secondary'
variant='outlined'
onClick={() => setShowHowToDialog(true)}
>
How to use Function
</Button>
{dialogProps.type !== 'TEMPLATE' && (
<Button style={{ marginBottom: 10 }} variant='outlined' onClick={() => setToolFunc(exampleAPIFunc)}>
See Example
@ -519,6 +531,7 @@ const ToolDialog = ({ show, dialogProps, onUseTemplate, onCancel, onConfirm }) =
)}
</DialogActions>
<ConfirmDialog />
<HowToUseFunctionDialog show={showHowToDialog} onCancel={() => setShowHowToDialog(false)} />
</Dialog>
) : null

View File

@ -24,17 +24,18 @@ import useNotifier from 'utils/useNotifier'
// const
import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions'
import { TooltipWithParser } from '../../ui-component/tooltip/TooltipWithParser'
import { Dropdown } from '../../ui-component/dropdown/Dropdown'
const variableTypes = [
{
label: 'Static Variable',
name: 'static'
label: 'Static',
name: 'static',
description: 'Variable value will be read from the value entered below'
},
{
label: 'Runtime Variable',
name: 'runtime'
label: 'Runtime',
name: 'runtime',
description: 'Variable value will be read from .env file'
}
]
@ -208,6 +209,8 @@ const AddEditVariableDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
<div style={{ flexGrow: 1 }}></div>
</div>
<OutlinedInput
size='small'
sx={{ mt: 1 }}
type='string'
fullWidth
key='variableName'
@ -215,23 +218,6 @@ const AddEditVariableDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
value={variableName ?? ''}
/>
</Box>
<Box sx={{ p: 2 }}>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Typography>
Value
<TooltipWithParser style={{ marginLeft: 10 }} title='Value is mandatory for static variables.' />
</Typography>
<div style={{ flexGrow: 1 }}></div>
</div>
<OutlinedInput
type='string'
fullWidth
key='variableValue'
onChange={(e) => setVariableValue(e.target.value)}
value={variableValue ?? ''}
/>
<Typography variant='subtitle2'>Leave the value empty for runtime variables. Will be populated at runtime.</Typography>
</Box>
<Box sx={{ p: 2 }}>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Typography>
@ -245,14 +231,30 @@ const AddEditVariableDialog = ({ show, dialogProps, onCancel, onConfirm }) => {
onSelect={(newValue) => setVariableType(newValue)}
value={variableType}
/>
<Typography variant='subtitle2'>
Runtime: Value would be populated from env. Static: Value would be used as is.
</Typography>
</Box>
{variableType === 'static' && (
<Box sx={{ p: 2 }}>
<div style={{ display: 'flex', flexDirection: 'row' }}>
<Typography>
Value<span style={{ color: 'red' }}>&nbsp;*</span>
</Typography>
<div style={{ flexGrow: 1 }}></div>
</div>
<OutlinedInput
size='small'
sx={{ mt: 1 }}
type='string'
fullWidth
key='variableValue'
onChange={(e) => setVariableValue(e.target.value)}
value={variableValue ?? ''}
/>
</Box>
)}
</DialogContent>
<DialogActions>
<StyledButton
disabled={!variableName || (variableType === 'static' && !variableValue)}
disabled={!variableName || !variableType || (variableType === 'static' && !variableValue)}
variant='contained'
onClick={() => (dialogType === 'ADD' ? addNewVariable() : saveVariable())}
>

View File

@ -0,0 +1,72 @@
import { createPortal } from 'react-dom'
import PropTypes from 'prop-types'
import { Dialog, DialogContent, DialogTitle } from '@mui/material'
import { CodeEditor } from 'ui-component/editor/CodeEditor'
const overrideConfig = `{
overrideConfig: {
vars: {
var1: 'abc'
}
}
}`
const HowToUseVariablesDialog = ({ show, onCancel }) => {
const portalElement = document.getElementById('portal')
const component = show ? (
<Dialog
onClose={onCancel}
open={show}
fullWidth
maxWidth='sm'
aria-labelledby='alert-dialog-title'
aria-describedby='alert-dialog-description'
>
<DialogTitle sx={{ fontSize: '1rem' }} id='alert-dialog-title'>
How To Use Variables
</DialogTitle>
<DialogContent>
<p style={{ marginBottom: '10px' }}>Variables can be used in Custom Tool Function with the $ prefix.</p>
<CodeEditor
disabled={true}
value={`$vars.<variable-name>`}
height={'50px'}
theme={'dark'}
lang={'js'}
basicSetup={{ highlightActiveLine: false, highlightActiveLineGutter: false }}
/>
<p style={{ marginBottom: '10px' }}>
If variable type is Static, the value will be retrieved as it is. If variable type is Runtime, the value will be
retrieved from .env file.
</p>
<p style={{ marginBottom: '10px' }}>
You can also override variable values in API overrideConfig using <b>vars</b>:
</p>
<CodeEditor
disabled={true}
value={overrideConfig}
height={'170px'}
theme={'dark'}
lang={'js'}
basicSetup={{ highlightActiveLine: false, highlightActiveLineGutter: false }}
/>
<p>
Read more from{' '}
<a target='_blank' rel='noreferrer' href='https://docs.flowiseai.com/using-flowise/variables'>
docs
</a>
</p>
</DialogContent>
</Dialog>
) : null
return createPortal(component, portalElement)
}
HowToUseVariablesDialog.propTypes = {
show: PropTypes.bool,
onCancel: PropTypes.func
}
export default HowToUseVariablesDialog

View File

@ -19,7 +19,8 @@ import {
Toolbar,
TextField,
InputAdornment,
ButtonGroup
ButtonGroup,
Chip
} from '@mui/material'
import { useTheme } from '@mui/material/styles'
@ -40,10 +41,11 @@ import useNotifier from 'utils/useNotifier'
// Icons
import { IconTrash, IconEdit, IconX, IconPlus, IconSearch, IconVariable } from '@tabler/icons'
import CredentialEmptySVG from 'assets/images/credential_empty.svg'
import VariablesEmptySVG from 'assets/images/variables_empty.svg'
// const
import AddEditVariableDialog from './AddEditVariableDialog'
import HowToUseVariablesDialog from './HowToUseVariablesDialog'
// ==============================|| Credentials ||============================== //
@ -60,6 +62,7 @@ const Variables = () => {
const [showVariableDialog, setShowVariableDialog] = useState(false)
const [variableDialogProps, setVariableDialogProps] = useState({})
const [variables, setVariables] = useState([])
const [showHowToDialog, setShowHowToDialog] = useState(false)
const { confirm } = useConfirm()
@ -173,7 +176,7 @@ const Variables = () => {
width: '100%'
}}
>
<h1>Environment Variables&nbsp;</h1>
<h1>Variables&nbsp;</h1>
<TextField
size='small'
sx={{ display: { xs: 'none', sm: 'block' }, ml: 3 }}
@ -189,6 +192,9 @@ const Variables = () => {
}}
/>
<Box sx={{ flexGrow: 1 }} />
<Button variant='outlined' sx={{ mr: 2 }} onClick={() => setShowHowToDialog(true)}>
How To Use
</Button>
<ButtonGroup
sx={{ maxHeight: 40 }}
disableElevation
@ -214,8 +220,8 @@ const Variables = () => {
<Box sx={{ p: 2, height: 'auto' }}>
<img
style={{ objectFit: 'cover', height: '30vh', width: 'auto' }}
src={CredentialEmptySVG}
alt='CredentialEmptySVG'
src={VariablesEmptySVG}
alt='VariablesEmptySVG'
/>
</Box>
<div>No Variables Yet</div>
@ -267,7 +273,13 @@ const Variables = () => {
</div>
</TableCell>
<TableCell>{variable.value}</TableCell>
<TableCell>{variable.type === 'static' ? 'Static Variable' : 'Runtime Variable'}</TableCell>
<TableCell>
<Chip
color={variable.type === 'static' ? 'info' : 'secondary'}
size='small'
label={variable.type}
/>
</TableCell>
<TableCell>{moment(variable.updatedDate).format('DD-MMM-YY')}</TableCell>
<TableCell>{moment(variable.createdDate).format('DD-MMM-YY')}</TableCell>
<TableCell>
@ -293,6 +305,7 @@ const Variables = () => {
onCancel={() => setShowVariableDialog(false)}
onConfirm={onConfirm}
></AddEditVariableDialog>
<HowToUseVariablesDialog show={showHowToDialog} onCancel={() => setShowHowToDialog(false)}></HowToUseVariablesDialog>
<ConfirmDialog />
</>
)