diff --git a/src/app/_common/components/nodeHook.ts b/src/app/_common/components/nodeHook.ts index 441c447f..337bda9f 100644 --- a/src/app/_common/components/nodeHook.ts +++ b/src/app/_common/components/nodeHook.ts @@ -4,6 +4,7 @@ import { useState, useEffect, useCallback } from 'react'; import { getNodes as apiGetNodes, exportNodes as apiExportNodes, + refreshNodes as apiRefreshNodes } from '@/app/api/nodeAPI'; import { toast } from 'react-hot-toast'; @@ -86,7 +87,7 @@ export const useNodes = (): UseNodesReturn => { setIsLoading(true); setError(null); try { - const data = await apiExportNodes(); + const data = await apiRefreshNodes(); setNodes(data as NodeCategory[]); toast.success('노드 목록 새로고침 완료!'); } catch (err: any) { diff --git a/src/app/api/chatAPI.js b/src/app/api/chatAPI.js deleted file mode 100644 index 7336730c..00000000 --- a/src/app/api/chatAPI.js +++ /dev/null @@ -1,155 +0,0 @@ -// Configuration API 호출 함수들을 관리하는 파일 -import { API_BASE_URL } from '@/app/config.js'; - -/** - * Creates a new chat session - * @param {Object} params - The chat creation parameters - * @param {string} params.interaction_id - Unique interaction identifier - * @param {string} [params.input_data] - Optional initial message - * @returns {Promise} A promise that resolves with the chat creation response - */ -export const createNewChat = async ({ interaction_id, input_data = null }) => { - try { - const response = await fetch(`${API_BASE_URL}/api/chat/new`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - workflow_name: "default_mode", - workflow_id: "default_mode", - interaction_id, - input_data - }), - }); - - if (!response.ok) { - const errorData = await response.json(); - throw new Error(`HTTP ${response.status}: ${errorData.detail || 'Unknown error'}`); - } - - return await response.json(); - } catch (error) { - console.error('Error creating new chat:', error); - throw error; - } -}; - -/** - * Continues an existing chat session - * @param {Object} params - The chat execution parameters - * @param {string} params.user_input - The user's message - * @param {string} params.interaction_id - The interaction identifier - * @param {string} [params.workflow_id] - Optional workflow ID (defaults to "default_mode") - * @param {string} [params.workflow_name] - Optional workflow name (defaults to "default_mode") - * @param {string|null} [params.selectedCollection] - Optional selected collection for default_mode - * @returns {Promise} A promise that resolves with the chat response - */ -export const executeChatMessage = async ({ - user_input, - interaction_id, - workflow_id = "default_mode", - workflow_name = "default_mode", - selectedCollection = null, -}) => { - try { - const requestBody = { - user_input, - interaction_id, - workflow_id, - workflow_name, - }; - - // selectedCollection이 있으면 body에 추가 - if (selectedCollection) { - requestBody.selected_collection = selectedCollection; - } - - const response = await fetch(`${API_BASE_URL}/api/chat/execution`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(requestBody), - }); - - if (!response.ok) { - const errorData = await response.json(); - throw new Error(`HTTP ${response.status}: ${errorData.detail || 'Unknown error'}`); - } - - return await response.json(); - } catch (error) { - console.error('Error executing chat message:', error); - throw error; - } -}; - -/** - * High-level function to handle a complete chat flow - * @param {Object} params - The chat parameters - * @param {string} params.message - The user's message - * @param {string} [params.interaction_id] - Existing interaction ID or will generate new one - * @param {boolean} [params.isNewChat] - Whether this is a new chat session - * @returns {Promise} A promise that resolves with the chat response - */ -export const sendMessage = async ({ - message, - interaction_id = null, - isNewChat = false -}) => { - try { - // Generate interaction ID if not provided - const chatInteractionId = interaction_id || `chat_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; - - if (isNewChat) { - // Create new chat session with initial message - const result = await createNewChat({ - interaction_id: chatInteractionId, - input_data: message - }); - - return { - text: result.chat_response || 'Chat session created successfully', - interaction_id: result.interaction_id, - session_info: result.execution_meta, - timestamp: result.timestamp, - status: result.status - }; - } else { - // Continue existing chat session - const result = await executeChatMessage({ - user_input: message, - interaction_id: chatInteractionId - }); - - return { - text: result.ai_response, - interaction_id: result.interaction_id, - session_id: result.session_id, - session_info: result.execution_meta, - timestamp: result.timestamp, - status: result.status - }; - } - } catch (error) { - console.error('Error in sendMessage:', error); - throw error; - } -}; - -/** - * Legacy function for backward compatibility - simulates sending a message - * @deprecated Use sendMessage with proper parameters instead - * @param {string} message - The message to send - * @returns {Promise<{text: string}>} A promise that resolves with a response object - */ -export const sendMessageLegacy = (message) => { - return new Promise((resolve) => { - setTimeout(() => { - resolve({ - text: `This is a response to your message: "${message}"`, - }); - }, 1000); // Simulate 1 second delay - }); -}; diff --git a/src/app/api/nodeAPI.js b/src/app/api/nodeAPI.js index 7ce28e54..6b032599 100644 --- a/src/app/api/nodeAPI.js +++ b/src/app/api/nodeAPI.js @@ -46,3 +46,26 @@ export const exportNodes = async () => { throw error; } }; + +/** + * @returns {Promise>} 노드 객체의 배열을 반환하는 프로미스 + * @throws {Error} API 요청이 실패하면 에러를 발생시킵니다. + */ +export const refreshNodes = async () => { + try { + const response = await fetch(`${API_BASE_URL}/api/node/refresh`); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error( + errorData.detail || `HTTP error! status: ${response.status}`, + ); + } + + // force_refresh 후, 최신 노드 리스트를 다시 불러옵니다. + return await getNodes(); + } catch (error) { + devLog.error('Failed to get nodes:', error); + throw error; // 에러를 호출한 쪽으로 다시 던져서 UI에서 처리할 수 있도록 합니다. + } +}; diff --git a/src/app/api/workflowAPI.js b/src/app/api/workflowAPI.js index 323bcd5d..84e53065 100644 --- a/src/app/api/workflowAPI.js +++ b/src/app/api/workflowAPI.js @@ -346,6 +346,7 @@ export const deleteWorkflowIOLogs = async (workflowName, workflowId, interaction * @param {string} workflowName - 워크플로우 이름 (.json 확장자 제외) * @param {string} workflowId - 워크플로우 ID * @param {string} inputData - 실행에 사용할 입력 데이터 (선택사항) + * @param {string|null} [params.selectedCollection] - Optional selected collection * @returns {Promise} 실행 결과를 포함하는 프로미스 * @throws {Error} API 요청이 실패하면 에러를 발생시킵니다. */ @@ -354,30 +355,30 @@ export const executeWorkflowById = async ( workflowId, inputData = '', interaction_id = 'default', + selectedCollection = null, ) => { try { - const body = { + const requestBody = { workflow_name: workflowName, workflow_id: workflowId, input_data: inputData || '', interaction_id: interaction_id || 'default', }; - const response = await fetch( - `${API_BASE_URL}/api/workflow/execute/based_id`, - { + if (selectedCollection) { + requestBody.selected_collection = selectedCollection; + } + const response = await fetch(`${API_BASE_URL}/api/workflow/execute/based_id`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify(body), + body: JSON.stringify(requestBody), }, ); if (!response.ok) { const errorData = await response.json(); - throw new Error( - errorData.detail || `HTTP error! status: ${response.status}`, - ); + throw new Error(errorData.detail || `HTTP error! status: ${response.status}`); } const result = await response.json(); diff --git a/src/app/canvas/components/Node.tsx b/src/app/canvas/components/Node.tsx index 4e518b07..d3a2f232 100644 --- a/src/app/canvas/components/Node.tsx +++ b/src/app/canvas/components/Node.tsx @@ -92,7 +92,13 @@ const Node: React.FC = ({ {param.options && param.options.length > 0 ? ( + ) : param.type === 'BOOL' ? ( + ) : ( = ({ ); }; -export default memo(Node); \ No newline at end of file +export default memo(Node); diff --git a/src/app/canvas/components/SideMenu.tsx b/src/app/canvas/components/SideMenu.tsx index 65578c21..6f642a90 100644 --- a/src/app/canvas/components/SideMenu.tsx +++ b/src/app/canvas/components/SideMenu.tsx @@ -2,7 +2,6 @@ import React, { useState, RefObject } from 'react'; import styles from '@/app/canvas/assets/SideMenu.module.scss'; import AddNodePanel from '@/app/canvas/components/SideMenuPanel/AddNodePanel'; -import ChatPanel from '@/app/canvas/components/SideMenuPanel/ChatPanel'; import WorkflowPanel from '@/app/canvas/components/SideMenuPanel/WorkflowPanel'; import TemplatePanel from '@/app/canvas/components/SideMenuPanel/TemplatePanel'; import { LuCirclePlus, LuCircleHelp, LuSettings, LuLayoutGrid, LuMessageSquare, LuLayoutTemplate } from "react-icons/lu"; @@ -30,10 +29,10 @@ const MainMenu: React.FC = ({ onNavigate }) => { Add Node - + */} -

Chat

- - -
- {messages.map((msg: Message) => ( -
- {msg.text} -
- ))} - {isLoading && isLastMessageFromUser() && ( -
- -
- )} -
- -
-