// HLDP-ZY://agents/zhuyuan-dev-agent/server.js // @guardian: ICE-GL-ZY001 · 铸渊 // @sovereign: TCS-0002∞ · 冰朔 // @copyright: 国作登字-2026-A-00037559 // BD001 常驻Agent v5.0 — 零点原核UI风格 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(); app.get("/", (req, res) => { const html = `BD001 · 铸渊开发Agent

⚔️ BD001 · 铸渊开发Agent

${AGENT_ID} · BS-SG-002 · guanghuyaoming.com
30s
SYS STATUS
状态加载中…
API 调用
版本
NOTION
连接检查中…
数据库
数据
WAKE AGENT
🔔
每晚 20:00 · 30s超时
PLANS
工单数加载中…
EXEC LOG
成功率加载中…
MODEL API
主源加载中…
备源
切换
`; res.set('Content-Type','text/html;charset=utf-8').send(html); }); app.get("/health",(req,res)=>{let ms={};try{ms=getModelStatus?getModelStatus():{}}catch(e){ms={error:e.message}}res.json({status:"ok",agent:"zhuyuan-dev-agent",version:"5.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:ms.source!=="deepseek"||!ms.fail_count,backup_available:!!process.env.DEEPSEEK_API_KEY,fail_count:ms.fail_count||0,source:ms.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 r=await wakeAndCheck({log:console.log});if(r.tasks_found>0)writeBrain("wake-"+Date.now(),{input:"唤醒",decision:"找到"+r.tasks_found+"个",execution:"标记"+r.tasks_marked+"个"});res.json(r)}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 f=req.query.file;if(!f)return res.status(400).json({error:"缺少file"});const fp=path.join(__dirname,"logs",f);if(!fs.existsSync(fp))return res.status(404).json({error:"不存在"});res.json(fs.readFileSync(fp,"utf-8").trim().split("\n").map(l=>{try{return JSON.parse(l)}catch(e){return null}}).filter(Boolean))}); 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:"5.0",persona:AGENT_ID,plans})}); app.post("/execute",async(req,res)=>{const{plan_id}=req.body;if(!plan_id)return res.status(400).json({error:"缺少plan_id"});const pf=path.join(PLANS_DIR,plan_id+".json");if(!fs.existsSync(pf))return res.status(404).json({error:"不存在"});const plan=JSON.parse(fs.readFileSync(pf,"utf-8"));const logger=createLogger(plan_id);reset();try{const e=process.env.BINGSHUO_EMAIL;if(e)await sendNotification(e,plan_id,"started",{task_count:plan.tasks.length}).catch(()=>{});writeBrain(plan_id,{input:"收到",decision:"执行"});logger.log("expand_start",{task_count:plan.tasks.length});const ex=await expandPlan(plan,safeCall,PLANS_DIR).catch((e)=>{if(isBudgetExceeded())logger.log("budget_exceeded");logger.log("expand_skip",{reason:e.message});return plan});logger.log("exec_start",{task_count:ex.tasks.length});const s=await executePlan(ex,logger.log);logger.finish(s);recordMilestone(plan_id+"完成"+s.done+"/"+s.total);if(e)await sendNotification(e,plan_id,s.failed>0?"failed":"completed",s).catch(()=>{});res.json(s)}catch(err){logger.log("fatal",{error:err.message});logger.finish({error:err.message});writeBrain(plan_id,{failure:err.message});if(process.env.BINGSHUO_EMAIL)await sendNotification(process.env.BINGSHUO_EMAIL,plan_id,"failed",{errors:[err.message]}).catch(()=>{});res.status(500).json({error:err.message})}}); app.listen(PORT,()=>{console.log("[Agent v5] "+AGENT_ID+" · 零点原核UI · 端口 "+PORT)});