From e412e809eba64af7ae5dbe2157131dd0f9c81aac Mon Sep 17 00:00:00 2001 From: xiamuceer-j Date: Wed, 14 Jan 2026 14:30:06 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=B5=8B=E8=AF=95=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9Etemperature=E5=92=8Cmax=5Ftokens=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/settings.py | 23 +++- backend/app/main.py | 2 +- frontend/src/pages/Settings.tsx | 232 +++++++++++++++++--------------- 3 files changed, 143 insertions(+), 114 deletions(-) diff --git a/backend/app/api/settings.py b/backend/app/api/settings.py index e737dd9..576f482 100644 --- a/backend/app/api/settings.py +++ b/backend/app/api/settings.py @@ -349,6 +349,8 @@ class ApiTestRequest(BaseModel): api_base_url: str provider: str llm_model: str + temperature: Optional[float] = None + max_tokens: Optional[int] = None @router.post("/check-function-calling") @@ -578,7 +580,7 @@ async def test_api_connection(data: ApiTestRequest): 测试 API 连接和配置是否正确 Args: - data: 包含 API 配置的请求数据 + data: 包含 API 配置的请求数据(包括 temperature 和 max_tokens) Returns: 测试结果包含状态、响应时间和详细信息 @@ -587,19 +589,22 @@ async def test_api_connection(data: ApiTestRequest): api_base_url = data.api_base_url provider = data.provider llm_model = data.llm_model + # 使用前端传递的参数,如果未传递则使用默认值 + temperature = data.temperature if data.temperature is not None else 0.7 + max_tokens = data.max_tokens if data.max_tokens is not None else 2000 import time try: start_time = time.time() - # 创建临时 AI 服务实例 + # 创建临时 AI 服务实例,使用前端传递的参数 test_service = AIService( api_provider=provider, api_key=api_key, api_base_url=api_base_url, default_model=llm_model, - default_temperature=0.7, - default_max_tokens=100 + default_temperature=temperature, + default_max_tokens=max_tokens ) # 发送简单的测试请求 @@ -609,13 +614,15 @@ async def test_api_connection(data: ApiTestRequest): logger.info(f" - 提供商: {provider}") logger.info(f" - 模型: {llm_model}") logger.info(f" - Base URL: {api_base_url}") + logger.info(f" - Temperature: {temperature}") + logger.info(f" - Max Tokens: {max_tokens}") response = await test_service.generate_text( prompt=test_prompt, provider=provider, model=llm_model, - temperature=0.7, - max_tokens=8000, + temperature=temperature, + max_tokens=max_tokens, auto_mcp=False # 测试时不加载MCP工具 ) @@ -639,7 +646,9 @@ async def test_api_connection(data: ApiTestRequest): "details": { "api_available": True, "model_accessible": True, - "response_valid": bool(response) + "response_valid": bool(response), + "temperature": temperature, + "max_tokens": max_tokens } } diff --git a/backend/app/main.py b/backend/app/main.py index 526859e..9f0f462 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -184,7 +184,7 @@ else: @app.get("/") async def root(): return { - "message": "欢迎使用AI Story Creator", + "message": "欢迎使用MuMuAINovel", "version": config_settings.app_version, "docs": "/docs", "notice": "请先构建前端: cd frontend && npm run build" diff --git a/frontend/src/pages/Settings.tsx b/frontend/src/pages/Settings.tsx index fa5ec0a..2a99396 100644 --- a/frontend/src/pages/Settings.tsx +++ b/frontend/src/pages/Settings.tsx @@ -1,9 +1,9 @@ import { useState, useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; import { Card, Form, Input, Button, Select, Slider, InputNumber, message, Space, Typography, Spin, Modal, Alert, Grid, Tabs, List, Tag, Popconfirm, Empty, Row, Col } from 'antd'; -import { SettingOutlined, SaveOutlined, DeleteOutlined, ReloadOutlined, ArrowLeftOutlined, InfoCircleOutlined, CheckCircleOutlined, CloseCircleOutlined, ThunderboltOutlined, PlusOutlined, EditOutlined, CopyOutlined, WarningOutlined } from '@ant-design/icons'; +import { SaveOutlined, DeleteOutlined, ReloadOutlined, InfoCircleOutlined, CheckCircleOutlined, CloseCircleOutlined, ThunderboltOutlined, PlusOutlined, EditOutlined, CopyOutlined, WarningOutlined } from '@ant-design/icons'; import { settingsApi, mcpPluginApi } from '../services/api'; import type { SettingsUpdate, APIKeyPreset, PresetCreateRequest, APIKeyPresetConfig } from '../types'; +import { eventBus, EventNames } from '../store/eventBus'; const { Title, Text } = Typography; const { Option } = Select; @@ -11,7 +11,6 @@ const { useBreakpoint } = Grid; const { TextArea } = Input; export default function SettingsPage() { - const navigate = useNavigate(); const screens = useBreakpoint(); const isMobile = !screens.md; // md断点是768px const [form] = Form.useForm(); @@ -50,6 +49,7 @@ export default function SettingsPage() { if (activeTab === 'presets') { loadPresets(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { @@ -72,6 +72,7 @@ export default function SettingsPage() { setIsDefaultSettings(false); setHasSettings(true); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { // 如果404表示还没有设置,使用默认值 if (error?.response?.status === 404) { @@ -167,7 +168,7 @@ export default function SettingsPage() { okText: '前往 MCP 页面', cancelText: '稍后处理', onOk: () => { - navigate('/mcp-plugins'); + eventBus.emit(EventNames.SWITCH_TO_MCP_VIEW); }, }); } @@ -175,7 +176,7 @@ export default function SettingsPage() { console.error('Failed to disable MCP plugins:', err); } } - } catch (error) { + } catch { message.error('保存设置失败'); } finally { setLoading(false); @@ -218,7 +219,7 @@ export default function SettingsPage() { message.success('设置已删除'); setHasSettings(false); form.resetFields(); - } catch (error) { + } catch { message.error('删除设置失败'); } finally { setLoading(false); @@ -268,6 +269,7 @@ export default function SettingsPage() { if (!silent) { message.success(`成功获取 ${response.count || response.models.length} 个可用模型`); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { const errorMsg = error?.response?.data?.detail || '获取模型列表失败'; if (!silent) { @@ -292,6 +294,8 @@ export default function SettingsPage() { const apiBaseUrl = form.getFieldValue('api_base_url'); const provider = form.getFieldValue('api_provider'); const modelName = form.getFieldValue('llm_model'); + const temperature = form.getFieldValue('temperature'); + const maxTokens = form.getFieldValue('max_tokens'); if (!apiKey || !apiBaseUrl || !provider || !modelName) { message.warning('请先填写完整的配置信息'); @@ -306,7 +310,9 @@ export default function SettingsPage() { api_key: apiKey, api_base_url: apiBaseUrl, provider: provider, - llm_model: modelName + llm_model: modelName, + temperature: temperature, + max_tokens: maxTokens }); setTestResult(result); @@ -317,6 +323,7 @@ export default function SettingsPage() { } else { message.error('API 测试失败,请查看详细信息'); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { const errorMsg = error?.response?.data?.detail || '测试请求失败'; message.error(errorMsg); @@ -416,6 +423,7 @@ export default function SettingsPage() { await settingsApi.deletePreset(presetId); message.success('预设已删除'); loadPresets(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { message.error(error.response?.data?.detail || '删除失败'); console.error(error); @@ -503,7 +511,7 @@ export default function SettingsPage() { okText: '前往 MCP 页面', cancelText: '稍后处理', onOk: () => { - navigate('/mcp-plugins'); + eventBus.emit(EventNames.SWITCH_TO_MCP_VIEW); }, }); } @@ -784,11 +792,12 @@ export default function SettingsPage() { <> {contextHolder}
- <SettingOutlined style={{ color: 'rgba(255,255,255,0.9)', marginRight: 8 }} /> AI API 设置 @@ -829,31 +837,7 @@ export default function SettingsPage() { - - - + {/* 按钮区域预留 */} @@ -1399,99 +1383,135 @@ export default function SettingsPage() { open={isPresetModalVisible} onOk={handlePresetSave} onCancel={handlePresetCancel} - width={isMobile ? '90%' : 600} + width={isMobile ? '95%' : 640} centered okText="保存" cancelText="取消" + styles={{ + body: { + padding: isMobile ? '16px' : '20px 24px' + } + }} >
- - - + {/* 基本信息 */} + + + + + + + + + + + + -