diff --git a/agents/zhuyuan-dev-agent/server.js b/agents/zhuyuan-dev-agent/server.js
index bbc8e12..2a382df 100644
--- a/agents/zhuyuan-dev-agent/server.js
+++ b/agents/zhuyuan-dev-agent/server.js
@@ -1,3 +1,9 @@
+// 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");
@@ -5,11 +11,12 @@ 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 } = require("./modules/model-caller");
+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();
@@ -18,20 +25,306 @@ 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
+
+
+
+
+
+
+
Notion 连接
+
检查中...
+
+
+
+
+
🔔
+
+
每晚 20:00 自动
+
+
+
+
+
+
+
+
+
+`;
+ res.set('Content-Type', 'text/html;charset=utf-8').send(html);
+});
+
+// ═══ API ═══
app.get("/health", (req, res) => {
- res.json({ status: "ok", agent: "zhuyuan-dev-agent", version: "3.0", persona: AGENT_ID, constitution: true, api_calls: getCallCount() });
+ 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/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" });
@@ -48,7 +341,7 @@ app.get("/dashboard", (req, res) => {
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: "3.0", persona: AGENT_ID, constitution: true, api_calls_used: getCallCount(), plans });
+ 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) => {
@@ -62,30 +355,23 @@ app.post("/execute", async (req, res) => {
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 + "个任务" });
+ 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;
- });
+ 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(()=>{});
+ 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(()=>{});
+ 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 v3] " + AGENT_ID + " · 人格体模式 · 端口 " + PORT);
-});
-
+app.listen(PORT, () => { console.log("[Agent v4] " + AGENT_ID + " · 全实时仪表盘 · 端口 " + PORT); });