0.1.0
This commit is contained in:
+120
-2
@@ -16,12 +16,67 @@ const { spawn } = require("child_process");
|
||||
const path = require("path");
|
||||
const net = require("net");
|
||||
const { URL } = require("url");
|
||||
const fs = require("fs");
|
||||
|
||||
const rootDir = path.resolve(__dirname, "..");
|
||||
const frontendDir = path.join(rootDir, "wolai-frontend");
|
||||
const backendDir = path.join(rootDir, "wolai-backend");
|
||||
const mineruDir = path.join(rootDir, "services", "mineru");
|
||||
const baseEnv = { ...process.env };
|
||||
const frontendEnv = { ...baseEnv };
|
||||
const backendEnv = { ...baseEnv };
|
||||
const mineruEnv = { ...baseEnv };
|
||||
|
||||
const pythonBin = process.env.PYTHON_BIN || "python";
|
||||
function loadEnvFile(filePath, targetEnv, { overrideSupabase = false } = {}) {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
return;
|
||||
}
|
||||
const content = fs.readFileSync(filePath, "utf8");
|
||||
content.split(/\r?\n/).forEach((line) => {
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed || trimmed.startsWith("#")) return;
|
||||
const eqIndex = trimmed.indexOf("=");
|
||||
if (eqIndex <= 0) return;
|
||||
const key = trimmed.slice(0, eqIndex).trim();
|
||||
const value = trimmed.slice(eqIndex + 1).trim();
|
||||
const hasValue = Boolean(targetEnv[key]);
|
||||
const shouldForce =
|
||||
overrideSupabase && key.startsWith("SUPABASE_") && (!hasValue || targetEnv[key].includes("supabase.co"));
|
||||
if (!hasValue || shouldForce) {
|
||||
targetEnv[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 强制后端优先使用本地 .env 中的 Supabase 配置,避免系统环境变量指向线上实例。
|
||||
loadEnvFile(path.join(backendDir, ".env"), backendEnv, { overrideSupabase: true });
|
||||
loadEnvFile(path.join(rootDir, ".env.local"), backendEnv);
|
||||
loadEnvFile(path.join(rootDir, ".env.local"), frontendEnv);
|
||||
loadEnvFile(path.join(rootDir, ".env.local"), mineruEnv);
|
||||
|
||||
function resolvePythonBin() {
|
||||
const suffixes =
|
||||
process.platform === "win32"
|
||||
? [
|
||||
["venv", "Scripts", "python.exe"],
|
||||
[".venv", "Scripts", "python.exe"],
|
||||
]
|
||||
: [
|
||||
["venv", "bin", "python3"],
|
||||
["venv", "bin", "python"],
|
||||
[".venv", "bin", "python3"],
|
||||
[".venv", "bin", "python"],
|
||||
];
|
||||
const candidates = suffixes.map((parts) => path.join(backendDir, ...parts));
|
||||
for (const candidate of candidates) {
|
||||
if (fs.existsSync(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const pythonBin = process.env.PYTHON_BIN || resolvePythonBin() || "python";
|
||||
const celeryBin = process.env.CELERY_BIN || "celery";
|
||||
const skipCelery =
|
||||
(process.env.SKIP_CELERY || "").toLowerCase() === "1" ||
|
||||
@@ -34,6 +89,7 @@ const tasks = [
|
||||
name: "frontend",
|
||||
command: process.env.FRONTEND_CMD || "pnpm dev",
|
||||
cwd: frontendDir,
|
||||
env: frontendEnv,
|
||||
},
|
||||
{
|
||||
name: "backend",
|
||||
@@ -41,9 +97,59 @@ const tasks = [
|
||||
process.env.BACKEND_CMD ||
|
||||
`${pythonBin} -m uvicorn app.main:app --reload --port 8000`,
|
||||
cwd: backendDir,
|
||||
env: backendEnv,
|
||||
},
|
||||
];
|
||||
|
||||
function resolveMineru() {
|
||||
// 优先使用带 ROCm 的全局 venv,找不到再回退 services/mineru/.venv
|
||||
const rocmPython = path.join("F:\\", "rocm", ".venv-rocm312", "Scripts", "python.exe");
|
||||
const localVenvPython = path.join(mineruDir, ".venv", "Scripts", "python.exe");
|
||||
const pythonCandidates = [rocmPython, localVenvPython].filter((p) => fs.existsSync(p));
|
||||
const venvPython = pythonCandidates[0];
|
||||
const srcDir = path.join(mineruDir, "src");
|
||||
if (!venvPython || !fs.existsSync(srcDir)) {
|
||||
logPrefix(
|
||||
"mineru",
|
||||
"未找到 MinerU 虚拟环境或源码,已跳过自动启动。请先运行 services/mineru/setup.ps1",
|
||||
);
|
||||
return null;
|
||||
}
|
||||
const endpoint = mineruEnv.MINERU_ENDPOINT || "http://127.0.0.1:18888";
|
||||
const url = new URL(endpoint);
|
||||
const host = url.hostname || "127.0.0.1";
|
||||
const port = url.port || "18888";
|
||||
const command =
|
||||
process.env.MINERU_CMD ||
|
||||
`${venvPython} -m uvicorn mineru.cli.fast_api:app --host ${host} --port ${port}`;
|
||||
const modelPath = path.join(mineruDir, "models", "MinerU2.5-2509-1.2B");
|
||||
const configPath = path.join(mineruDir, "mineru.json");
|
||||
return {
|
||||
name: "mineru",
|
||||
command,
|
||||
cwd: srcDir,
|
||||
env: {
|
||||
...mineruEnv,
|
||||
PYTHONPATH: srcDir,
|
||||
MINERU_ENDPOINT: endpoint,
|
||||
// 默认使用本地 VLM 模型
|
||||
MINERU_TOOLS_CONFIG_JSON: configPath,
|
||||
MINERU_MODEL_SOURCE: "local",
|
||||
MINERU_MODEL_PATH: modelPath,
|
||||
MINERU_DEFAULT_BACKEND: "vlm-transformers",
|
||||
MINERU_TIMEOUT_SECONDS: mineruEnv.MINERU_TIMEOUT_SECONDS || "600",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const mineruTask = resolveMineru();
|
||||
if (mineruTask) {
|
||||
tasks.unshift(mineruTask);
|
||||
backendEnv.MINERU_ENDPOINT = mineruTask.env.MINERU_ENDPOINT;
|
||||
}
|
||||
|
||||
console.log(`[system] Python 解释器:${pythonBin}`);
|
||||
|
||||
const children = [];
|
||||
let shuttingDown = false;
|
||||
|
||||
@@ -57,7 +163,7 @@ function startTask(task) {
|
||||
cwd: task.cwd,
|
||||
stdio: "inherit",
|
||||
shell: true,
|
||||
env: { ...process.env },
|
||||
env: task.env ? { ...task.env } : { ...process.env },
|
||||
});
|
||||
|
||||
child.on("exit", (code, signal) => {
|
||||
@@ -133,6 +239,7 @@ async function checkRedisReachable(urlString, timeoutMs = 2000) {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let celeryScheduled = false;
|
||||
if (!skipCelery) {
|
||||
const celeryTask = {
|
||||
name: "celery",
|
||||
@@ -142,8 +249,10 @@ async function main() {
|
||||
|
||||
if (celeryCmdFromEnv) {
|
||||
tasks.push(celeryTask);
|
||||
celeryScheduled = true;
|
||||
} else if (await checkRedisReachable(redisUrl)) {
|
||||
tasks.push(celeryTask);
|
||||
celeryScheduled = true;
|
||||
} else {
|
||||
// Redis 未就绪时直接跳过 Celery,避免热调试流程整体退出。
|
||||
logPrefix(
|
||||
@@ -153,6 +262,15 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!celeryScheduled) {
|
||||
backendEnv.CELERY_TASK_ALWAYS_EAGER = "1";
|
||||
backendEnv.CELERY_TASK_EAGER_PROPAGATES = backendEnv.CELERY_TASK_EAGER_PROPAGATES || "1";
|
||||
logPrefix(
|
||||
"backend",
|
||||
"未启动 Celery,自动启用 task_always_eager 模式用于同步执行后台任务。",
|
||||
);
|
||||
}
|
||||
|
||||
if (tasks.length === 0) {
|
||||
console.error("未配置任何可运行的任务,检查环境变量设置。");
|
||||
process.exit(1);
|
||||
|
||||
Reference in New Issue
Block a user