| | 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, |
| | }; |
| | }; |