feat: auto LLM feedback runner + problem link + 5xx retry

- Add SubmissionFeedbackRunner: async background queue for auto LLM feedback
- Enqueue feedback generation after each submission in submitProblem()
- Register runner in main.cc with CSP_FEEDBACK_AUTO_RUN env var
- Add problem_title to GET /api/v1/submissions/{id} response
- Frontend: clickable problem link on submission detail page
- Enhance LLM prompt with richer analysis dimensions
- Add 5xx/connection error retry (max 5 attempts) in Python LLM script

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
这个提交包含在:
cryptocommuniums-afk
2026-02-16 15:13:35 +08:00
父节点 bc2e085c70
当前提交 7860414ae5
修改 37 个文件,包含 312 行新增5343 行删除

查看文件

@@ -6,6 +6,7 @@
#include "csp/services/contest_service.h"
#include "csp/services/problem_service.h"
#include "csp/services/solution_access_service.h"
#include "csp/services/submission_feedback_runner.h"
#include "csp/services/submission_feedback_service.h"
#include "csp/services/submission_service.h"
#include "http_auth.h"
@@ -130,6 +131,10 @@ void SubmissionController::submitProblem(
services::SubmissionService svc(csp::AppState::Instance().db());
auto s = svc.CreateAndJudge(create);
// Auto-enqueue LLM feedback generation in background.
services::SubmissionFeedbackRunner::Instance().Enqueue(s.id);
cb(JsonOk(domain::ToJson(s)));
} catch (const std::invalid_argument&) {
cb(JsonError(drogon::k400BadRequest, "invalid numeric field"));
@@ -187,6 +192,14 @@ void SubmissionController::getSubmission(
Json::Value payload = domain::ToJson(*s);
payload["code"] = s->code;
// Attach problem title for frontend linking.
{
services::ProblemService psvc(csp::AppState::Instance().db());
if (const auto p = psvc.GetById(s->problem_id); p.has_value()) {
payload["problem_title"] = p->title;
}
}
services::SolutionAccessService access_svc(csp::AppState::Instance().db());
const auto stats =
access_svc.QueryUserProblemViewStats(s->user_id, s->problem_id);