Bugfix/Generator Prompt Markdown Format (#4592)

* add ui fixes

* refactor: update image structure in CustomAssistantLayout to use object format
This commit is contained in:
Henry Heng 2025-06-06 18:07:43 +01:00 committed by GitHub
parent 8793ed628c
commit 2cd8db0c53
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 234 additions and 52 deletions

View File

@ -68,6 +68,7 @@
"rehype-raw": "^7.0.0",
"remark-gfm": "^3.0.1",
"remark-math": "^5.1.1",
"showdown": "^2.1.0",
"tippy.js": "^6.3.7",
"uuid": "^9.0.1",
"yup": "^0.32.9"

View File

@ -15,7 +15,7 @@ import { Dropdown } from '@/ui-component/dropdown/Dropdown'
import { useTheme } from '@mui/material/styles'
import assistantsApi from '@/api/assistants'
import { baseURL } from '@/store/constant'
import { initNode } from '@/utils/genericHelper'
import { initNode, showHideInputParams } from '@/utils/genericHelper'
import DocStoreInputHandler from '@/views/docstore/DocStoreInputHandler'
import useApi from '@/hooks/useApi'
@ -55,6 +55,15 @@ const AgentflowGeneratorDialog = ({ show, dialogProps, onCancel, onConfirm }) =>
const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args))
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
const handleChatModelDataChange = ({ inputParam, newValue }) => {
setSelectedChatModel((prevData) => {
const updatedData = { ...prevData }
updatedData.inputs[inputParam.name] = newValue
updatedData.inputParams = showHideInputParams(updatedData)
return updatedData
})
}
useEffect(() => {
if (getChatModelsApi.data) {
setChatModelsComponents(getChatModelsApi.data)
@ -303,10 +312,15 @@ const AgentflowGeneratorDialog = ({ show, dialogProps, onCancel, onConfirm }) =>
borderRadius: 2
}}
>
{(selectedChatModel.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
{showHideInputParams(selectedChatModel)
.filter((inputParam) => !inputParam.hidden && inputParam.display !== false)
.map((inputParam, index) => (
<DocStoreInputHandler key={index} inputParam={inputParam} data={selectedChatModel} />
<DocStoreInputHandler
key={index}
inputParam={inputParam}
data={selectedChatModel}
onNodeDataChange={handleChatModelDataChange}
/>
))}
</Box>
)}

View File

@ -81,7 +81,11 @@ const NodeInfoDialog = ({ show, dialogProps, onCancel }) => {
height: 50,
marginRight: 10,
borderRadius: '50%',
backgroundColor: 'white'
backgroundColor: 'white',
flexShrink: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<img

View File

@ -379,7 +379,11 @@ const SpeechToText = ({ dialogProps }) => {
width: 50,
height: 50,
borderRadius: '50%',
backgroundColor: 'white'
backgroundColor: 'white',
flexShrink: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<img

View File

@ -53,7 +53,7 @@ import { baseURL } from '@/store/constant'
import { SET_CHATFLOW, closeSnackbar as closeSnackbarAction, enqueueSnackbar as enqueueSnackbarAction } from '@/store/actions'
// Utils
import { initNode } from '@/utils/genericHelper'
import { initNode, showHideInputParams } from '@/utils/genericHelper'
import useNotifier from '@/utils/useNotifier'
import { toolAgentFlow } from './toolAgentFlow'
@ -127,6 +127,28 @@ const CustomAssistantConfigurePreview = () => {
const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args))
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
const handleChatModelDataChange = ({ inputParam, newValue }) => {
setSelectedChatModel((prevData) => {
const updatedData = { ...prevData }
updatedData.inputs[inputParam.name] = newValue
updatedData.inputParams = showHideInputParams(updatedData)
return updatedData
})
}
const handleToolDataChange =
(toolIndex) =>
({ inputParam, newValue }) => {
setSelectedTools((prevTools) => {
const updatedTools = [...prevTools]
const updatedTool = { ...updatedTools[toolIndex] }
updatedTool.inputs[inputParam.name] = newValue
updatedTool.inputParams = showHideInputParams(updatedTool)
updatedTools[toolIndex] = updatedTool
return updatedTools
})
}
const displayWarning = () => {
enqueueSnackbar({
message: 'Please fill in all mandatory fields.',
@ -1126,13 +1148,14 @@ const CustomAssistantConfigurePreview = () => {
borderRadius: 2
}}
>
{(selectedChatModel.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
{showHideInputParams(selectedChatModel)
.filter((inputParam) => !inputParam.hidden && inputParam.display !== false)
.map((inputParam, index) => (
<DocStoreInputHandler
key={index}
inputParam={inputParam}
data={selectedChatModel}
onNodeDataChange={handleChatModelDataChange}
/>
))}
</Box>
@ -1217,13 +1240,16 @@ const CustomAssistantConfigurePreview = () => {
mb: 1
}}
>
{(tool.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
.map((inputParam, index) => (
{showHideInputParams(tool)
.filter(
(inputParam) => !inputParam.hidden && inputParam.display !== false
)
.map((inputParam, inputIndex) => (
<DocStoreInputHandler
key={index}
key={inputIndex}
inputParam={inputParam}
data={tool}
onNodeDataChange={handleToolDataChange(index)}
/>
))}
</Box>

View File

@ -64,7 +64,9 @@ const CustomAssistantLayout = () => {
const getImages = (details) => {
const images = []
if (details && details.chatModel && details.chatModel.name) {
images.push(`${baseURL}/api/v1/node-icon/${details.chatModel.name}`)
images.push({
imageSrc: `${baseURL}/api/v1/node-icon/${details.chatModel.name}`
})
}
return images
}

View File

@ -3,6 +3,7 @@ import { Handle, Position, useUpdateNodeInternals } from 'reactflow'
import { useEffect, useRef, useState, useContext } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { cloneDeep } from 'lodash'
import showdown from 'showdown'
// material-ui
import { useTheme, styled } from '@mui/material/styles'
@ -98,6 +99,13 @@ const StyledPopper = styled(Popper)({
}
})
const markdownConverter = new showdown.Converter({
simplifiedAutoLink: true,
strikethrough: true,
tables: true,
tasklists: true
})
// ===========================|| NodeInputHandler ||=========================== //
const NodeInputHandler = ({
@ -1389,7 +1397,12 @@ const NodeInputHandler = ({
onCancel={() => setPromptGeneratorDialogOpen(false)}
onConfirm={(generatedInstruction) => {
try {
data.inputs[inputParam.name] = generatedInstruction
if (inputParam?.acceptVariable && window.location.href.includes('v2/agentcanvas')) {
const htmlContent = markdownConverter.makeHtml(generatedInstruction)
data.inputs[inputParam.name] = htmlContent
} else {
data.inputs[inputParam.name] = generatedInstruction
}
setPromptGeneratorDialogOpen(false)
} catch (error) {
enqueueSnackbar({

View File

@ -140,7 +140,11 @@ const CredentialListDialog = ({ show, dialogProps, onCancel, onCredentialSelecte
width: 50,
height: 50,
borderRadius: '50%',
backgroundColor: 'white'
backgroundColor: 'white',
flexShrink: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<img

View File

@ -153,7 +153,11 @@ const ComponentsListDialog = ({ show, dialogProps, onCancel, apiCall, onSelected
width: 50,
height: 50,
borderRadius: '50%',
backgroundColor: 'white'
backgroundColor: 'white',
flexShrink: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<img

View File

@ -1,5 +1,5 @@
import PropTypes from 'prop-types'
import { useState } from 'react'
import { useState, useContext } from 'react'
import { useSelector } from 'react-redux'
// material-ui
@ -20,14 +20,17 @@ import { CodeEditor } from '@/ui-component/editor/CodeEditor'
import ExpandTextDialog from '@/ui-component/dialog/ExpandTextDialog'
import ManageScrapedLinksDialog from '@/ui-component/dialog/ManageScrapedLinksDialog'
import CredentialInputHandler from '@/views/canvas/CredentialInputHandler'
import { flowContext } from '@/store/context/ReactFlowContext'
// const
import { FLOWISE_CREDENTIAL_ID } from '@/store/constant'
// ===========================|| DocStoreInputHandler ||=========================== //
const DocStoreInputHandler = ({ inputParam, data, disabled = false }) => {
const DocStoreInputHandler = ({ inputParam, data, disabled = false, onNodeDataChange }) => {
const customization = useSelector((state) => state.customization)
const flowContextValue = useContext(flowContext)
const nodeDataChangeHandler = onNodeDataChange || flowContextValue?.onNodeDataChange
const [showExpandDialog, setShowExpandDialog] = useState(false)
const [expandDialogProps, setExpandDialogProps] = useState({})
@ -35,6 +38,14 @@ const DocStoreInputHandler = ({ inputParam, data, disabled = false }) => {
const [manageScrapedLinksDialogProps, setManageScrapedLinksDialogProps] = useState({})
const [reloadTimestamp, setReloadTimestamp] = useState(Date.now().toString())
const handleDataChange = ({ inputParam, newValue }) => {
data.inputs[inputParam.name] = newValue
const allowedShowHideInputTypes = ['boolean', 'asyncOptions', 'asyncMultiOptions', 'options', 'multiOptions']
if (allowedShowHideInputTypes.includes(inputParam.type) && nodeDataChangeHandler) {
nodeDataChangeHandler({ nodeId: data.id, inputParam, newValue })
}
}
const onExpandDialogClicked = (value, inputParam) => {
const dialogProps = {
value,
@ -149,7 +160,7 @@ const DocStoreInputHandler = ({ inputParam, data, disabled = false }) => {
{inputParam.type === 'boolean' && (
<SwitchInput
disabled={disabled}
onChange={(newValue) => (data.inputs[inputParam.name] = newValue)}
onChange={(newValue) => handleDataChange({ inputParam, newValue })}
value={data.inputs[inputParam.name] ?? inputParam.default ?? false}
/>
)}
@ -203,7 +214,7 @@ const DocStoreInputHandler = ({ inputParam, data, disabled = false }) => {
disabled={disabled}
name={inputParam.name}
options={inputParam.options}
onSelect={(newValue) => (data.inputs[inputParam.name] = newValue)}
onSelect={(newValue) => handleDataChange({ inputParam, newValue })}
value={data.inputs[inputParam.name] ?? inputParam.default ?? 'choose an option'}
/>
)}
@ -213,7 +224,7 @@ const DocStoreInputHandler = ({ inputParam, data, disabled = false }) => {
disabled={disabled}
name={inputParam.name}
options={inputParam.options}
onSelect={(newValue) => (data.inputs[inputParam.name] = newValue)}
onSelect={(newValue) => handleDataChange({ inputParam, newValue })}
value={data.inputs[inputParam.name] ?? inputParam.default ?? 'choose an option'}
/>
)}
@ -230,7 +241,7 @@ const DocStoreInputHandler = ({ inputParam, data, disabled = false }) => {
freeSolo={inputParam.freeSolo}
multiple={inputParam.type === 'asyncMultiOptions'}
value={data.inputs[inputParam.name] ?? inputParam.default ?? 'choose an option'}
onSelect={(newValue) => (data.inputs[inputParam.name] = newValue)}
onSelect={(newValue) => handleDataChange({ inputParam, newValue })}
onCreateNew={() => addAsyncOption(inputParam.name)}
/>
</div>
@ -296,7 +307,8 @@ const DocStoreInputHandler = ({ inputParam, data, disabled = false }) => {
DocStoreInputHandler.propTypes = {
inputParam: PropTypes.object,
data: PropTypes.object,
disabled: PropTypes.bool
disabled: PropTypes.bool,
onNodeDataChange: PropTypes.func
}
export default DocStoreInputHandler

View File

@ -153,7 +153,11 @@ const DocumentLoaderListDialog = ({ show, dialogProps, onCancel, onDocLoaderSele
width: 50,
height: 50,
borderRadius: '50%',
backgroundColor: 'white'
backgroundColor: 'white',
flexShrink: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
<img

View File

@ -35,7 +35,7 @@ import { closeSnackbar as closeSnackbarAction, enqueueSnackbar as enqueueSnackba
import { useError } from '@/store/context/ErrorContext'
// Utils
import { initNode } from '@/utils/genericHelper'
import { initNode, showHideInputParams } from '@/utils/genericHelper'
import useNotifier from '@/utils/useNotifier'
const CardWrapper = styled(MainCard)(({ theme }) => ({
@ -98,6 +98,24 @@ const LoaderConfigPreviewChunks = () => {
const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args))
const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args))
const handleDocumentLoaderDataChange = ({ inputParam, newValue }) => {
setSelectedDocumentLoader((prevData) => {
const updatedData = { ...prevData }
updatedData.inputs[inputParam.name] = newValue
updatedData.inputParams = showHideInputParams(updatedData)
return updatedData
})
}
const handleTextSplitterDataChange = ({ inputParam, newValue }) => {
setSelectedTextSplitter((prevData) => {
const updatedData = { ...prevData }
updatedData.inputs[inputParam.name] = newValue
updatedData.inputParams = showHideInputParams(updatedData)
return updatedData
})
}
const onSplitterChange = (name) => {
const textSplitter = (textSplitterNodes ?? []).find((splitter) => splitter.name === name)
if (textSplitter) {
@ -452,13 +470,14 @@ const LoaderConfigPreviewChunks = () => {
</Box>
{selectedDocumentLoader &&
Object.keys(selectedDocumentLoader).length > 0 &&
(selectedDocumentLoader.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
showHideInputParams(selectedDocumentLoader)
.filter((inputParam) => !inputParam.hidden && inputParam.display !== false)
.map((inputParam, index) => (
<DocStoreInputHandler
key={index}
inputParam={inputParam}
data={selectedDocumentLoader}
onNodeDataChange={handleDocumentLoaderDataChange}
/>
))}
{textSplitterNodes && textSplitterNodes.length > 0 && (
@ -511,10 +530,15 @@ const LoaderConfigPreviewChunks = () => {
</>
)}
{Object.keys(selectedTextSplitter).length > 0 &&
(selectedTextSplitter.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
showHideInputParams(selectedTextSplitter)
.filter((inputParam) => !inputParam.hidden && inputParam.display !== false)
.map((inputParam, index) => (
<DocStoreInputHandler key={index} data={selectedTextSplitter} inputParam={inputParam} />
<DocStoreInputHandler
key={index}
data={selectedTextSplitter}
inputParam={inputParam}
onNodeDataChange={handleTextSplitterDataChange}
/>
))}
</div>
</Grid>

View File

@ -40,7 +40,7 @@ import Storage from '@mui/icons-material/Storage'
import DynamicFeed from '@mui/icons-material/Filter1'
// utils
import { initNode } from '@/utils/genericHelper'
import { initNode, showHideInputParams } from '@/utils/genericHelper'
import useNotifier from '@/utils/useNotifier'
// const
@ -89,6 +89,33 @@ const VectorStoreConfigure = () => {
const [showUpsertHistoryDetailsDialog, setShowUpsertHistoryDetailsDialog] = useState(false)
const [upsertDetailsDialogProps, setUpsertDetailsDialogProps] = useState({})
const handleEmbeddingsProviderDataChange = ({ inputParam, newValue }) => {
setSelectedEmbeddingsProvider((prevData) => {
const updatedData = { ...prevData }
updatedData.inputs[inputParam.name] = newValue
updatedData.inputParams = showHideInputParams(updatedData)
return updatedData
})
}
const handleVectorStoreProviderDataChange = ({ inputParam, newValue }) => {
setSelectedVectorStoreProvider((prevData) => {
const updatedData = { ...prevData }
updatedData.inputs[inputParam.name] = newValue
updatedData.inputParams = showHideInputParams(updatedData)
return updatedData
})
}
const handleRecordManagerProviderDataChange = ({ inputParam, newValue }) => {
setSelectedRecordManagerProvider((prevData) => {
const updatedData = { ...prevData }
updatedData.inputs[inputParam.name] = newValue
updatedData.inputParams = showHideInputParams(updatedData)
return updatedData
})
}
const onEmbeddingsSelected = (component) => {
const nodeData = cloneDeep(initNode(component, uuidv4()))
if (!showEmbeddingsListDialog && documentStore.embeddingConfig) {
@ -599,14 +626,17 @@ const VectorStoreConfigure = () => {
</Box>
{selectedEmbeddingsProvider &&
Object.keys(selectedEmbeddingsProvider).length > 0 &&
(selectedEmbeddingsProvider.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
showHideInputParams(selectedEmbeddingsProvider)
.filter(
(inputParam) => !inputParam.hidden && inputParam.display !== false
)
.map((inputParam, index) => (
<DocStoreInputHandler
key={index}
data={selectedEmbeddingsProvider}
inputParam={inputParam}
isAdditionalParams={inputParam.additionalParams}
onNodeDataChange={handleEmbeddingsProviderDataChange}
/>
))}
</div>
@ -714,14 +744,17 @@ const VectorStoreConfigure = () => {
</Box>
{selectedVectorStoreProvider &&
Object.keys(selectedVectorStoreProvider).length > 0 &&
(selectedVectorStoreProvider.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
showHideInputParams(selectedVectorStoreProvider)
.filter(
(inputParam) => !inputParam.hidden && inputParam.display !== false
)
.map((inputParam, index) => (
<DocStoreInputHandler
key={index}
data={selectedVectorStoreProvider}
inputParam={inputParam}
isAdditionalParams={inputParam.additionalParams}
onNodeDataChange={handleVectorStoreProviderDataChange}
/>
))}
</div>
@ -837,17 +870,18 @@ const VectorStoreConfigure = () => {
</Box>
{selectedRecordManagerProvider &&
Object.keys(selectedRecordManagerProvider).length > 0 &&
(selectedRecordManagerProvider.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
showHideInputParams(selectedRecordManagerProvider)
.filter(
(inputParam) => !inputParam.hidden && inputParam.display !== false
)
.map((inputParam, index) => (
<>
<DocStoreInputHandler
key={index}
data={selectedRecordManagerProvider}
inputParam={inputParam}
isAdditionalParams={inputParam.additionalParams}
/>
</>
<DocStoreInputHandler
key={index}
data={selectedRecordManagerProvider}
inputParam={inputParam}
isAdditionalParams={inputParam.additionalParams}
onNodeDataChange={handleRecordManagerProviderDataChange}
/>
))}
</div>
</Grid>

View File

@ -31,7 +31,7 @@ import useApi from '@/hooks/useApi'
import { useAuth } from '@/hooks/useAuth'
import useNotifier from '@/utils/useNotifier'
import { baseURL } from '@/store/constant'
import { initNode } from '@/utils/genericHelper'
import { initNode, showHideInputParams } from '@/utils/genericHelper'
import { closeSnackbar as closeSnackbarAction, enqueueSnackbar as enqueueSnackbarAction } from '@/store/actions'
const CardWrapper = styled(MainCard)(({ theme }) => ({
@ -84,6 +84,15 @@ const VectorStoreQuery = () => {
const getVectorStoreNodeDetailsApi = useApi(nodesApi.getSpecificNode)
const [selectedVectorStoreProvider, setSelectedVectorStoreProvider] = useState({})
const handleVectorStoreProviderDataChange = ({ inputParam, newValue }) => {
setSelectedVectorStoreProvider((prevData) => {
const updatedData = { ...prevData }
updatedData.inputs[inputParam.name] = newValue
updatedData.inputParams = showHideInputParams(updatedData)
return updatedData
})
}
const chunkSelected = (chunkId, selectedChunkNumber) => {
const selectedChunk = documentChunks.find((chunk) => chunk.id === chunkId)
const dialogProps = {
@ -354,14 +363,15 @@ const VectorStoreQuery = () => {
</Box>
{selectedVectorStoreProvider &&
Object.keys(selectedVectorStoreProvider).length > 0 &&
(selectedVectorStoreProvider.inputParams ?? [])
.filter((inputParam) => !inputParam.hidden)
showHideInputParams(selectedVectorStoreProvider)
.filter((inputParam) => !inputParam.hidden && inputParam.display !== false)
.map((inputParam, index) => (
<DocStoreInputHandler
key={index}
data={selectedVectorStoreProvider}
inputParam={inputParam}
isAdditionalParams={inputParam.additionalParams}
onNodeDataChange={handleVectorStoreProviderDataChange}
/>
))}
</div>

View File

@ -726,7 +726,7 @@ importers:
version: 6.9.15
openai:
specifier: 4.96.0
version: 4.96.0(encoding@0.1.13)(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4))(zod@3.22.4)
version: 4.96.0(encoding@0.1.13)(ws@8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(zod@3.22.4)
passport:
specifier: ^0.7.0
version: 0.7.0
@ -1067,6 +1067,9 @@ importers:
remark-math:
specifier: ^5.1.1
version: 5.1.1
showdown:
specifier: ^2.1.0
version: 2.1.0
tippy.js:
specifier: ^6.3.7
version: 6.3.7
@ -16119,6 +16122,10 @@ packages:
shimmer@1.2.1:
resolution: { integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== }
showdown@2.1.0:
resolution: { integrity: sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ== }
hasBin: true
shx@0.3.4:
resolution: { integrity: sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g== }
engines: { node: '>=6' }
@ -21653,7 +21660,7 @@ snapshots:
dotenv: 16.4.5
openai: 4.96.0(encoding@0.1.13)(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4))(zod@3.22.4)
sharp: 0.33.5
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
ws: 8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4)
zod: 3.22.4
zod-to-json-schema: 3.24.1(zod@3.22.4)
transitivePeerDependencies:
@ -22402,7 +22409,7 @@ snapshots:
'@google/genai@0.7.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@6.0.4)':
dependencies:
google-auth-library: 9.15.1(encoding@0.1.13)
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
ws: 8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4)
transitivePeerDependencies:
- bufferutil
- encoding
@ -36019,6 +36026,21 @@ snapshots:
transitivePeerDependencies:
- encoding
openai@4.96.0(encoding@0.1.13)(ws@8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(zod@3.22.4):
dependencies:
'@types/node': 18.19.23
'@types/node-fetch': 2.6.12
abort-controller: 3.0.0
agentkeepalive: 4.5.0
form-data-encoder: 1.7.2
formdata-node: 4.4.1
node-fetch: 2.7.0(encoding@0.1.13)
optionalDependencies:
ws: 8.18.2(bufferutil@4.0.8)(utf-8-validate@6.0.4)
zod: 3.22.4
transitivePeerDependencies:
- encoding
openapi-types@12.1.3: {}
openapi-typescript-fetch@1.1.3: {}
@ -38734,6 +38756,10 @@ snapshots:
shimmer@1.2.1: {}
showdown@2.1.0:
dependencies:
commander: 9.5.0
shx@0.3.4:
dependencies:
minimist: 1.2.8