- Refactor 6000+ line web_server.py into server/ module - Create separate modules: auth, chat, conversation, files, admin, etc. - Keep web_server.py as backward-compatible entry point - Add container running status field in user_container_manager - Improve admin dashboard API with credentials and debug support 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
97 lines
3.9 KiB
Python
97 lines
3.9 KiB
Python
from __future__ import annotations
|
|
import time
|
|
from flask import Blueprint, jsonify
|
|
|
|
from .auth_helpers import api_login_required, resolve_admin_policy
|
|
from .context import with_terminal
|
|
from .state import (
|
|
PROJECT_STORAGE_CACHE,
|
|
PROJECT_STORAGE_CACHE_TTL_SECONDS,
|
|
PROJECT_MAX_STORAGE_MB,
|
|
container_manager,
|
|
user_manager,
|
|
)
|
|
from config import AGENT_VERSION
|
|
|
|
status_bp = Blueprint('status', __name__)
|
|
|
|
|
|
@status_bp.route('/api/status')
|
|
@api_login_required
|
|
@with_terminal
|
|
def get_status(terminal, workspace, username):
|
|
"""获取系统状态(包含对话、容器、版本等信息)"""
|
|
status = terminal.get_status()
|
|
if terminal.terminal_manager:
|
|
status['terminals'] = terminal.terminal_manager.list_terminals()
|
|
try:
|
|
current_conv = terminal.context_manager.current_conversation_id
|
|
status.setdefault('conversation', {})['current_id'] = current_conv
|
|
if current_conv and not current_conv.startswith('temp_'):
|
|
current_conv_data = terminal.context_manager.conversation_manager.load_conversation(current_conv)
|
|
if current_conv_data:
|
|
status['conversation']['title'] = current_conv_data.get('title', '未知对话')
|
|
status['conversation']['created_at'] = current_conv_data.get('created_at')
|
|
status['conversation']['updated_at'] = current_conv_data.get('updated_at')
|
|
except Exception as exc:
|
|
print(f"[Status] 获取当前对话信息失败: {exc}")
|
|
status['project_path'] = str(workspace.project_path)
|
|
try:
|
|
status['container'] = container_manager.get_container_status(username)
|
|
except Exception as exc:
|
|
status['container'] = {"success": False, "error": str(exc)}
|
|
status['version'] = AGENT_VERSION
|
|
try:
|
|
policy = resolve_admin_policy(user_manager.get_user(username))
|
|
status['admin_policy'] = {
|
|
"ui_blocks": policy.get("ui_blocks") or {},
|
|
"disabled_models": policy.get("disabled_models") or [],
|
|
"forced_category_states": policy.get("forced_category_states") or {},
|
|
"version": policy.get("updated_at"),
|
|
}
|
|
except Exception:
|
|
pass
|
|
return jsonify(status)
|
|
|
|
|
|
@status_bp.route('/api/container-status')
|
|
@api_login_required
|
|
@with_terminal
|
|
def get_container_status_api(terminal, workspace, username):
|
|
try:
|
|
status = container_manager.get_container_status(username)
|
|
return jsonify({"success": True, "data": status})
|
|
except Exception as exc:
|
|
return jsonify({"success": False, "error": str(exc)}), 500
|
|
|
|
|
|
@status_bp.route('/api/project-storage')
|
|
@api_login_required
|
|
@with_terminal
|
|
def get_project_storage(terminal, workspace, username):
|
|
now = time.time()
|
|
cache_entry = PROJECT_STORAGE_CACHE.get(username)
|
|
if cache_entry and (now - cache_entry.get("ts", 0)) < PROJECT_STORAGE_CACHE_TTL_SECONDS:
|
|
return jsonify({"success": True, "data": cache_entry["data"]})
|
|
try:
|
|
file_manager = getattr(terminal, 'file_manager', None)
|
|
if not file_manager:
|
|
return jsonify({"success": False, "error": "文件管理器未初始化"}), 500
|
|
used_bytes = file_manager._get_project_size()
|
|
limit_bytes = PROJECT_MAX_STORAGE_MB * 1024 * 1024 if PROJECT_MAX_STORAGE_MB else None
|
|
usage_percent = (used_bytes / limit_bytes * 100) if limit_bytes else None
|
|
data = {
|
|
"used_bytes": used_bytes,
|
|
"limit_bytes": limit_bytes,
|
|
"limit_label": f"{PROJECT_MAX_STORAGE_MB}MB" if PROJECT_MAX_STORAGE_MB else "未限制",
|
|
"usage_percent": usage_percent
|
|
}
|
|
PROJECT_STORAGE_CACHE[username] = {"ts": now, "data": data}
|
|
return jsonify({"success": True, "data": data})
|
|
except Exception as exc:
|
|
stale = PROJECT_STORAGE_CACHE.get(username)
|
|
if stale:
|
|
return jsonify({"success": True, "data": stale.get("data"), "stale": True}), 200
|
|
return jsonify({"success": False, "error": str(exc)}), 500
|
|
|