From 09732d992703d083103b5ba8877593b68ed4924d Mon Sep 17 00:00:00 2001 From: marvikomo Date: Mon, 15 Sep 2025 16:04:29 +0100 Subject: [PATCH 1/7] feat: add gpt-5-chat-latest and gpt-4.1-mini to Azure OpenAI Node --- packages/components/models.json | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/components/models.json b/packages/components/models.json index 73a3c7bb7f2..fb3feb21948 100644 --- a/packages/components/models.json +++ b/packages/components/models.json @@ -396,6 +396,18 @@ "name": "gpt-4.5-preview", "input_cost": 0.000075, "output_cost": 0.00015 + }, + { + "label": "gpt-4.1-mini", + "name": "gpt-4.1-mini", + "input_cost": 0.0000004, + "output_cost": 0.0000016 + }, + { + "label": "gpt-5-chat-latest", + "name": "gpt-5-chat-latest", + "input_cost": 0.00000125, + "output_cost": 0.00001 } ] }, @@ -455,6 +467,18 @@ "name": "gpt-4-1106-preview", "input_cost": 0.00001, "output_cost": 0.00003 + }, + { + "label": "gpt-4.1-mini", + "name": "gpt-4.1-mini", + "input_cost": 0.0000004, + "output_cost": 0.0000016 + }, + { + "label": "gpt-5-chat-latest", + "name": "gpt-5-chat-latest", + "input_cost": 0.00000125, + "output_cost": 0.00001 } ] }, @@ -1682,6 +1706,18 @@ "name": "gpt-4-32k", "input_cost": 0.00006, "output_cost": 0.00012 + }, + { + "label": "gpt-4.1-mini", + "name": "gpt-4.1-mini", + "input_cost": 0.0000004, + "output_cost": 0.0000016 + }, + { + "label": "gpt-5-chat-latest", + "name": "gpt-5-chat-latest", + "input_cost": 0.00000125, + "output_cost": 0.00001 } ] }, From 0cc77c2fc358d3b11ece69976966a5be3e0d79d1 Mon Sep 17 00:00:00 2001 From: marvikomo Date: Tue, 16 Sep 2025 12:53:02 +0100 Subject: [PATCH 2/7] fix(ui): add save prompt for unsaved agent flows in chat --- .../ui/src/views/chatmessage/ChatMessage.jsx | 90 ++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/views/chatmessage/ChatMessage.jsx b/packages/ui/src/views/chatmessage/ChatMessage.jsx index b3eb5ed2718..9ae5d3f5400 100644 --- a/packages/ui/src/views/chatmessage/ChatMessage.jsx +++ b/packages/ui/src/views/chatmessage/ChatMessage.jsx @@ -38,7 +38,8 @@ import { IconSquareFilled, IconCheck, IconPaperclip, - IconSparkles + IconSparkles, + IconDeviceFloppy } from '@tabler/icons-react' import robotPNG from '@/assets/images/robot.png' import userPNG from '@/assets/images/account.png' @@ -162,7 +163,7 @@ CardWithDeleteOverlay.propTypes = { onDelete: PropTypes.func } -const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setPreviews }) => { +const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setPreviews, onOpenSaveDialog }) => { const theme = useTheme() const customization = useSelector((state) => state.customization) @@ -250,6 +251,10 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP const [formInputParams, setFormInputParams] = useState([]) const [isConfigLoading, setIsConfigLoading] = useState(true) + const [showSaveDialog, setShowSaveDialog] = useState(false) + const [pendingMessage, setPendingMessage] = useState('') + const [pendingMessageAction, setPendingMessageAction] = useState(null) + const [pendingHumanInput, setPendingHumanInput] = useState(null) const isFileAllowedForUpload = (file) => { const constraints = getAllowChatFlowUploads.data @@ -1672,6 +1677,48 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP } } + // If no chatflowid and this is an agent canvas, show save prompt + if (!chatflowid) { + const handleSaveFlow = () => { + // Use the proper Flowise save dialog + if (onOpenSaveDialog) { + onOpenSaveDialog() + } + } + + return ( + + + + Save Flow to Continue + + + You need to save this agent flow before you can test it with messages. + + + + ) + } + if (isConfigLoading) { return ( + + {/* Save Flow Dialog */} + {/* setShowSaveDialog(false)} maxWidth="sm" fullWidth> + + + Save Flow to Continue + + + + You need to save this agent flow before you can test it with messages. + + + Would you like to save the flow and continue with your message? + + + + + + + */} ) } From 0aa7d7562d3a9f2ee8e7bd827a644b628e43259b Mon Sep 17 00:00:00 2001 From: marvikomo Date: Tue, 16 Sep 2025 12:53:43 +0100 Subject: [PATCH 3/7] added SaveChatflowDialog --- packages/ui/src/views/agentflowsv2/Canvas.jsx | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/views/agentflowsv2/Canvas.jsx b/packages/ui/src/views/agentflowsv2/Canvas.jsx index 3a724666f94..9e590104ba4 100644 --- a/packages/ui/src/views/agentflowsv2/Canvas.jsx +++ b/packages/ui/src/views/agentflowsv2/Canvas.jsx @@ -31,6 +31,7 @@ import ConfirmDialog from '@/ui-component/dialog/ConfirmDialog' import EditNodeDialog from '@/views/agentflowsv2/EditNodeDialog' import ChatPopUp from '@/views/chatmessage/ChatPopUp' import ValidationPopUp from '@/views/chatmessage/ValidationPopUp' +import SaveChatflowDialog from '@/ui-component/dialog/SaveChatflowDialog' import { flowContext } from '@/store/context/ReactFlowContext' // API @@ -100,6 +101,7 @@ const AgentflowCanvas = () => { const [isSyncNodesButtonEnabled, setIsSyncNodesButtonEnabled] = useState(false) const [editNodeDialogOpen, setEditNodeDialogOpen] = useState(false) const [editNodeDialogProps, setEditNodeDialogProps] = useState({}) + const [flowDialogOpen, setFlowDialogOpen] = useState(false) const [isSnappingEnabled, setIsSnappingEnabled] = useState(false) const reactFlowWrapper = useRef(null) @@ -240,6 +242,15 @@ const AgentflowCanvas = () => { } } + const onConfirmSaveName = (flowName) => { + setFlowDialogOpen(false) + handleSaveFlow(flowName) + } + + const openSaveDialog = () => { + setFlowDialogOpen(true) + } + // eslint-disable-next-line const onNodeClick = useCallback((event, clickedNode) => { setSelectedNode(clickedNode) @@ -785,13 +796,23 @@ const AgentflowCanvas = () => { )} - + {!chatPopupOpen && } + setFlowDialogOpen(false)} + onConfirm={onConfirmSaveName} + /> ) From fdd9f668abf5611e91f451ebd69a19bddd65d35d Mon Sep 17 00:00:00 2001 From: marvikomo Date: Tue, 16 Sep 2025 12:54:29 +0100 Subject: [PATCH 4/7] updated chatPopUp to use the onOpenSaveDialog --- packages/ui/src/views/chatmessage/ChatPopUp.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/views/chatmessage/ChatPopUp.jsx b/packages/ui/src/views/chatmessage/ChatPopUp.jsx index 1731feb7eca..762672a33e4 100644 --- a/packages/ui/src/views/chatmessage/ChatPopUp.jsx +++ b/packages/ui/src/views/chatmessage/ChatPopUp.jsx @@ -27,7 +27,7 @@ import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackba // Utils import { getLocalStorageChatflow, removeLocalStorageChatHistory } from '@/utils/genericHelper' -const ChatPopUp = ({ chatflowid, isAgentCanvas, onOpenChange }) => { +const ChatPopUp = ({ chatflowid, isAgentCanvas, onOpenChange, onOpenSaveDialog }) => { const theme = useTheme() const { confirm } = useConfirm() const dispatch = useDispatch() @@ -215,6 +215,7 @@ const ChatPopUp = ({ chatflowid, isAgentCanvas, onOpenChange }) => { open={open} previews={previews} setPreviews={setPreviews} + onOpenSaveDialog={onOpenSaveDialog} /> @@ -238,7 +239,8 @@ const ChatPopUp = ({ chatflowid, isAgentCanvas, onOpenChange }) => { ChatPopUp.propTypes = { chatflowid: PropTypes.string, isAgentCanvas: PropTypes.bool, - onOpenChange: PropTypes.func + onOpenChange: PropTypes.func, + onOpenSaveDialog: PropTypes.func } export default memo(ChatPopUp) From 3e15e75d6b7a5de52730b22cd10cbe56816db0bb Mon Sep 17 00:00:00 2001 From: marvikomo Date: Tue, 16 Sep 2025 18:47:06 +0100 Subject: [PATCH 5/7] Fixes infinite loading issue when clicking message icon on unsaved regular chatflows and agent flows --- packages/ui/src/views/canvas/index.jsx | 27 +++++++++++++++++-- .../ui/src/views/chatmessage/ChatMessage.jsx | 2 +- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/views/canvas/index.jsx b/packages/ui/src/views/canvas/index.jsx index ebfbd0506fa..4027af6149f 100644 --- a/packages/ui/src/views/canvas/index.jsx +++ b/packages/ui/src/views/canvas/index.jsx @@ -24,6 +24,7 @@ import StickyNote from './StickyNote' import CanvasHeader from './CanvasHeader' import AddNodes from './AddNodes' import ConfirmDialog from '@/ui-component/dialog/ConfirmDialog' +import SaveChatflowDialog from '@/ui-component/dialog/SaveChatflowDialog' import ChatPopUp from '@/views/chatmessage/ChatPopUp' import VectorStorePopUp from '@/views/vectorstore/VectorStorePopUp' import { flowContext } from '@/store/context/ReactFlowContext' @@ -104,6 +105,7 @@ const Canvas = () => { const [lastUpdatedDateTime, setLasUpdatedDateTime] = useState('') const [chatflowName, setChatflowName] = useState('') const [flowData, setFlowData] = useState('') + const [flowDialogOpen, setFlowDialogOpen] = useState(false) // ==============================|| Chatflow API ||============================== // @@ -243,6 +245,16 @@ const Canvas = () => { } } + const openSaveDialog = () => { + if (chatflow?.id) { + // If chatflow has an ID, save directly using the flow name + handleSaveFlow(chatflow.name) + } else { + // If no ID, open the save dialog + setFlowDialogOpen(true) + } + } + // eslint-disable-next-line const onNodeClick = useCallback((event, clickedNode) => { setSelectedNode(clickedNode) @@ -431,7 +443,8 @@ const Canvas = () => { const chatflow = createNewChatflowApi.data dispatch({ type: SET_CHATFLOW, chatflow }) saveChatflowSuccess() - window.history.replaceState(state, null, `/${isAgentCanvas ? 'agentcanvas' : 'canvas'}/${chatflow.id}`) + setFlowDialogOpen(false) // Close the save dialog + navigate(`/${isAgentCanvas ? 'agentcanvas' : 'canvas'}/${chatflow.id}`) } else if (createNewChatflowApi.error) { errorFailed(`Failed to retrieve ${canvasTitle}: ${createNewChatflowApi.error.response.data.message}`) } @@ -645,12 +658,22 @@ const Canvas = () => { )} {isUpsertButtonEnabled && } - + + setFlowDialogOpen(false)} + onConfirm={(name) => handleSaveFlow(name)} + /> ) diff --git a/packages/ui/src/views/chatmessage/ChatMessage.jsx b/packages/ui/src/views/chatmessage/ChatMessage.jsx index 9ae5d3f5400..0b6800aaca1 100644 --- a/packages/ui/src/views/chatmessage/ChatMessage.jsx +++ b/packages/ui/src/views/chatmessage/ChatMessage.jsx @@ -1705,7 +1705,7 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP Save Flow to Continue - You need to save this agent flow before you can test it with messages. + You need to save this {isAgentCanvas ? 'agent flow' : 'chatflow'} before you can test it with messages. ) - } + } if (isConfigLoading) { return ( @@ -2593,7 +2584,8 @@ ChatMessage.propTypes = { isAgentCanvas: PropTypes.bool, isDialog: PropTypes.bool, previews: PropTypes.array, - setPreviews: PropTypes.func + setPreviews: PropTypes.func, + onOpenSaveDialog: PropTypes.func } export default memo(ChatMessage) From 9be44f430ec0e3df023d4d87858693bb8e53de16 Mon Sep 17 00:00:00 2001 From: marvikomo Date: Tue, 16 Sep 2025 19:06:13 +0100 Subject: [PATCH 7/7] cleanup --- .../ui/src/views/chatmessage/ChatMessage.jsx | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/packages/ui/src/views/chatmessage/ChatMessage.jsx b/packages/ui/src/views/chatmessage/ChatMessage.jsx index 06157197604..cd8e9ec4509 100644 --- a/packages/ui/src/views/chatmessage/ChatMessage.jsx +++ b/packages/ui/src/views/chatmessage/ChatMessage.jsx @@ -2535,45 +2535,6 @@ const ChatMessage = ({ open, chatflowid, isAgentCanvas, isDialog, previews, setP - - {/* Save Flow Dialog */} - {/* setShowSaveDialog(false)} maxWidth="sm" fullWidth> - - - Save Flow to Continue - - - - You need to save this agent flow before you can test it with messages. - - - Would you like to save the flow and continue with your message? - - - - - - - */} ) }