Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# LLM API配置(支持 OpenAI SDK 格式的任意 LLM API
# 推荐使用阿里百炼平台qwen-plus模型:https://bailian.console.aliyun.com/
# 注意消耗较大,可先进行小于40轮的模拟尝试
# LLM API (any OpenAI-compatible API)
# Alibaba Bailian qwen-plus: https://bailian.console.aliyun.com/
# High token usage; try simulations with fewer than 40 rounds first
LLM_API_KEY=your_api_key_here
LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_MODEL_NAME=qwen-plus

# ===== ZEP记忆图谱配置 =====
# 每月免费额度即可支撑简单使用:https://app.getzep.com/
# Zep graph memory: https://app.getzep.com/
ZEP_API_KEY=your_zep_api_key_here

# ===== 加速 LLM 配置(可选)=====
# 注意如果不使用加速配置,env文件中就不要出现下面的配置项
# Optional: accelerated LLM (omit these keys if not used)
LLM_BOOST_API_KEY=your_api_key_here
LLM_BOOST_BASE_URL=your_base_url_here
LLM_BOOST_MODEL_NAME=your_model_name_here
12 changes: 6 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.DS_Store
Thumbs.db

# 环境变量(保护敏感信息)
# Env files (sensitive)
.env
.env.local
.env.*.local
Expand Down Expand Up @@ -36,7 +36,7 @@ yarn-error.log*
*.swp
*.swo

# 测试
# Tests
.pytest_cache/
.coverage
htmlcov/
Expand All @@ -45,16 +45,16 @@ htmlcov/
.cursor/
.claude/

# 文档与测试程序
# Docs and test apps
mydoc/
mytest/

# 日志文件
# Logs
backend/logs/
*.log

# 上传文件
# Uploads
backend/uploads/

# Docker 数据
# Docker data
data/
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
FROM python:3.11

# 安装 Node.js (满足 >=18)及必要工具
# Install Node.js (>=18) and tools
RUN apt-get update \
&& apt-get install -y --no-install-recommends nodejs npm \
&& rm -rf /var/lib/apt/lists/*

# uv 官方镜像复制 uv
# Copy uv from official image
COPY --from=ghcr.io/astral-sh/uv:0.9.26 /uv /uvx /bin/

WORKDIR /app

# 先复制依赖描述文件以利用缓存
# Copy dependency files first for cache
COPY package.json package-lock.json ./
COPY frontend/package.json frontend/package-lock.json ./frontend/
COPY backend/pyproject.toml backend/uv.lock ./backend/

# 安装依赖(Node + Python
# Install dependencies (Node + Python)
RUN npm ci \
&& npm ci --prefix frontend \
&& cd backend && uv sync --frozen

# 复制项目源码
# Copy project source
COPY . .

EXPOSE 3000 5001

# 同时启动前后端(开发模式)
# Start frontend and backend (dev mode)
CMD ["npm", "run", "dev"]
55 changes: 24 additions & 31 deletions backend/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""
MiroFish Backend - Flask应用工厂
MiroFish Backend - Flask application factory.
"""

import os
import warnings

# 抑制 multiprocessing resource_tracker 的警告(来自第三方库如 transformers
# 需要在所有其他导入之前设置
# Suppress multiprocessing resource_tracker warnings (from third-party libs e.g. transformers).
# Must be set before any other imports.
warnings.filterwarnings("ignore", message=".*resource_tracker.*")

from flask import Flask, request
Expand All @@ -17,64 +17,57 @@


def create_app(config_class=Config):
"""Flask应用工厂函数"""
"""Flask application factory."""
app = Flask(__name__)
app.config.from_object(config_class)

# 设置JSON编码:确保中文直接显示(而不是 \uXXXX 格式)
# Flask >= 2.3 使用 app.json.ensure_ascii,旧版本使用 JSON_AS_ASCII 配置

# JSON: ensure Unicode is not escaped (e.g. for non-ASCII)
if hasattr(app, 'json') and hasattr(app.json, 'ensure_ascii'):
app.json.ensure_ascii = False

# 设置日志

logger = setup_logger('mirofish')
# 只在 reloader 子进程中打印启动信息(避免 debug 模式下打印两次)

# Log startup only in reloader child (avoid duplicate in debug)
is_reloader_process = os.environ.get('WERKZEUG_RUN_MAIN') == 'true'
debug_mode = app.config.get('DEBUG', False)
should_log_startup = not debug_mode or is_reloader_process

if should_log_startup:
logger.info("=" * 50)
logger.info("MiroFish Backend 启动中...")
logger.info("MiroFish Backend starting...")
logger.info("=" * 50)

# 启用CORS

CORS(app, resources={r"/api/*": {"origins": "*"}})

# 注册模拟进程清理函数(确保服务器关闭时终止所有模拟进程)

from .services.simulation_runner import SimulationRunner
SimulationRunner.register_cleanup()
if should_log_startup:
logger.info("已注册模拟进程清理函数")

# 请求日志中间件
logger.info("Simulation process cleanup registered")

@app.before_request
def log_request():
logger = get_logger('mirofish.request')
logger.debug(f"请求: {request.method} {request.path}")
logger.debug(f"Request: {request.method} {request.path}")
if request.content_type and 'json' in request.content_type:
logger.debug(f"请求体: {request.get_json(silent=True)}")
logger.debug(f"Body: {request.get_json(silent=True)}")

@app.after_request
def log_response(response):
logger = get_logger('mirofish.request')
logger.debug(f"响应: {response.status_code}")
logger.debug(f"Response: {response.status_code}")
return response

# 注册蓝图

from .api import graph_bp, simulation_bp, report_bp
app.register_blueprint(graph_bp, url_prefix='/api/graph')
app.register_blueprint(simulation_bp, url_prefix='/api/simulation')
app.register_blueprint(report_bp, url_prefix='/api/report')

# 健康检查

@app.route('/health')
def health():
return {'status': 'ok', 'service': 'MiroFish Backend'}

if should_log_startup:
logger.info("MiroFish Backend 启动完成")
logger.info("MiroFish Backend started")

return app

2 changes: 1 addition & 1 deletion backend/app/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
API路由模块
API route modules.
"""

from flask import Blueprint
Expand Down
Loading