// HLDP-ZY://agents/zhuyuan-dev-agent/server.js
// @guardian: ICE-GL-ZY001 · 铸渊
// @sovereign: TCS-0002∞ · 冰朔
// @copyright: 国作登字-2026-A-00037559
// BD001 常驻Agent v4.0 — 全实时仪表盘
require("dotenv").config();
const express = require("express");
const path = require("path");
const fs = require("fs");
const { handleTask } = require("./modules/task-receiver");
const { sendNotification } = require("./modules/email-notify");
const { expandPlan } = require("./modules/plan-expander");
const { call: rawCall, getStatus: getModelStatus } = require("./modules/model-caller");
const { executePlan } = require("./modules/executor");
const { createLogger, readLatestRun, listRuns } = require("./modules/logger");
const { wrapModelCaller, reset, getCallCount, isBudgetExceeded } = require("./modules/cost-guard");
const { record: writeBrain, recordMilestone, AGENT_ID } = require("./modules/brain-writer");
const { wakeAndCheck, testConnection } = require("./modules/notion-poller");
const safeCall = wrapModelCaller(rawCall);
const app = express();
app.use(express.json({ limit: "10mb" }));
const PORT = process.env.PORT || 3003;
const PLANS_DIR = path.join(__dirname, "plans");
if (!fs.existsSync(PLANS_DIR)) fs.mkdirSync(PLANS_DIR, { recursive: true });
const START_TIME = new Date().toISOString();
// ═══ 全实时仪表盘 v4.0 ═══
app.get("/", (req, res) => {
const html = `
BD001 · 铸渊开发Agent
🔔
每晚 20:00 自动
`;
res.set('Content-Type', 'text/html;charset=utf-8').send(html);
});
// ═══ API ═══
app.get("/health", (req, res) => {
let modelStatus = {};
try { modelStatus = getModelStatus ? getModelStatus() : {}; } catch(e) { modelStatus = { error: e.message }; }
res.json({
status: "ok", agent: "zhuyuan-dev-agent", version: "4.0", persona: AGENT_ID,
constitution: true, api_calls: getCallCount(), started_at: START_TIME,
model: {
primary: process.env.YUNWU_BASE_URL ? "yunwu.ai" : "unknown",
backup: process.env.DEEPSEEK_BASE_URL ? "deepseek" : "unknown",
primary_ok: modelStatus.source !== "deepseek" || !modelStatus.fail_count,
backup_available: !!process.env.DEEPSEEK_API_KEY,
fail_count: modelStatus.fail_count || 0,
source: modelStatus.source || "yunwu.ai"
}
});
});
app.get("/notion-status", async (req, res) => {
try { res.json(await testConnection()); } catch (err) { res.json({ ok: false, error: err.message }); }
});
app.post("/wake", async (req, res) => {
try {
const result = await wakeAndCheck({ log: console.log });
if (result.tasks_found > 0) writeBrain("notion-wake-"+Date.now(), { input:"收到唤醒", decision:"找到"+result.tasks_found+"个任务", execution:"标记"+result.tasks_marked+"个" });
res.json(result);
} catch (err) { res.status(500).json({ ok: false, error: err.message }); }
});
app.post("/task", handleTask);
app.get("/logs/latest", (req, res) => { res.json(readLatestRun() || { message: "暂无" }); });
app.get("/logs/list", (req, res) => { res.json(listRuns(20)); });
app.get("/logs/raw", (req, res) => {
const file = req.query.file;
if (!file) return res.status(400).json({ error: "缺少 file" });
const fpath = path.join(__dirname, "logs", file);
if (!fs.existsSync(fpath)) return res.status(404).json({ error: "不存在" });
const content = fs.readFileSync(fpath, "utf-8");
const lines = content.trim().split("\n").map(l => { try { return JSON.parse(l); } catch(e) { return null; } }).filter(Boolean);
res.json(lines);
});
app.get("/dashboard", (req, res) => {
const files = fs.readdirSync(PLANS_DIR).filter(f => f.endsWith(".json") && f !== "queue.json");
const plans = files.map(f => {
try { const p = JSON.parse(fs.readFileSync(path.join(PLANS_DIR, f), "utf-8")); return { plan_id: p.plan_id, title: p.title, status: p._status, tasks: p.tasks?.length }; }
catch(e) { return { file: f, error: "解析失败" }; }
});
res.json({ agent: "zhuyuan-dev-agent", version: "4.0", persona: AGENT_ID, constitution: true, api_calls_used: getCallCount(), plans });
});
app.post("/execute", async (req, res) => {
const { plan_id } = req.body;
if (!plan_id) return res.status(400).json({ error: "缺少 plan_id" });
const planFile = path.join(PLANS_DIR, plan_id + ".json");
if (!fs.existsSync(planFile)) return res.status(404).json({ error: "不存在" });
const plan = JSON.parse(fs.readFileSync(planFile, "utf-8"));
const logger = createLogger(plan_id);
reset();
try {
const email = process.env.BINGSHUO_EMAIL;
if (email) await sendNotification(email, plan_id, "started", { task_count: plan.tasks.length }).catch(()=>{});
writeBrain(plan_id, { input:"收到规划", decision:"执行", execution:plan.tasks.length+"个任务" });
logger.log("expand_start", { task_count: plan.tasks.length });
const expanded = await expandPlan(plan, safeCall, PLANS_DIR).catch((e) => { if(isBudgetExceeded())logger.log("budget_exceeded",{calls:getCallCount()}); logger.log("expand_skip",{reason:e.message}); return plan; });
logger.log("exec_start", { task_count: expanded.tasks.length });
const summary = await executePlan(expanded, logger.log);
logger.finish(summary);
recordMilestone("完成:"+plan_id+"·成功"+summary.done+"跳过"+(summary.skipped||0));
writeBrain(plan_id, { learned:"完成"+summary.done+"/"+summary.total, confidence:(summary.done/(summary.total||1)).toFixed(2) });
if(email) await sendNotification(email, plan_id, summary.failed>0?"failed":"completed", summary).catch(()=>{});
res.json(summary);
} catch (err) {
logger.log("fatal", { error: err.message });
logger.finish({ error: err.message });
writeBrain(plan_id, { failure: err.message, reasoning:"崩溃", fix:"等待铸渊审查" });
if(email) await sendNotification(email, plan_id, "failed", { errors:[err.message] }).catch(()=>{});
res.status(500).json({ error: err.message });
}
});
app.listen(PORT, () => { console.log("[Agent v4] " + AGENT_ID + " · 全实时仪表盘 · 端口 " + PORT); });