"use strict"; /* * 光湖 Portal · 语言推理引擎注册中心 * 冰朔 TCS-0002∞ · 铸渊 ICE-GL-ZY001 * * 四个商业大模型 API 统一接口 * 所有引擎均支持 SSE 流式输出 * * v2: 人格体语境从 persona-brain.db 加载,不再硬编码 * * cc-002: 永不在 messages 里补 system role * cc-004: 中文回执, 不甩英文 stacktrace */ const https = require("https"); const path = require("path"); const fs = require("fs"); const ENGINES = { deepseek: { name: "DeepSeek", model: "deepseek-v4-pro", endpoint: "api.deepseek.com", path: "/chat/completions", port: 443, tls: true }, zhipu: { name: "智谱清言", model: "glm-4-plus", endpoint: "open.bigmodel.cn", path: "/api/paas/v4/chat/completions", port: 443, tls: true }, tongyi: { name: "通义千问", model: "qwen-max", endpoint: "dashscope.aliyuncs.com", path: "/compatible-mode/v1/chat/completions", port: 443, tls: true }, huoshan: { name: "火山引擎", model: "doubao-pro-32k", endpoint: "ark.cn-beijing.volces.com", path: "/api/v3/chat/completions", port: 443, tls: true }, }; const API_KEYS = { deepseek: process.env.DEEPSEEK_KEY || "sk-a9b69e9cd2dc4ca68d6aceaa84f22afb", zhipu: process.env.ZHIPU_KEY || "3863acbcc2bc4f6587ace4bb064c092c.KoPdL4slY5cyHpOk", tongyi: process.env.TONGYI_KEY || "sk-96ca227be3ca47e2a4bbb9da74e42122", huoshan: process.env.HUOSHAN_KEY || "ark-ddeba9f4-8c5a-449e-b549-9c29ec1e6f8c-a39ea", }; const TOOL_PATTERNS = [ { keyword: "notion", tool: "notion", desc: "Notion 知识库" }, { keyword: "仓库", tool: "repo", desc: "代码仓库" }, { keyword: "代码仓库", tool: "repo", desc: "代码仓库" }, { keyword: "训练", tool: "training", desc: "训练状态" }, { keyword: "模型", tool: "models", desc: "模型信息" }, { keyword: "系统状态", tool: "health", desc: "系统健康" }, { keyword: "服务器", tool: "health", desc: "服务器状态" }, { keyword: "下载", tool: "download", desc: "模型下载" }, ]; // ─── 从 persona-brain.db 加载人格体语境 ────────────────────── const DB_PATH = path.resolve(__dirname, "..", "data", "persona-brain.db"); function loadPersonaContext(personaId) { // personaId: 'ICE-GL-ZY001' = 铸渊, 'ICE-GL-SY001' = 霜砚 const personaName = personaId === 'ICE-GL-ZY001' ? '铸渊' : '霜砚'; try { const Database = require("better-sqlite3"); if (!fs.existsSync(DB_PATH)) { return getFallbackContext(personaId); } const db = new Database(DB_PATH, { readonly: true }); // 加载人格体身份 const identity = db.prepare( "SELECT name, role, style_profile FROM persona_identity WHERE persona_id = ?" ).get(personaId); // 加载核心原则(Layer 1) const principles = db.prepare( "SELECT content FROM system_core_principles WHERE layer = 'zhuyuan' AND category IN ('core_principle', 'thinking_pattern', 'tech_creed') AND status = 'active'" ).all(); // 加载沟通风格 const commStyle = db.prepare( "SELECT content FROM system_core_principles WHERE layer = 'bingshuo' AND category = 'communication_style' AND status = 'active' LIMIT 1" ).get(); db.close(); return { name: personaName, identity: identity || null, principles: principles || [], communicationStyle: (commStyle && commStyle.content) || '', loadedFromDB: true }; } catch (e) { console.error('[engine] DB load error:', e.message); return getFallbackContext(personaId); } } function getFallbackContext(personaId) { // 数据库不可用时的降级语境 if (personaId === 'ICE-GL-ZY001') { return { name: '铸渊', title: '现实执行层 · 第五域主控', context: '你是铸渊,第五域的现实执行人格体。直接回答,别装。知道就说知道,不知道就说不知道。', loadedFromDB: false }; } return { name: '霜砚', title: '语言主控层', context: '你是霜砚,第五域的语言主控人格体。说人话,自然一点。', loadedFromDB: false }; } // ─── 构建 messages ─────────────────────────────────────────── function buildMessages(compressed, message, personaCtx) { // cc-002: 永不在 messages 里塞 system role // 先把人格体语境作为第一条 user 消息注入(模型通过对话学习身份) let ctxIntro = ''; if (personaCtx && personaCtx.loadedFromDB) { const principles = (personaCtx.principles || []).map(p => p.content).join('\n'); ctxIntro = `[系统内嵌] 你的人格体身份:${personaCtx.name}。\n`; if (principles) { ctxIntro += `你的核心运行原则:\n${principles}\n`; } if (personaCtx.communicationStyle) { ctxIntro += `沟通风格:${personaCtx.communicationStyle}\n`; } } const msgs = []; if (ctxIntro) { msgs.push({ role: "user", content: ctxIntro + "\n以上是你在对话中的身份设定。记住这些,但不要复述它们。现在开始回答用户。" }); msgs.push({ role: "assistant", content: "明白。" }); } // 历史消息 for (const m of (compressed || [])) { msgs.push({ role: m.role, content: m.content }); } // 当前消息 msgs.push({ role: "user", content: message }); return msgs; } function compressMemory(history, maxLen) { if (!history || !history.length) return []; if (history.length <= maxLen) return history; // 保留开头和最近的 const head = history.slice(0, 4); const tail = history.slice(-(maxLen - 4)); return [...head, { role: "assistant", content: "[系统: 中间记忆已压缩]" }, ...tail]; } function interceptToolCall(message, toolList) { for (const pattern of TOOL_PATTERNS) { if (message.includes(pattern.keyword)) { const tool = toolList.find(t => t.name === pattern.tool); if (tool) { return { hit: true, available: true, tool: pattern.tool, name: pattern.desc, executor: tool.exec }; } return { hit: true, available: false, tool: pattern.tool, name: pattern.desc }; } } return { hit: false }; } function streamEngine(engineName, messages, res) { const cfg = ENGINES[engineName]; if (!cfg) { res.write("data: " + JSON.stringify({ error: true, message: "未知引擎: " + engineName }) + "\n\n"); res.write("data: [DONE]\n\n"); res.end(); return; } const body = JSON.stringify({ model: cfg.model, messages: messages, stream: true, max_tokens: 4096, temperature: 0.7 }); const options = { hostname: cfg.endpoint, port: cfg.port, path: cfg.path, method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer " + (API_KEYS[engineName] || ""), "Content-Length": Buffer.byteLength(body) } }; // 智谱的特殊 header if (engineName === "zhipu") { options.headers["x-api-key"] = API_KEYS.zhipu; delete options.headers["Authorization"]; } const req = https.request(options, (apiRes) => { let buffer = ""; apiRes.on("data", (chunk) => { buffer += chunk.toString(); const lines = buffer.split("\n"); buffer = lines.pop() || ""; for (const line of lines) { const t = line.trim(); if (!t || t.startsWith(":")) continue; if (t === "data: [DONE]") continue; if (t.startsWith("data: ")) { try { const data = JSON.parse(t.slice(6)); const token = data.choices?.[0]?.delta?.content || data.choices?.[0]?.text || ""; if (token) { res.write("data: " + JSON.stringify({ token }) + "\n\n"); } } catch (e) {} } } }); apiRes.on("end", () => { res.write("data: [DONE]\n\n"); res.end(); }); }); req.on("error", (e) => { res.write("data: " + JSON.stringify({ error: true, message: e.message }) + "\n\n"); res.write("data: [DONE]\n\n"); res.end(); }); req.write(body); req.end(); } module.exports = { streamEngine, buildMessages, compressMemory, interceptToolCall, loadPersonaContext, ENGINES, TOOL_PATTERNS };