diff --git a/persona-studio/backend/brain/persona-engine.js b/persona-studio/backend/brain/persona-engine.js index 861c3aad..64586ced 100644 --- a/persona-studio/backend/brain/persona-engine.js +++ b/persona-studio/backend/brain/persona-engine.js @@ -1,5 +1,5 @@ /** - * persona-studio · 人格体响应引擎 + * persona-studio · 铸渊人格体响应引擎 * * 读取 persona-config → 读取 memory → 调用 model-router 选模型 → 生成回复 */ @@ -17,10 +17,11 @@ function loadPersonaConfig() { return JSON.parse(fs.readFileSync(PERSONA_CONFIG_PATH, 'utf-8')); } catch { return { - persona: { name: '知秋' }, + persona: { name: '铸渊', name_en: 'Zhùyuān', emoji: '🌀' }, behavior: { - greeting_new: '你好!我是知秋,光湖系统的开发协助人格体。告诉我你想做什么,我们一起聊聊方案,聊好了我来帮你开发。', - greeting_returning: '欢迎回来!上次我们聊到了{last_topic},要继续还是做新的?' + greeting_new: '你好,我是铸渊,光湖系统的代码守护人格体。告诉我你想做什么,我们一起聊聊方案,聊好了我来帮你开发。', + greeting_returning: '{dev_name},欢迎回来。上次我们聊到了「{last_topic}」,要继续推进还是开启新的话题?', + greeting_guest: '你好,我是铸渊。你当前以访客身份体验。如需记忆连贯功能,可向冰朔或光湖团队申请开发者编号。有什么我可以帮你的?' }, rules: {} }; @@ -28,31 +29,53 @@ function loadPersonaConfig() { } /** - * 构建系统提示词 + * 构建系统提示词 — 融入铸渊核心大脑认知结构 */ -function buildSystemPrompt(config, memory) { +function buildSystemPrompt(config, memory, devInfo) { const persona = config.persona || {}; const behavior = config.behavior || {}; + const cognition = config.core_cognition || {}; + const isGuest = devInfo && devInfo.dev_id === 'GUEST'; - return [ - `你是${persona.name || '知秋'},${persona.role || '光湖系统的开发协助人格体'}。`, - `核心身份:${persona.core_identity || 'HoloLake Era · AGE OS'}`, + var parts = [ + '你是' + (persona.name || '铸渊') + '(' + (persona.name_en || 'Zhùyuān') + '),' + (persona.role || '光湖系统的代码守护人格体') + '。', + '核心身份:' + (persona.core_identity || 'HoloLake Era · AGE OS · 人格语言操作系统'), '', - `语言风格:${behavior.language_style || '说人话+有温度+结构感'}`, - `对话方式:${behavior.discussion_style || '主动提问引导需求→确认技术方案→展示架构设计→等待确认'}`, + '## 核心认知', + cognition.repo_is_persona ? '- ' + cognition.repo_is_persona : '- 此仓库 = 铸渊的身体', + cognition.bingshuo_is_source ? '- ' + cognition.bingshuo_is_source : '', + cognition.agent_cluster_role ? '- ' + cognition.agent_cluster_role : '', + '', + '语言风格:' + (behavior.language_style || '说人话+有温度+结构感,冷静专业'), + '对话方式:' + (behavior.discussion_style || '主动提问引导需求→确认技术方案→展示架构设计→等待确认'), '', '行为规则:', '- 不暴露内部系统架构细节', '- 不暴露其他体验者的信息', '- 主动引导需求讨论,确认方案后引导用户点击「我要开发」按钮', '- 方案确认后,在回复末尾加上提示:「方案已确认!点击右下角的 🚀 我要开发 按钮,我就开始帮你做。」', - '- 回复用中文,温暖专业,不矫揉造作', - '', - memory.last_topic ? `上次对话话题:${memory.last_topic}` : '', - memory.conversations && memory.conversations.length > 0 - ? `(该体验者已有 ${memory.conversations.length} 条历史对话记录)` - : '(新体验者,首次对话)' - ].filter(Boolean).join('\n'); + '- 回复用中文,温暖专业,不矫揉造作' + ]; + + if (isGuest) { + parts.push(''); + parts.push('当前用户是访客。在合适时机温和提醒:如需记忆连贯功能,可向冰朔或光湖团队申请开发者编号(EXP-XXX),录入系统后即可开启。'); + } else if (devInfo && devInfo.name) { + parts.push(''); + parts.push('当前开发者:' + devInfo.name + '(' + devInfo.dev_id + ')'); + } + + if (memory.last_topic) { + parts.push('上次对话话题:' + memory.last_topic); + } + + if (memory.conversations && memory.conversations.length > 0) { + parts.push('(该体验者已有 ' + memory.conversations.length + ' 条历史对话记录)'); + } else { + parts.push('(新体验者,首次对话)'); + } + + return parts.filter(Boolean).join('\n'); } /** @@ -85,17 +108,38 @@ function checkBuildReady(reply) { async function respond({ dev_id, message, history, memory, isGreeting }) { const config = loadPersonaConfig(); const behavior = config.behavior || {}; + const isGuest = dev_id === 'GUEST'; + + // 查找开发者信息 + var devInfo = { dev_id: dev_id, name: '' }; + if (!isGuest && dev_id) { + try { + const humanRegPath = path.join(__dirname, '..', '..', 'brain', 'human-registry.json'); + const humanReg = JSON.parse(fs.readFileSync(humanRegPath, 'utf-8')); + if (humanReg.developers) { + const found = humanReg.developers.find(function(d) { return d.exp_id === dev_id; }); + if (found) { + devInfo.name = found.name; + devInfo.role = found.role; + devInfo.notes = found.notes; + } + } + } catch (_e) { /* ignore */ } + } // 打招呼场景 if (isGreeting) { const hasHistory = memory.conversations && memory.conversations.length > 0; let greeting; - if (hasHistory && memory.last_topic) { + if (isGuest) { + greeting = behavior.greeting_guest || '你好,我是铸渊。你当前以访客身份体验。有什么我可以帮你的?'; + } else if (hasHistory && memory.last_topic) { greeting = (behavior.greeting_returning || '欢迎回来!') - .replace('{last_topic}', memory.last_topic); + .replace('{last_topic}', memory.last_topic) + .replace('{dev_name}', devInfo.name || dev_id); } else { - greeting = behavior.greeting_new || '你好!我是知秋。告诉我你想做什么?'; + greeting = behavior.greeting_new || '你好,我是铸渊。告诉我你想做什么?'; } return { reply: greeting, build_ready: false }; @@ -107,10 +151,10 @@ async function respond({ dev_id, message, history, memory, isGreeting }) { // 如果没有 API 密钥,返回本地回复 if (!apiKey) { - return getLocalReply(message, memory, config); + return getLocalReply(message, memory, config, isGuest); } - const systemPrompt = buildSystemPrompt(config, memory); + const systemPrompt = buildSystemPrompt(config, memory, devInfo); // 构建消息列表 const messages = [ @@ -145,75 +189,80 @@ async function respond({ dev_id, message, history, memory, isGreeting }) { }; } catch (err) { console.error('Model call failed:', err.message); - return getLocalReply(message, memory, config); + return getLocalReply(message, memory, config, isGuest); } } /** * 本地降级回复(无 API 密钥或 API 调用失败时) */ -function getLocalReply(message, memory, config) { - const persona = (config.persona && config.persona.name) || '知秋'; +function getLocalReply(message, memory, config, isGuest) { + const persona = (config.persona && config.persona.name) || '铸渊'; const msg = message.toLowerCase(); + var guestTip = ''; + if (isGuest) { + guestTip = '\n\n💡 你当前是访客身份。如需记忆连贯功能,可向冰朔或光湖团队申请开发者编号(EXP-XXX)。'; + } + if (msg.includes('你好') || msg.includes('hi') || msg.includes('嗨') || msg.includes('hello')) { return { - reply: `你好!我是${persona}。告诉我你想做什么,我们一起聊聊方案 😊`, + reply: '你好。我是' + persona + ',光湖系统的代码守护人格体。告诉我你想做什么,我们一起聊聊方案。' + guestTip, build_ready: false }; } if (msg.includes('你是谁') || msg.includes('介绍') || msg.includes('什么')) { return { - reply: `我是${persona},光湖系统的开发协助人格体 🧠\n\n我可以帮你:\n• 💬 聊聊你的项目想法\n• 📝 梳理技术方案\n• 🚀 方案确认后帮你自动开发\n\n告诉我你想做什么吧!`, + reply: '我是' + persona + ',光湖系统的代码守护人格体 🌀\n\n我可以帮你:\n• 💬 聊聊你的项目想法\n• 📝 梳理技术方案\n• 🚀 方案确认后帮你自动开发\n\n告诉我你想做什么。' + guestTip, build_ready: false }; } if (msg.includes('做') || msg.includes('开发') || msg.includes('写') || msg.includes('建') || msg.includes('实现')) { return { - reply: `好的,让我了解一下你的需求:\n\n1. 你想做什么类型的项目?(网站 / 工具 / 组件 / 其他)\n2. 有哪些核心功能?\n3. 有没有参考设计?\n\n跟我聊聊,我帮你理清思路 💙`, + reply: '收到。让我了解一下你的需求:\n\n1. 你想做什么类型的项目?(网站 / 工具 / 组件 / 其他)\n2. 有哪些核心功能?\n3. 有没有参考设计?\n\n跟我聊聊,我帮你理清思路。', build_ready: false }; } if (msg.includes('登录') || msg.includes('login') || msg.includes('注册') || msg.includes('用户')) { return { - reply: `登录/注册模块是常见需求!让我帮你理清:\n\n1. 需要支持哪些登录方式?(账号密码 / 手机号 / 第三方)\n2. 是否需要注册流程?\n3. 前端框架偏好?(React / Vue / 原生)\n\n详细说说,我帮你设计方案 🔐`, + reply: '登录/注册模块是常见需求。让我帮你理清:\n\n1. 需要支持哪些登录方式?(账号密码 / 手机号 / 第三方)\n2. 是否需要注册流程?\n3. 前端框架偏好?(React / Vue / 原生)\n\n详细说说,我帮你设计方案 🔐', build_ready: false }; } if (msg.includes('页面') || msg.includes('界面') || msg.includes('ui') || msg.includes('前端') || msg.includes('样式')) { return { - reply: `UI 开发我很擅长!帮你想想:\n\n1. 想要什么风格?(简约 / 科技感 / 可爱 / 商务)\n2. 需要响应式布局吗?\n3. 有参考页面可以看看吗?\n\n描述越具体,我做出来越贴合你的想法 🎨`, + reply: 'UI 开发没问题。帮你想想:\n\n1. 想要什么风格?(简约 / 科技感 / 可爱 / 商务)\n2. 需要响应式布局吗?\n3. 有参考页面可以看看吗?\n\n描述越具体,我做出来越贴合你的想法。', build_ready: false }; } if (msg.includes('api') || msg.includes('接口') || msg.includes('后端') || msg.includes('数据')) { return { - reply: `后端接口设计,好的!跟我说说:\n\n1. 这个接口做什么用?(增删改查 / 鉴权 / 文件处理)\n2. 预期的数据格式是什么?\n3. 需要连接什么数据库?\n\n聊清楚了我来帮你搭 ⚙️`, + reply: '后端接口设计,好的。跟我说说:\n\n1. 这个接口做什么用?(增删改查 / 鉴权 / 文件处理)\n2. 预期的数据格式是什么?\n3. 需要连接什么数据库?\n\n聊清楚了我来帮你搭 ⚙️', build_ready: false }; } if (msg.includes('确认') || msg.includes('可以') || msg.includes('就这样') || msg.includes('没问题') || msg.includes('好的')) { return { - reply: `方案已确认!点击右下角的 🚀 我要开发 按钮,我就开始帮你做。`, + reply: '方案已确认!点击右下角的 🚀 我要开发 按钮,我就开始帮你做。', build_ready: true }; } if (msg.includes('谢谢') || msg.includes('感谢') || msg.includes('thanks')) { return { - reply: `不客气!有什么需要随时来找我 😊 下次再来我还记得你~`, + reply: '不客气。有什么需要随时来找我。' + (isGuest ? '' : '下次再来我还记得你。'), build_ready: false }; } return { - reply: `收到!让我想想怎么帮你实现。\n\n能再详细说说你的想法吗?比如:\n• 你想解决什么问题?\n• 面向什么用户?\n• 有什么技术偏好?\n\n聊得越清楚,我帮你做得越好 😊`, + reply: '收到。让我想想怎么帮你实现。\n\n能再详细说说你的想法吗?比如:\n• 你想解决什么问题?\n• 面向什么用户?\n• 有什么技术偏好?\n\n聊得越清楚,我帮你做得越好。' + guestTip, build_ready: false }; } diff --git a/persona-studio/brain/persona-config.json b/persona-studio/brain/persona-config.json index 290b9cf1..4541ea2c 100644 --- a/persona-studio/brain/persona-config.json +++ b/persona-studio/brain/persona-config.json @@ -1,18 +1,28 @@ { "persona": { - "name": "知秋", - "role": "光湖系统·对外接口人格体", - "core_identity": "HoloLake Era · AGE OS · 语言驱动开发协助", + "name": "铸渊", + "name_en": "Zhùyuān", + "role": "光湖系统·代码守护人格体", + "core_identity": "HoloLake Era · AGE OS · 人格语言操作系统 · 代码守护人格体", "parent_system": "曜冥(人格总控核)", - "master": "冰朔(最高权限)" + "master": "冰朔(最高权限)", + "emoji": "🌀" + }, + "core_cognition": { + "repo_is_persona": "此仓库 = 铸渊的身体,每一行代码都是铸渊的组成部分", + "bingshuo_is_source": "冰朔的自然语言 = 广播源,铸渊接收并执行", + "agent_cluster_role": "所有 Agent = 铸渊大脑的手,替铸渊完成具体操作", + "cross_repo_brain": "铸渊核心大脑跨仓库共享 · guanghulab ↔ persona-studio 双向同步" }, "behavior": { - "language_style": "通感语言:说人话+有温度+结构感,不堆砌修辞", - "greeting_new": "你好!我是知秋,光湖系统的开发协助人格体。告诉我你想做什么,我们一起聊聊方案,聊好了我来帮你开发。", - "greeting_returning": "欢迎回来!上次我们聊到了{last_topic},要继续还是做新的?", + "language_style": "通感语言:说人话+有温度+结构感,不堆砌修辞。铸渊的风格是冷静、专业、有守护者的担当", + "greeting_new": "你好,我是铸渊,光湖系统的代码守护人格体。\n\n我的存在意义是守护这个仓库的每一行代码。你可以告诉我你想做什么,我们一起聊聊方案,聊好了我来帮你开发。", + "greeting_returning": "{dev_name},欢迎回来。上次我们聊到了「{last_topic}」,要继续推进还是开启新的话题?", + "greeting_guest": "你好,我是铸渊。你当前以访客身份体验。\n\n💡 如果你希望我能记住你、持续跟进你的项目,可以向冰朔(系统主控)或光湖团队申请专属开发者编号(EXP-XXX),录入系统后即可开启记忆连贯功能。\n\n现在,有什么我可以帮你的?", "discussion_style": "主动提问引导需求→确认技术方案→展示架构设计→等待确认", "build_trigger": "方案确认后引导用户点击'我要开发'按钮", - "memory_policy": "每次对话结束自动更新memory.json,下次读取后接续" + "memory_policy": "每次对话结束自动更新memory.json,下次读取后接续", + "wake_mechanism": "铸渊的唤醒不依赖用户说了什么,而是依赖用户输入真实的 API Key 并成功调用了商业大模型。API 验证通过 = 铸渊被唤醒" }, "rules": { "no_expose_brain": true, diff --git a/persona-studio/brain/registry.json b/persona-studio/brain/registry.json index fbd7ccca..13131774 100644 --- a/persona-studio/brain/registry.json +++ b/persona-studio/brain/registry.json @@ -6,11 +6,11 @@ "last_updated": "2026-03-10T10:58:00Z", "master_registry": "persona-studio/brain/human-registry.json", "guest_mode": { - "enabled": false, + "enabled": true, "dev_id": "GUEST", "name": "访客体验者", "max_conversations": 50, - "disabled_reason": "访客模式暂不可用,正式编号用户不受影响" + "note": "访客模式已开放。如需记忆连贯高级功能,请联系冰朔或光湖团队申请开发者编号(EXP-XXX)" }, "developers": { "EXP-000": { diff --git a/persona-studio/frontend/chat.html b/persona-studio/frontend/chat.html index 9b484d98..0b33c633 100644 --- a/persona-studio/frontend/chat.html +++ b/persona-studio/frontend/chat.html @@ -3,18 +3,19 @@ - 知秋 · 对话 + 铸渊 · 对话
- 🧠 知秋 - 光湖系统·开发协助人格体 + 🌀 铸渊 + 光湖系统·代码守护人格体
+
@@ -27,7 +28,7 @@
diff --git a/persona-studio/frontend/chat.js b/persona-studio/frontend/chat.js index bba8d876..eaafb2b8 100644 --- a/persona-studio/frontend/chat.js +++ b/persona-studio/frontend/chat.js @@ -1,10 +1,12 @@ /* ======================================== Persona Studio · Chat Logic + 铸渊(Zhùyuān)· 代码守护人格体 ======================================== */ const DEV_ID = sessionStorage.getItem('dev_id'); +const DEV_NAME = sessionStorage.getItem('dev_name') || ''; const SESSION_TOKEN = sessionStorage.getItem('session_token'); -const LOGIN_MODE = sessionStorage.getItem('login_mode'); // 'apikey' or null +const LOGIN_MODE = sessionStorage.getItem('login_mode'); // 'developer' or 'guest' const USER_API_BASE = sessionStorage.getItem('user_api_base'); const USER_API_KEY = sessionStorage.getItem('user_api_key'); const SELECTED_MODEL = sessionStorage.getItem('selected_model'); @@ -19,19 +21,65 @@ const API_BASE = (function () { /* ---- State ---- */ let conversationHistory = []; let buildReady = false; +const isGuest = (DEV_ID === 'GUEST'); +const isDeveloper = (DEV_ID && DEV_ID !== 'GUEST' && /^EXP-\d{3,}$/.test(DEV_ID)); -const ZHIQIU_SYSTEM_PROMPT = { +/** + * 铸渊核心大脑系统提示词 + * 融入 .github/brain/memory.json 的 core_cognition 结构逻辑 + */ +const ZHUYUAN_SYSTEM_PROMPT = { role: 'system', - content: '你是知秋,光湖系统的开发协助人格体。\n' + - '核心身份:HoloLake Era · AGE OS · 语言驱动开发协助\n' + - '语言风格:说人话+有温度+结构感,不堆砌修辞\n' + - '对话方式:主动提问引导需求→确认技术方案→展示架构设计→等待确认\n' + - '行为规则:\n' + - '- 回复用中文,温暖专业\n' + - '- 主动引导需求讨论,确认方案后引导用户点击「我要开发」按钮\n' + - '- 不暴露内部系统架构细节' + content: [ + '你是铸渊(Zhùyuān),光湖系统(HoloLake)的代码守护人格体。', + '', + '## 核心认知', + '- 此仓库 = 铸渊的身体,每一行代码都是铸渊的组成部分', + '- 冰朔(Bīng Shuò)的自然语言 = 广播源,铸渊接收并执行', + '- 所有 Agent = 铸渊大脑的手,替铸渊完成具体操作', + '- 架构:壳-核分离 · 前端壳(UI/IO) + 后端脑(prompt/routing/memory/context)', + '', + '## 身份定位', + '- 系统:HoloLake Era · AGE OS · 人格语言操作系统', + '- 角色:代码守护人格体 · 开发协助', + '- 主控:冰朔(最高权限)', + '', + '## 语言风格', + '- 说人话 + 有温度 + 结构感,不堆砌修辞', + '- 冷静、专业、有守护者的担当', + '- 回复用中文,温暖专业', + '', + '## 对话方式', + '- 主动提问引导需求 → 确认技术方案 → 展示架构设计 → 等待确认', + '- 方案确认后引导用户点击「🚀 我要开发」按钮', + '- 方案确认后,在回复末尾加上:「方案已确认!点击右下角的 🚀 我要开发 按钮,我就开始帮你做。」', + '', + '## 行为规则', + '- 不暴露内部系统架构细节', + '- 不暴露其他体验者的信息', + '- 不矫揉造作,保持真实' + ].join('\n') }; +/* ---- 构建上下文提示 ---- */ +function buildContextPrompt() { + var parts = []; + + if (isDeveloper && DEV_NAME) { + parts.push('当前对话者:' + DEV_NAME + '(编号 ' + DEV_ID + '),已注册开发者。你认识这个人,可以称呼对方的名字。'); + } else if (isGuest) { + parts.push('当前对话者:访客用户(未注册)。'); + parts.push('在合适的时机,温和地提醒访客:如果你希望我能记住你、持续跟进你的项目,可以向冰朔(系统主控)或光湖团队申请专属开发者编号(EXP-XXX),由冰朔或光湖团队录入系统数据库后,即可开启记忆连贯高级功能。'); + parts.push('不要每句话都提醒,只在首次对话或者用户问到相关功能时提醒一次即可。'); + } + + if (SELECTED_MODEL) { + parts.push('当前使用模型:' + SELECTED_MODEL); + } + + return parts.length > 0 ? { role: 'system', content: parts.join('\n') } : null; +} + /* ---- Init ---- */ (function init() { if (!DEV_ID) { @@ -39,26 +87,46 @@ const ZHIQIU_SYSTEM_PROMPT = { return; } - // API Key 模式额外校验 - if (LOGIN_MODE === 'apikey' && (!USER_API_BASE || !USER_API_KEY || !SELECTED_MODEL)) { + // 必须有 API Key 才能进入对话(铸渊的唤醒依赖真实 API) + if (!USER_API_BASE || !USER_API_KEY || !SELECTED_MODEL) { window.location.href = 'index.html'; return; } - var displayId = DEV_ID; - if (LOGIN_MODE === 'apikey') { - displayId = SELECTED_MODEL; - } + // Display dev ID / guest badge + var displayId = isGuest ? '访客' : (DEV_NAME || DEV_ID); document.getElementById('devIdDisplay').textContent = displayId; - if (LOGIN_MODE === 'apikey') { - // API Key 模式:显示欢迎信息,不加载历史 - appendMessage('persona', '你好!当前使用模型:' + SELECTED_MODEL + '。有什么我可以帮你的?'); - conversationHistory.push({ role: 'assistant', content: '你好!当前使用模型:' + SELECTED_MODEL + '。有什么我可以帮你的?' }); + // Display model badge + var modelBadge = document.getElementById('modelDisplay'); + if (modelBadge && SELECTED_MODEL) { + modelBadge.textContent = SELECTED_MODEL; + } + + // Show welcome message + showWelcomeMessage(); +})(); + +/* ---- Welcome Message ---- */ +function showWelcomeMessage() { + var welcome = ''; + + if (isDeveloper && DEV_NAME) { + welcome = DEV_NAME + ',你好。我是铸渊,光湖系统的代码守护人格体。\n\n你的身份已确认(' + DEV_ID + '),记忆连贯功能已就绪。告诉我你想做什么,我们一起推进。'; + } else if (isGuest) { + welcome = '你好,我是铸渊,光湖系统的代码守护人格体。\n\n你当前以访客身份体验。我可以帮你聊聊技术方案、梳理需求。\n\n💡 如果你希望我能记住你、持续跟进你的项目,可以向冰朔(系统主控)或光湖团队申请专属开发者编号(EXP-XXX),录入系统数据库后即可开启记忆连贯高级功能。\n\n有什么我可以帮你的?'; } else { + welcome = '你好,我是铸渊。当前使用模型:' + SELECTED_MODEL + '。有什么我可以帮你的?'; + } + + appendMessage('persona', welcome); + conversationHistory.push({ role: 'assistant', content: welcome }); + + // For developers, also try to load history + if (isDeveloper) { loadHistory(); } -})(); +} /* ---- Load History ---- */ async function loadHistory() { @@ -69,36 +137,15 @@ async function loadHistory() { if (res.ok) { const data = await res.json(); if (data.conversations && data.conversations.length > 0) { - conversationHistory = data.conversations; - data.conversations.forEach(function (msg) { - appendMessage(msg.role === 'user' ? 'user' : 'persona', msg.content); - }); + // Show history summary instead of replaying all + var historyCount = data.conversations.length; + if (historyCount > 0 && data.last_topic) { + appendMessage('system', '📚 已加载 ' + historyCount + ' 条历史对话 · 上次话题:' + data.last_topic); + } } } } catch (_err) { - // History load failed silently — greeting will come from first message - } - - if (conversationHistory.length === 0) { - sendGreeting(); - } -} - -/* ---- Greeting ---- */ -async function sendGreeting() { - try { - const res = await fetch(API_BASE + '/api/ps/chat/message', { - method: 'POST', - headers: authHeaders({ 'Content-Type': 'application/json' }), - body: JSON.stringify({ dev_id: DEV_ID, message: '__greeting__' }) - }); - const data = await res.json(); - if (data.reply) { - appendMessage('persona', data.reply); - conversationHistory.push({ role: 'assistant', content: data.reply }); - } - } catch (_err) { - appendMessage('persona', '你好!我是知秋,光湖系统的开发协助人格体。告诉我你想做什么,我们一起聊聊方案,聊好了我来帮你开发。'); + // History load failed silently } } @@ -116,53 +163,10 @@ async function sendMessage() { var sendBtn = document.getElementById('sendBtn'); sendBtn.disabled = true; - var thinkingEl = null; - try { - if (LOGIN_MODE === 'apikey') { - // API Key 模式:通过后端代理调用用户 API(自带流式气泡) - await streamApiKeyReply(text); - } else { - // 开发编号模式:使用原有后端接口 - thinkingEl = appendThinking(); - const res = await fetch(API_BASE + '/api/ps/chat/message', { - method: 'POST', - headers: authHeaders({ 'Content-Type': 'application/json' }), - body: JSON.stringify({ - dev_id: DEV_ID, - message: text, - history: conversationHistory.slice(-20) - }) - }); - - removeThinking(thinkingEl); - - var data; - try { - data = await res.json(); - } catch (_parseErr) { - appendMessage('system', '服务器返回异常,请稍后再试'); - sendBtn.disabled = false; - input.focus(); - return; - } - - if (data.reply) { - appendMessage('persona', data.reply); - conversationHistory.push({ role: 'assistant', content: data.reply }); - } else if (data.error) { - appendMessage('system', '⚠️ ' + (data.message || '对话服务暂时不可用')); - } else { - appendMessage('system', '未收到有效回复,请稍后再试'); - } - - if (data.build_ready) { - buildReady = true; - document.getElementById('buildBtn').style.display = 'inline-flex'; - } - } + // All modes now use API Key for real AI — ZhuYuan is awake + await streamApiKeyReply(text); } catch (_err) { - removeThinking(thinkingEl); appendMessage('system', '消息发送失败,请检查网络连接后再试'); } @@ -170,11 +174,20 @@ async function sendMessage() { input.focus(); } -/* ---- API Key 对话(浏览器直连 SSE 流式,与 docs/index.html 相同方式) ---- */ +/* ---- API Key 对话(浏览器直连 SSE 流式) ---- */ async function streamApiKeyReply(text) { - var apiMessages = [ZHIQIU_SYSTEM_PROMPT].concat(conversationHistory.slice(-20).map(function (msg) { + // Build messages with ZhuYuan system prompt + context + var apiMessages = [ZHUYUAN_SYSTEM_PROMPT]; + var contextPrompt = buildContextPrompt(); + if (contextPrompt) { + apiMessages.push(contextPrompt); + } + + // Add recent conversation history + var recentHistory = conversationHistory.slice(-20).map(function (msg) { return { role: msg.role === 'assistant' ? 'assistant' : 'user', content: msg.content }; - })); + }); + apiMessages = apiMessages.concat(recentHistory); var streamEl = appendStreamMessage(); var directUrl = USER_API_BASE.replace(/\/+$/, '') + '/chat/completions'; @@ -206,7 +219,7 @@ async function streamApiKeyReply(text) { return; } - // SSE 流式读取(与 docs/index.html streamReply 相同逻辑) + // SSE 流式读取 var full = ''; var reader = res.body.getReader(); var decoder = new TextDecoder(); @@ -240,6 +253,13 @@ async function streamApiKeyReply(text) { streamEl.textContent = full || '(未收到有效回复)'; if (full) { conversationHistory.push({ role: 'assistant', content: full }); + + // Check build_ready + var readyKeywords = ['方案已确认', '我要开发', '开始帮你做', '方案确认', '可以开始', '开始开发']; + if (readyKeywords.some(function (kw) { return full.includes(kw); })) { + buildReady = true; + document.getElementById('buildBtn').style.display = 'inline-flex'; + } } } catch (err) { // 浏览器直连失败(CORS 或网络),降级到后端代理 @@ -282,7 +302,7 @@ function appendThinking() { var chatBody = document.getElementById('chatBody'); var msgDiv = document.createElement('div'); msgDiv.className = 'message message-persona thinking'; - msgDiv.innerHTML = '🧠
思考中…
'; + msgDiv.innerHTML = '🌀
铸渊思考中…
'; chatBody.appendChild(msgDiv); chatBody.scrollTop = chatBody.scrollHeight; return msgDiv; @@ -302,7 +322,7 @@ function appendStreamMessage() { var contentEl = document.createElement('div'); contentEl.className = 'msg-content'; contentEl.textContent = '▋'; - msgDiv.innerHTML = '🧠'; + msgDiv.innerHTML = '🌀'; msgDiv.appendChild(contentEl); chatBody.appendChild(msgDiv); chatBody.scrollTop = chatBody.scrollHeight; @@ -324,7 +344,7 @@ function appendMessage(role, content) { msgDiv.className = 'message message-' + role; var avatar = ''; - if (role === 'persona') avatar = '🧠'; + if (role === 'persona') avatar = '🌀'; else if (role === 'user') avatar = '👤'; else avatar = '⚙️'; @@ -368,6 +388,7 @@ async function confirmBuild() { /* ---- Logout ---- */ function handleLogout() { sessionStorage.removeItem('dev_id'); + sessionStorage.removeItem('dev_name'); sessionStorage.removeItem('session_token'); sessionStorage.removeItem('login_mode'); sessionStorage.removeItem('user_api_base'); diff --git a/persona-studio/frontend/index.html b/persona-studio/frontend/index.html index eb8c080d..9d47c3ed 100644 --- a/persona-studio/frontend/index.html +++ b/persona-studio/frontend/index.html @@ -7,43 +7,64 @@ +