| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { useState, useCallback, useRef, useEffect } from 'react'; |
| import { |
| DEFAULT_MESSAGES, |
| DEFAULT_CONFIG, |
| DEBUG_TABS, |
| MESSAGE_STATUS, |
| } from '../../constants/playground.constants'; |
| import { |
| loadConfig, |
| saveConfig, |
| loadMessages, |
| saveMessages, |
| } from '../../components/playground/configStorage'; |
| import { processIncompleteThinkTags } from '../../helpers'; |
|
|
| export const usePlaygroundState = () => { |
| |
| const [savedConfig] = useState(() => loadConfig()); |
| const [initialMessages] = useState(() => loadMessages() || DEFAULT_MESSAGES); |
|
|
| |
| const [inputs, setInputs] = useState( |
| savedConfig.inputs || DEFAULT_CONFIG.inputs, |
| ); |
| const [parameterEnabled, setParameterEnabled] = useState( |
| savedConfig.parameterEnabled || DEFAULT_CONFIG.parameterEnabled, |
| ); |
| const [showDebugPanel, setShowDebugPanel] = useState( |
| savedConfig.showDebugPanel || DEFAULT_CONFIG.showDebugPanel, |
| ); |
| const [customRequestMode, setCustomRequestMode] = useState( |
| savedConfig.customRequestMode || DEFAULT_CONFIG.customRequestMode, |
| ); |
| const [customRequestBody, setCustomRequestBody] = useState( |
| savedConfig.customRequestBody || DEFAULT_CONFIG.customRequestBody, |
| ); |
|
|
| |
| const [showSettings, setShowSettings] = useState(false); |
| const [models, setModels] = useState([]); |
| const [groups, setGroups] = useState([]); |
| const [status, setStatus] = useState({}); |
|
|
| |
| const [message, setMessage] = useState(initialMessages); |
|
|
| |
| const [debugData, setDebugData] = useState({ |
| request: null, |
| response: null, |
| timestamp: null, |
| previewRequest: null, |
| previewTimestamp: null, |
| }); |
| const [activeDebugTab, setActiveDebugTab] = useState(DEBUG_TABS.PREVIEW); |
| const [previewPayload, setPreviewPayload] = useState(null); |
|
|
| |
| const [editingMessageId, setEditingMessageId] = useState(null); |
| const [editValue, setEditValue] = useState(''); |
|
|
| |
| const sseSourceRef = useRef(null); |
| const chatRef = useRef(null); |
| const saveConfigTimeoutRef = useRef(null); |
| const saveMessagesTimeoutRef = useRef(null); |
|
|
| |
| const handleInputChange = useCallback((name, value) => { |
| setInputs((prev) => ({ ...prev, [name]: value })); |
| }, []); |
|
|
| const handleParameterToggle = useCallback((paramName) => { |
| setParameterEnabled((prev) => ({ |
| ...prev, |
| [paramName]: !prev[paramName], |
| })); |
| }, []); |
|
|
| |
| const saveMessagesImmediately = useCallback( |
| (messagesToSave) => { |
| |
| saveMessages(messagesToSave || message); |
| }, |
| [message], |
| ); |
|
|
| |
| const debouncedSaveConfig = useCallback(() => { |
| if (saveConfigTimeoutRef.current) { |
| clearTimeout(saveConfigTimeoutRef.current); |
| } |
|
|
| saveConfigTimeoutRef.current = setTimeout(() => { |
| const configToSave = { |
| inputs, |
| parameterEnabled, |
| showDebugPanel, |
| customRequestMode, |
| customRequestBody, |
| }; |
| saveConfig(configToSave); |
| }, 1000); |
| }, [ |
| inputs, |
| parameterEnabled, |
| showDebugPanel, |
| customRequestMode, |
| customRequestBody, |
| ]); |
|
|
| |
| const handleConfigImport = useCallback((importedConfig) => { |
| if (importedConfig.inputs) { |
| setInputs((prev) => ({ ...prev, ...importedConfig.inputs })); |
| } |
| if (importedConfig.parameterEnabled) { |
| setParameterEnabled((prev) => ({ |
| ...prev, |
| ...importedConfig.parameterEnabled, |
| })); |
| } |
| if (typeof importedConfig.showDebugPanel === 'boolean') { |
| setShowDebugPanel(importedConfig.showDebugPanel); |
| } |
| if (importedConfig.customRequestMode) { |
| setCustomRequestMode(importedConfig.customRequestMode); |
| } |
| if (importedConfig.customRequestBody) { |
| setCustomRequestBody(importedConfig.customRequestBody); |
| } |
| |
| if (importedConfig.messages && Array.isArray(importedConfig.messages)) { |
| setMessage(importedConfig.messages); |
| } |
| }, []); |
|
|
| const handleConfigReset = useCallback((options = {}) => { |
| const { resetMessages = false } = options; |
|
|
| setInputs(DEFAULT_CONFIG.inputs); |
| setParameterEnabled(DEFAULT_CONFIG.parameterEnabled); |
| setShowDebugPanel(DEFAULT_CONFIG.showDebugPanel); |
| setCustomRequestMode(DEFAULT_CONFIG.customRequestMode); |
| setCustomRequestBody(DEFAULT_CONFIG.customRequestBody); |
|
|
| |
| if (resetMessages) { |
| setMessage([]); |
| setTimeout(() => { |
| setMessage(DEFAULT_MESSAGES); |
| }, 0); |
| } |
| }, []); |
|
|
| |
| useEffect(() => { |
| return () => { |
| if (saveConfigTimeoutRef.current) { |
| clearTimeout(saveConfigTimeoutRef.current); |
| } |
| }; |
| }, []); |
|
|
| |
| useEffect(() => { |
| if (!Array.isArray(message) || message.length === 0) return; |
|
|
| const lastMsg = message[message.length - 1]; |
| if ( |
| lastMsg.status === MESSAGE_STATUS.LOADING || |
| lastMsg.status === MESSAGE_STATUS.INCOMPLETE |
| ) { |
| const processed = processIncompleteThinkTags( |
| lastMsg.content || '', |
| lastMsg.reasoningContent || '', |
| ); |
|
|
| const fixedLastMsg = { |
| ...lastMsg, |
| status: MESSAGE_STATUS.COMPLETE, |
| content: processed.content, |
| reasoningContent: processed.reasoningContent || null, |
| isThinkingComplete: true, |
| }; |
|
|
| const updatedMessages = [...message.slice(0, -1), fixedLastMsg]; |
| setMessage(updatedMessages); |
|
|
| |
| setTimeout(() => saveMessagesImmediately(updatedMessages), 0); |
| } |
| }, []); |
|
|
| return { |
| |
| inputs, |
| parameterEnabled, |
| showDebugPanel, |
| customRequestMode, |
| customRequestBody, |
|
|
| |
| showSettings, |
| models, |
| groups, |
| status, |
|
|
| |
| message, |
|
|
| |
| debugData, |
| activeDebugTab, |
| previewPayload, |
|
|
| |
| editingMessageId, |
| editValue, |
|
|
| |
| sseSourceRef, |
| chatRef, |
| saveConfigTimeoutRef, |
|
|
| |
| setInputs, |
| setParameterEnabled, |
| setShowDebugPanel, |
| setCustomRequestMode, |
| setCustomRequestBody, |
| setShowSettings, |
| setModels, |
| setGroups, |
| setStatus, |
| setMessage, |
| setDebugData, |
| setActiveDebugTab, |
| setPreviewPayload, |
| setEditingMessageId, |
| setEditValue, |
|
|
| |
| handleInputChange, |
| handleParameterToggle, |
| debouncedSaveConfig, |
| saveMessagesImmediately, |
| handleConfigImport, |
| handleConfigReset, |
| }; |
| }; |
|
|