From 4a85cd977af5bafc18329401aa23e9548ed5e9fc Mon Sep 17 00:00:00 2001 From: bingshuo Date: Sat, 30 May 2026 22:04:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BB=AA=E8=A1=A8=E7=9B=98=20v4.0=20API?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E4=BF=AE=E5=A4=8D=20=E2=80=94=20=E5=85=A8?= =?UTF-8?q?=E9=83=A8fetch=E5=8A=A0/dev-agent/=E5=89=8D=E7=BC=80=20=C2=B10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agents/zhuyuan-dev-agent/server.js | 338 ++++++++++++++++++++++++++--- 1 file changed, 312 insertions(+), 26 deletions(-) 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 + +
+
+

⚔️ BD001 · 铸渊开发Agent

+
${AGENT_ID} · BS-SG-002 · guanghuyaoming.com
+
+
+ 30s自动刷新 + +
+
+ +
+
+

系统状态

+
加载中...
+
+
+
+
+

Notion 连接

+
检查中...
+
+
+
+
+
🔔
+ +
每晚 20:00 自动
+
+
+
+

开发工单

+
加载中...
+
+
+
+
+

执行记录

+
加载中...
+
+
+
+
+

模型 API

+
加载中...
+
+
+
+
+ +
+ +`; + 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); });