mirror of
https://gitcode.com/JianFeeeee/TrulyMEM-TrueHumanMEM.git
synced 2026-10-15 12:15:32 +00:00
fix: 修复Windows打包后WebUI无法加载HTML页面及TUI配置持久化问题
This commit is contained in:
@ -21,6 +21,17 @@ from core.activity_recorder import get_recorder
|
|||||||
from core.embedded_db import EmbeddedGraphDB
|
from core.embedded_db import EmbeddedGraphDB
|
||||||
|
|
||||||
|
|
||||||
|
def get_resource_path(relative_path):
|
||||||
|
"""获取资源文件的绝对路径,兼容开发环境和PyInstaller打包环境"""
|
||||||
|
if hasattr(sys, 'frozen'):
|
||||||
|
# PyInstaller打包后的环境
|
||||||
|
base_path = sys._MEIPASS
|
||||||
|
else:
|
||||||
|
# 开发环境
|
||||||
|
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
return os.path.join(base_path, relative_path)
|
||||||
|
|
||||||
|
|
||||||
# 登录安全限制
|
# 登录安全限制
|
||||||
LOGIN_MAX_ATTEMPTS = 5 # 最大尝试次数
|
LOGIN_MAX_ATTEMPTS = 5 # 最大尝试次数
|
||||||
LOGIN_WAIT_MINUTES = 5 # 超过次数后等待分钟数
|
LOGIN_WAIT_MINUTES = 5 # 超过次数后等待分钟数
|
||||||
@ -142,7 +153,7 @@ def save_web_config(updates: dict) -> bool:
|
|||||||
|
|
||||||
WEB_CONFIG = load_web_config()
|
WEB_CONFIG = load_web_config()
|
||||||
|
|
||||||
_ui_dir = os.path.join(os.path.dirname(__file__), '..', 'ui')
|
_ui_dir = get_resource_path('ui')
|
||||||
app = Flask(__name__, static_folder=os.path.join(_ui_dir, 'static'), static_url_path='', template_folder=os.path.join(_ui_dir, 'templates'))
|
app = Flask(__name__, static_folder=os.path.join(_ui_dir, 'static'), static_url_path='', template_folder=os.path.join(_ui_dir, 'templates'))
|
||||||
app.secret_key = WEB_CONFIG.get("SECRET_KEY", "trulymem-secret-key-2026")
|
app.secret_key = WEB_CONFIG.get("SECRET_KEY", "trulymem-secret-key-2026")
|
||||||
app.permanent_session_lifetime = timedelta(days=7)
|
app.permanent_session_lifetime = timedelta(days=7)
|
||||||
|
|||||||
46
ui/app.py
46
ui/app.py
@ -51,6 +51,9 @@ class GraphMemoryApp(App):
|
|||||||
initial_config.api_key = api_config.get("api_key", "")
|
initial_config.api_key = api_config.get("api_key", "")
|
||||||
initial_config.base_url = api_config.get("base_url", "https://api.deepseek.com")
|
initial_config.base_url = api_config.get("base_url", "https://api.deepseek.com")
|
||||||
initial_config.model = api_config.get("model", "deepseek-v4-flash")
|
initial_config.model = api_config.get("model", "deepseek-v4-flash")
|
||||||
|
initial_config.enable_web = api_config.get("enable_web", False)
|
||||||
|
initial_config.web_port = api_config.get("web_port", 4096)
|
||||||
|
initial_config.enable_tui = api_config.get("enable_tui", True)
|
||||||
|
|
||||||
tool_limits = settings_data.get("tool_limits", {})
|
tool_limits = settings_data.get("tool_limits", {})
|
||||||
initial_config.persona_update_max = tool_limits.get("persona_update_max", 1)
|
initial_config.persona_update_max = tool_limits.get("persona_update_max", 1)
|
||||||
@ -144,6 +147,23 @@ class GraphMemoryApp(App):
|
|||||||
welcome_msg += f"API Key: {'已配置' if self._api_configured else '未配置'}\n\n输入消息开始对话"
|
welcome_msg += f"API Key: {'已配置' if self._api_configured else '未配置'}\n\n输入消息开始对话"
|
||||||
welcome = Message(role="assistant", content=welcome_msg)
|
welcome = Message(role="assistant", content=welcome_msg)
|
||||||
history.add_message(welcome)
|
history.add_message(welcome)
|
||||||
|
|
||||||
|
# 自动启动Web服务(如果配置中启用了)
|
||||||
|
if self._backend_client:
|
||||||
|
settings_result = self._backend_client.get_settings()
|
||||||
|
settings_data = settings_result.get("data", {})
|
||||||
|
api_config = settings_data.get("api_config", {})
|
||||||
|
enable_web = api_config.get("enable_web", False)
|
||||||
|
web_port = api_config.get("web_port", 4096)
|
||||||
|
|
||||||
|
# 更新状态栏的Web服务状态
|
||||||
|
try:
|
||||||
|
status_bar.set_web_status(self._web_running, web_port if self._web_running else 0)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if enable_web:
|
||||||
|
self._start_web_server(web_port)
|
||||||
|
|
||||||
def _start_web_server(self, port: int = 4096) -> None:
|
def _start_web_server(self, port: int = 4096) -> None:
|
||||||
"""在当前进程通过线程启动 Web 服务(无需子进程)"""
|
"""在当前进程通过线程启动 Web 服务(无需子进程)"""
|
||||||
@ -153,10 +173,20 @@ class GraphMemoryApp(App):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from web_api import run_web_server
|
from web_api import run_web_server
|
||||||
|
from .widgets.status_bar import StatusBar
|
||||||
|
|
||||||
run_web_server(port=port)
|
run_web_server(port=port)
|
||||||
self._web_running = True
|
self._web_running = True
|
||||||
if self._backend_client:
|
if self._backend_client:
|
||||||
self._backend_client.report_web_status(True, port)
|
self._backend_client.report_web_status(True, port)
|
||||||
|
|
||||||
|
# 更新状态栏
|
||||||
|
try:
|
||||||
|
status_bar = self.query_one(StatusBar)
|
||||||
|
status_bar.set_web_status(True, port)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
self.notify(f"Web 服务已启动 → http://0.0.0.0:{port}", title="Web 服务")
|
self.notify(f"Web 服务已启动 → http://0.0.0.0:{port}", title="Web 服务")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.notify(f"启动 Web 服务失败: {e}", severity="error")
|
self.notify(f"启动 Web 服务失败: {e}", severity="error")
|
||||||
@ -166,12 +196,22 @@ class GraphMemoryApp(App):
|
|||||||
if self._web_running:
|
if self._web_running:
|
||||||
try:
|
try:
|
||||||
from web_api import stop_web_server
|
from web_api import stop_web_server
|
||||||
|
from .widgets.status_bar import StatusBar
|
||||||
|
|
||||||
stop_web_server()
|
stop_web_server()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
self._web_running = False
|
self._web_running = False
|
||||||
if self._backend_client:
|
if self._backend_client:
|
||||||
self._backend_client.report_web_status(False, 0)
|
self._backend_client.report_web_status(False, 0)
|
||||||
|
|
||||||
|
# 更新状态栏
|
||||||
|
try:
|
||||||
|
status_bar = self.query_one(StatusBar)
|
||||||
|
status_bar.set_web_status(False)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
self.notify("Web 服务已停止", title="Web 服务")
|
self.notify("Web 服务已停止", title="Web 服务")
|
||||||
|
|
||||||
def on_unmount(self) -> None:
|
def on_unmount(self) -> None:
|
||||||
@ -370,6 +410,12 @@ class GraphMemoryApp(App):
|
|||||||
self._start_web_server(config.web_port)
|
self._start_web_server(config.web_port)
|
||||||
else:
|
else:
|
||||||
self._stop_web_server()
|
self._stop_web_server()
|
||||||
|
|
||||||
|
# 更新状态栏的Web服务状态
|
||||||
|
try:
|
||||||
|
status_bar.set_web_status(self._web_running, config.web_port if self._web_running else 0)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
self.notify("✅ 配置已保存并生效", title="配置成功", severity="information")
|
self.notify("✅ 配置已保存并生效", title="配置成功", severity="information")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -18,6 +18,7 @@ class StatusBar(Static):
|
|||||||
self._shortcuts = "F1:帮助 F2:侧边栏 F3:工具详情 F5:清屏 F6:退出"
|
self._shortcuts = "F1:帮助 F2:侧边栏 F3:工具详情 F5:清屏 F6:退出"
|
||||||
self._license_info = "本项目由jianf设计,以GPLv3形式开源"
|
self._license_info = "本项目由jianf设计,以GPLv3形式开源"
|
||||||
self._api_status = "未配置"
|
self._api_status = "未配置"
|
||||||
|
self._web_status = "未启动"
|
||||||
self._processing = False
|
self._processing = False
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
@ -27,8 +28,9 @@ class StatusBar(Static):
|
|||||||
def _update_display(self) -> None:
|
def _update_display(self) -> None:
|
||||||
"""更新显示"""
|
"""更新显示"""
|
||||||
status_icon = "●" if self._api_status == "已配置" else "○"
|
status_icon = "●" if self._api_status == "已配置" else "○"
|
||||||
|
web_icon = "●" if self._web_status != "未启动" else "○"
|
||||||
processing_indicator = " [处理中...]" if self._processing else ""
|
processing_indicator = " [处理中...]" if self._processing else ""
|
||||||
self.update(f"{status_icon} API: {self._api_status}{processing_indicator} | {self._license_info} | {self._shortcuts}")
|
self.update(f"{status_icon} API: {self._api_status} | {web_icon} Web: {self._web_status}{processing_indicator} | {self._license_info} | {self._shortcuts}")
|
||||||
|
|
||||||
def set_api_status(self, configured: bool) -> None:
|
def set_api_status(self, configured: bool) -> None:
|
||||||
"""设置API状态"""
|
"""设置API状态"""
|
||||||
@ -39,3 +41,11 @@ class StatusBar(Static):
|
|||||||
"""设置处理状态"""
|
"""设置处理状态"""
|
||||||
self._processing = processing
|
self._processing = processing
|
||||||
self._update_display()
|
self._update_display()
|
||||||
|
|
||||||
|
def set_web_status(self, running: bool, port: int = 0) -> None:
|
||||||
|
"""设置Web服务状态"""
|
||||||
|
if running:
|
||||||
|
self._web_status = f"运行中(:{port})"
|
||||||
|
else:
|
||||||
|
self._web_status = "未启动"
|
||||||
|
self._update_display()
|
||||||
|
|||||||
Reference in New Issue
Block a user