+
{t('分组')}
+ {customRequestMode && (
+
+ (已在自定义模式中忽略)
+
+ )}
{/* 模型选择 */}
-
+
{t('模型')}
+ {customRequestMode && (
+
+ (已在自定义模式中忽略)
+
+ )}
{/* 图片URL输入 */}
-
onInputChange('imageUrls', urls)}
- onImageEnabledChange={(enabled) => onInputChange('imageEnabled', enabled)}
- />
+
+ onInputChange('imageUrls', urls)}
+ onImageEnabledChange={(enabled) => onInputChange('imageEnabled', enabled)}
+ disabled={customRequestMode}
+ />
+
{/* 参数控制组件 */}
-
+
{/* 流式输出开关 */}
-
+
流式输出
+ {customRequestMode && (
+
+ (已在自定义模式中忽略)
+
+ )}
-
- {/* System Prompt */}
-
-
-
-
- System Prompt
-
-
-
-
{/* 桌面端的配置管理放在底部 */}
@@ -187,6 +207,7 @@ const SettingsPanel = ({
onConfigImport={onConfigImport}
onConfigReset={onConfigReset}
styleState={styleState}
+ messages={messages}
/>
)}
diff --git a/web/src/components/playground/ThinkingContent.js b/web/src/components/playground/ThinkingContent.js
new file mode 100644
index 00000000..a7222bab
--- /dev/null
+++ b/web/src/components/playground/ThinkingContent.js
@@ -0,0 +1,98 @@
+import React from 'react';
+import { Typography } from '@douyinfe/semi-ui';
+import MarkdownRenderer from '../common/MarkdownRenderer';
+import { ChevronRight, ChevronUp, Brain, Loader2 } from 'lucide-react';
+import { useTranslation } from 'react-i18next';
+
+const ThinkingContent = ({
+ message,
+ finalExtractedThinkingContent,
+ thinkingSource,
+ styleState,
+ onToggleReasoningExpansion
+}) => {
+ const { t } = useTranslation();
+
+ if (!finalExtractedThinkingContent) return null;
+
+ const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
+ const headerText = (isThinkingStatus && !message.isThinkingComplete) ? t('思考中...') : t('思考过程');
+
+ return (
+
+
onToggleReasoningExpansion(message.id)}
+ >
+
+
+
+
+
+
+
+ {headerText}
+
+ {thinkingSource && (
+
+ 来源: {thinkingSource}
+
+ )}
+
+
+
+ {isThinkingStatus && !message.isThinkingComplete && (
+
+
+
+ 思考中
+
+
+ )}
+ {(!isThinkingStatus || message.isThinkingComplete) && (
+
+ {message.isReasoningExpanded ?
+ :
+
+ }
+
+ )}
+
+
+
+ {message.isReasoningExpanded && (
+
+ )}
+
+
+ );
+};
+
+export default ThinkingContent;
\ No newline at end of file
diff --git a/web/src/components/playground/configStorage.js b/web/src/components/playground/configStorage.js
index 7ddddb3f..6e6e679d 100644
--- a/web/src/components/playground/configStorage.js
+++ b/web/src/components/playground/configStorage.js
@@ -1,30 +1,6 @@
-const STORAGE_KEY = 'playground_config';
+import { STORAGE_KEYS, DEFAULT_CONFIG } from '../../utils/constants';
-const DEFAULT_CONFIG = {
- inputs: {
- model: 'deepseek-r1',
- group: '',
- max_tokens: 0,
- temperature: 0,
- top_p: 1,
- frequency_penalty: 0,
- presence_penalty: 0,
- seed: null,
- stream: true,
- imageUrls: [],
- imageEnabled: false,
- },
- parameterEnabled: {
- max_tokens: true,
- temperature: true,
- top_p: false,
- frequency_penalty: false,
- presence_penalty: false,
- seed: false,
- },
- systemPrompt: 'You are a helpful assistant. You can help me by answering my questions. You can also ask me questions.',
- showDebugPanel: false,
-};
+const MESSAGES_STORAGE_KEY = 'playground_messages';
/**
* 保存配置到 localStorage
@@ -36,20 +12,37 @@ export const saveConfig = (config) => {
...config,
timestamp: new Date().toISOString(),
};
- localStorage.setItem(STORAGE_KEY, JSON.stringify(configToSave));
+ localStorage.setItem(STORAGE_KEYS.CONFIG, JSON.stringify(configToSave));
console.log('配置已保存到本地存储');
} catch (error) {
console.error('保存配置失败:', error);
}
};
+/**
+ * 保存消息到 localStorage
+ * @param {Array} messages - 要保存的消息数组
+ */
+export const saveMessages = (messages) => {
+ try {
+ const messagesToSave = {
+ messages,
+ timestamp: new Date().toISOString(),
+ };
+ localStorage.setItem(STORAGE_KEYS.MESSAGES, JSON.stringify(messagesToSave));
+ console.log('消息已保存到本地存储');
+ } catch (error) {
+ console.error('保存消息失败:', error);
+ }
+};
+
/**
* 从 localStorage 加载配置
* @returns {Object} 配置对象,如果不存在则返回默认配置
*/
export const loadConfig = () => {
try {
- const savedConfig = localStorage.getItem(STORAGE_KEY);
+ const savedConfig = localStorage.getItem(STORAGE_KEYS.CONFIG);
if (savedConfig) {
const parsedConfig = JSON.parse(savedConfig);
@@ -62,8 +55,9 @@ export const loadConfig = () => {
...DEFAULT_CONFIG.parameterEnabled,
...parsedConfig.parameterEnabled,
},
- systemPrompt: parsedConfig.systemPrompt || DEFAULT_CONFIG.systemPrompt,
showDebugPanel: parsedConfig.showDebugPanel || DEFAULT_CONFIG.showDebugPanel,
+ customRequestMode: parsedConfig.customRequestMode || DEFAULT_CONFIG.customRequestMode,
+ customRequestBody: parsedConfig.customRequestBody || DEFAULT_CONFIG.customRequestBody,
};
console.log('配置已从本地存储加载');
@@ -77,25 +71,58 @@ export const loadConfig = () => {
return DEFAULT_CONFIG;
};
+/**
+ * 从 localStorage 加载消息
+ * @returns {Array} 消息数组,如果不存在则返回 null
+ */
+export const loadMessages = () => {
+ try {
+ const savedMessages = localStorage.getItem(STORAGE_KEYS.MESSAGES);
+ if (savedMessages) {
+ const parsedMessages = JSON.parse(savedMessages);
+ console.log('消息已从本地存储加载');
+ return parsedMessages.messages || null;
+ }
+ } catch (error) {
+ console.error('加载消息失败:', error);
+ }
+
+ console.log('没有找到保存的消息');
+ return null;
+};
+
/**
* 清除保存的配置
*/
export const clearConfig = () => {
try {
- localStorage.removeItem(STORAGE_KEY);
- console.log('配置已清除');
+ localStorage.removeItem(STORAGE_KEYS.CONFIG);
+ localStorage.removeItem(STORAGE_KEYS.MESSAGES); // 同时清除消息
+ console.log('配置和消息已清除');
} catch (error) {
console.error('清除配置失败:', error);
}
};
+/**
+ * 清除保存的消息
+ */
+export const clearMessages = () => {
+ try {
+ localStorage.removeItem(STORAGE_KEYS.MESSAGES);
+ console.log('消息已清除');
+ } catch (error) {
+ console.error('清除消息失败:', error);
+ }
+};
+
/**
* 检查是否有保存的配置
* @returns {boolean} 是否存在保存的配置
*/
export const hasStoredConfig = () => {
try {
- return localStorage.getItem(STORAGE_KEY) !== null;
+ return localStorage.getItem(STORAGE_KEYS.CONFIG) !== null;
} catch (error) {
console.error('检查配置失败:', error);
return false;
@@ -108,7 +135,7 @@ export const hasStoredConfig = () => {
*/
export const getConfigTimestamp = () => {
try {
- const savedConfig = localStorage.getItem(STORAGE_KEY);
+ const savedConfig = localStorage.getItem(STORAGE_KEYS.CONFIG);
if (savedConfig) {
const parsedConfig = JSON.parse(savedConfig);
return parsedConfig.timestamp || null;
@@ -120,13 +147,15 @@ export const getConfigTimestamp = () => {
};
/**
- * 导出配置为 JSON 文件
+ * 导出配置为 JSON 文件(包含消息)
* @param {Object} config - 要导出的配置
+ * @param {Array} messages - 要导出的消息
*/
-export const exportConfig = (config) => {
+export const exportConfig = (config, messages = null) => {
try {
const configToExport = {
...config,
+ messages: messages || loadMessages(), // 包含消息数据
exportTime: new Date().toISOString(),
version: '1.0',
};
@@ -148,7 +177,7 @@ export const exportConfig = (config) => {
};
/**
- * 从文件导入配置
+ * 从文件导入配置(包含消息)
* @param {File} file - 包含配置的 JSON 文件
* @returns {Promise