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
11 changes: 8 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# LLM API配置(支持 OpenAI SDK 格式的任意 LLM API)
# 推荐使用阿里百炼平台qwen-plus模型:https://bailian.console.aliyun.com/
# 注意消耗较大,可先进行小于40轮的模拟尝试
# LLM API Configuration (any OpenAI-SDK-compatible API)
# Recommended: Alibaba qwen-plus via Bailian Platform (cost-effective for high volume):
# https://bailian.console.aliyun.com/
# Also works with: OpenAI (gpt-4o-mini), Anthropic (via compatible proxy), etc.
# Note: token usage is high — start with fewer than 40 simulation rounds.
LLM_API_KEY=your_api_key_here
LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_MODEL_NAME=qwen-plus

# CORS — comma-separated allowed origins (set to your frontend domain in production)
CORS_ORIGINS=http://localhost:5173,http://localhost:5001

# ===== ZEP记忆图谱配置 =====
# 每月免费额度即可支撑简单使用:https://app.getzep.com/
ZEP_API_KEY=your_zep_api_key_here
Expand Down
4 changes: 2 additions & 2 deletions backend/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ def create_app(config_class=Config):
logger.info("MiroFish Backend 启动中...")
logger.info("=" * 50)

# 启用CORS
CORS(app, resources={r"/api/*": {"origins": "*"}})
# 启用CORS — 限制为配置的允许来源,而非通配符 "*"
CORS(app, resources={r"/api/*": {"origins": config_class.CORS_ORIGINS}})

# 注册模拟进程清理函数(确保服务器关闭时终止所有模拟进程)
from .services.simulation_runner import SimulationRunner
Expand Down
14 changes: 5 additions & 9 deletions backend/app/api/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,7 @@ def generate_ontology():
except Exception as e:
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -489,7 +488,7 @@ def wait_progress_callback(msg, progress_ratio):

except Exception as e:
# 更新项目状态为失败
build_logger.error(f"[{task_id}] 图谱构建失败: {str(e)}")
build_logger.error(f"[{task_id}] 图谱构建失败: {str(e)}", exc_info=True)
build_logger.debug(traceback.format_exc())

project.status = ProjectStatus.FAILED
Expand Down Expand Up @@ -519,8 +518,7 @@ def wait_progress_callback(msg, progress_ratio):
except Exception as e:
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -584,8 +582,7 @@ def get_graph_data(graph_id: str):
except Exception as e:
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand All @@ -612,6 +609,5 @@ def delete_graph(graph_id: str):
except Exception as e:
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500
90 changes: 36 additions & 54 deletions backend/app/api/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"""

import os
import traceback
import threading
from flask import request, jsonify, send_file

Expand Down Expand Up @@ -167,7 +166,7 @@ def progress_callback(stage, progress, message):
task_manager.fail_task(task_id, report.error or "报告生成失败")

except Exception as e:
logger.error(f"报告生成失败: {str(e)}")
logger.error(f"报告生成失败: {str(e)}", exc_info=True)
task_manager.fail_task(task_id, str(e))

# 启动后台线程
Expand All @@ -187,11 +186,10 @@ def progress_callback(stage, progress, message):
})

except Exception as e:
logger.error(f"启动报告生成任务失败: {str(e)}")
logger.error(f"启动报告生成任务失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -260,7 +258,7 @@ def get_generate_status():
})

except Exception as e:
logger.error(f"查询任务状态失败: {str(e)}")
logger.error(f"查询任务状态失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e)
Expand Down Expand Up @@ -303,11 +301,10 @@ def get_report(report_id: str):
})

except Exception as e:
logger.error(f"获取报告失败: {str(e)}")
logger.error(f"获取报告失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -342,11 +339,10 @@ def get_report_by_simulation(simulation_id: str):
})

except Exception as e:
logger.error(f"获取报告失败: {str(e)}")
logger.error(f"获取报告失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -382,11 +378,10 @@ def list_reports():
})

except Exception as e:
logger.error(f"列出报告失败: {str(e)}")
logger.error(f"列出报告失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -428,11 +423,10 @@ def download_report(report_id: str):
)

except Exception as e:
logger.error(f"下载报告失败: {str(e)}")
logger.error(f"下载报告失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand All @@ -454,11 +448,10 @@ def delete_report(report_id: str):
})

except Exception as e:
logger.error(f"删除报告失败: {str(e)}")
logger.error(f"删除报告失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -551,11 +544,10 @@ def chat_with_report_agent():
})

except Exception as e:
logger.error(f"对话失败: {str(e)}")
logger.error(f"对话失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -594,11 +586,10 @@ def get_report_progress(report_id: str):
})

except Exception as e:
logger.error(f"获取报告进度失败: {str(e)}")
logger.error(f"获取报告进度失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -645,11 +636,10 @@ def get_report_sections(report_id: str):
})

except Exception as e:
logger.error(f"获取章节列表失败: {str(e)}")
logger.error(f"获取章节列表失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -689,11 +679,10 @@ def get_single_section(report_id: str, section_index: int):
})

except Exception as e:
logger.error(f"获取章节内容失败: {str(e)}")
logger.error(f"获取章节内容失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -740,11 +729,10 @@ def check_report_status(simulation_id: str):
})

except Exception as e:
logger.error(f"检查报告状态失败: {str(e)}")
logger.error(f"检查报告状态失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -801,11 +789,10 @@ def get_agent_log(report_id: str):
})

except Exception as e:
logger.error(f"获取Agent日志失败: {str(e)}")
logger.error(f"获取Agent日志失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -835,11 +822,10 @@ def stream_agent_log(report_id: str):
})

except Exception as e:
logger.error(f"获取Agent日志失败: {str(e)}")
logger.error(f"获取Agent日志失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -883,11 +869,10 @@ def get_console_log(report_id: str):
})

except Exception as e:
logger.error(f"获取控制台日志失败: {str(e)}")
logger.error(f"获取控制台日志失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -917,11 +902,10 @@ def stream_console_log(report_id: str):
})

except Exception as e:
logger.error(f"获取控制台日志失败: {str(e)}")
logger.error(f"获取控制台日志失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -967,11 +951,10 @@ def search_graph_tool():
})

except Exception as e:
logger.error(f"图谱搜索失败: {str(e)}")
logger.error(f"图谱搜索失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500


Expand Down Expand Up @@ -1007,9 +990,8 @@ def get_graph_statistics_tool():
})

except Exception as e:
logger.error(f"获取图谱统计失败: {str(e)}")
logger.error(f"获取图谱统计失败: {str(e)}", exc_info=True)
return jsonify({
"success": False,
"error": str(e),
"traceback": traceback.format_exc()
"error": str(e)
}), 500
Loading