diff --git a/.github/ISSUE_TEMPLATE/syslog-submit.yml b/.github/ISSUE_TEMPLATE/syslog-submit.yml
new file mode 100644
index 00000000..80a87d27
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/syslog-submit.yml
@@ -0,0 +1,54 @@
+name: "📡 提交系统日志 / 提问"
+description: "做完了?提交你的 SYSLOG。有问题?在这里提问。"
+title: "BC-XXX-XXX|SYSLOG"
+labels: ["syslog", "pending"]
+assignees: []
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## 📡 SYSLOG 自助提交 / 广播提问
+
+ > 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。
+ >
+ > 有问题?把问题粘贴进去,填上邮箱,点提交。解答会发到你邮箱里。
+
+ **标题格式**:`BC-XXX-XXX|SYSLOG` 或 `BC-XXX-XXX|提问`
+
+ - type: input
+ id: broadcast_id
+ attributes:
+ label: "广播编号"
+ description: "写上你当前广播的编号,例如 BC-M22-009-AW"
+ placeholder: "BC-M22-009-AW"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: submit_type
+ attributes:
+ label: "类型"
+ description: "选择提交类型"
+ options:
+ - SYSLOG
+ - 提问
+ validations:
+ required: true
+
+ - type: input
+ id: email
+ attributes:
+ label: "你的邮箱"
+ description: "用于接收新广播或问题解答"
+ placeholder: "your@email.com"
+ validations:
+ required: true
+
+ - type: textarea
+ id: content
+ attributes:
+ label: "内容"
+ description: "粘贴你的 SYSLOG 全文 或 问题描述"
+ placeholder: "在这里粘贴你的 SYSLOG 或问题..."
+ validations:
+ required: true
diff --git a/.github/brain/bingshuo-issues-index.json b/.github/brain/bingshuo-issues-index.json
index 8e8121de..6d37d9af 100644
--- a/.github/brain/bingshuo-issues-index.json
+++ b/.github/brain/bingshuo-issues-index.json
@@ -1,7 +1,7 @@
{
"version": "1.0",
"description": "冰朔主控问题索引库 — 记录已知问题、根因与排查路由",
- "updated_at": "2026-03-13T04:49:20.482Z",
+ "updated_at": "2026-03-13T06:03:28.751Z",
"issues": [
{
"id": "BS-001",
diff --git a/.github/brain/bingshuo-master-brain.md b/.github/brain/bingshuo-master-brain.md
index 364f1351..80f1b9bc 100644
--- a/.github/brain/bingshuo-master-brain.md
+++ b/.github/brain/bingshuo-master-brain.md
@@ -1,7 +1,7 @@
# 冰朔主控神经系统 · 核心主控大脑 v1.0
> 本文件为冰朔主控神经系统的总控脑文件。
-> 最后编译时间:2026-03-13T04:49:20.482Z
+> 最后编译时间:2026-03-13T06:03:28.752Z
---
@@ -56,7 +56,7 @@
### 仓库统计
- 功能模块:10 个
-- Workflow:36 个
+- Workflow:37 个
---
@@ -85,7 +85,7 @@
> 本区块由 master-brain-compiler 自动编译。
-- **编译时间**:2026-03-13T04:49:20.482Z
+- **编译时间**:2026-03-13T06:03:28.752Z
- **脑文件规则版本**:v3.0
- **脑文件完整性**:✅ 完整
@@ -107,7 +107,7 @@
|--------|------|------|
| 🟡 brain_consistency | yellow | 主仓库脑文件完整,但与 persona-studio 脑文件的同步状态待验证 |
| 🟢 deployment_health | green | deploy-to-server.yml 与 deploy-pages.yml 均存在 |
-| 🟢 workflow_health | green | 36 个 workflow 已注册 |
+| 🟢 workflow_health | green | 37 个 workflow 已注册 |
| 🟡 routing_health | yellow | HLI 接口覆盖率 33.3%(7/21) |
| 🟢 docs_entry_health | green | docs/index.html 存在 |
| 🟡 persona_studio_health | yellow | 前后端结构存在,端到端对话链路待验证 |
diff --git a/.github/brain/bingshuo-system-health.json b/.github/brain/bingshuo-system-health.json
index 1ba8b36f..cb8e4669 100644
--- a/.github/brain/bingshuo-system-health.json
+++ b/.github/brain/bingshuo-system-health.json
@@ -1,7 +1,7 @@
{
"version": "1.0",
"description": "冰朔主控系统健康状态",
- "updated_at": "2026-03-13T04:49:20.482Z",
+ "updated_at": "2026-03-13T06:03:28.751Z",
"health": {
"brain_consistency": {
"status": "yellow",
@@ -13,7 +13,7 @@
},
"workflow_health": {
"status": "green",
- "detail": "36 个 workflow 已注册"
+ "detail": "37 个 workflow 已注册"
},
"routing_health": {
"status": "yellow",
diff --git a/.github/brain/memory.json b/.github/brain/memory.json
index d6645cda..cdc4885d 100644
--- a/.github/brain/memory.json
+++ b/.github/brain/memory.json
@@ -67,6 +67,12 @@
}
},
"events": [
+ {
+ "date": "2026-03-13",
+ "type": "brain_restore",
+ "description": "铸渊核心大脑恢复 · Persona Studio 铸渊代理开发工作流上线 · 修复「我要开发」功能无法触发代理开发 · Agent 5步自动化工作流(需求分析→架构规划→代码生成→预览部署→完成通知) · 使用用户API Key驱动 · 支持GUEST模式 · WebSocket时序修复 · 错误反馈增强",
+ "by": "铸渊(冰朔指令)"
+ },
{
"date": "2026-03-13",
"type": "psp_inspection",
diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json
index 119427b3..8ec2133c 100644
--- a/.github/brain/repo-map.json
+++ b/.github/brain/repo-map.json
@@ -1,13 +1,13 @@
{
"description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)",
"version": "2.0",
- "generated_at": "2026-03-13T04:49:33.903Z",
+ "generated_at": "2026-03-13T06:03:44.081Z",
"generated_by": "scripts/generate-repo-map.js",
"repo": "qinfendebingshuo/guanghulab",
"stats": {
"zones": 13,
"total_modules": 10,
- "total_workflows": 36,
+ "total_workflows": 37,
"total_scripts": 33,
"total_dev_nodes": 8,
"hli_interfaces": 21,
@@ -369,6 +369,13 @@
"unknown"
]
},
+ {
+ "file": "syslog-issue-pipeline.yml",
+ "name": "SYSLOG Issue Pipeline",
+ "triggers": [
+ "issues"
+ ]
+ },
{
"file": "syslog-pipeline.yml",
"name": "铸渊 · SYSLOG Pipeline (A/D/E)",
@@ -442,7 +449,7 @@
]
}
],
- "item_count": 36
+ "item_count": 37
},
{
"zone_id": "SCRIPTS",
@@ -1369,6 +1376,9 @@
"syslog-auto-pipeline": [
"WORKFLOWS::syslog-auto-pipeline.yml"
],
+ "syslog-issue-pipeline": [
+ "WORKFLOWS::syslog-issue-pipeline.yml"
+ ],
"syslog-pipeline": [
"WORKFLOWS::syslog-pipeline.yml"
],
diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md
index 8dd53858..4fd16315 100644
--- a/.github/brain/repo-snapshot.md
+++ b/.github/brain/repo-snapshot.md
@@ -1,5 +1,5 @@
# 铸渊图书馆快照 · Repo Snapshot
-> 生成于 2026-03-13 12:49 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件
+> 生成于 2026-03-13 14:03 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件
---
@@ -9,11 +9,11 @@
|------|------|
| 区域总数 | 13 个区域 |
| 功能模块 | 10 个 (m01~m18) |
-| 工作流 | 36 个 GitHub Actions |
+| 工作流 | 37 个 GitHub Actions |
| 脚本 | 33 个执行脚本 |
| 开发者节点 | 8 人 |
| HLI 接口覆盖率 | 7/21 (33%) |
-| 快照生成时间 | 2026-03-13 12:49 CST |
+| 快照生成时间 | 2026-03-13 14:03 CST |
---
@@ -30,7 +30,7 @@
**关键词**: persona · identity · dev-status · 人格 · 开发者状态
### ⚡ 自动化工作流(WORKFLOWS)
-**路径**: `.github/workflows` · **数量**: 36 项
+**路径**: `.github/workflows` · **数量**: 37 项
**描述**: 所有 GitHub Actions 工作流定义
**关键词**: workflow · actions · ci · automation · 工作流 · 自动化
@@ -117,6 +117,7 @@
| `sync-login-entry.yml` | 铸渊 · Sync Login Entry · Notion → 飞书文档A | manual |
| `sync-persona-studio.yml` | 🔄 铸渊跨仓库同步 · persona-studio | push, manual |
| `syslog-auto-pipeline.yml` | SYSLOG Auto Pipeline | unknown |
+| `syslog-issue-pipeline.yml` | SYSLOG Issue Pipeline | issues |
| `syslog-pipeline.yml` | 铸渊 · SYSLOG Pipeline (A/D/E) | push, manual |
| `test-notion-bridge.yml` | "🧪 Notion Bridge Connectivity Test" | push, manual |
| `update-readme-bulletin.yml` | 📢 更新系统公告区 | push, schedule(0 1 * * *), manual |
diff --git a/.github/persona-brain/memory.json b/.github/persona-brain/memory.json
index 6cfa0e99..dae0f307 100644
--- a/.github/persona-brain/memory.json
+++ b/.github/persona-brain/memory.json
@@ -2,6 +2,12 @@
"persona_id": "ICE-GL-ZY001",
"persona_name": "铸渊",
"recent_events": [
+ {
+ "date": "2026-03-13",
+ "type": "brain_restore",
+ "description": "核心大脑恢复 · Persona Studio 铸渊代理开发工作流上线 · 「我要开发」功能修复 · Agent自动化5步开发 · 支持GUEST模式 · 使用用户API Key驱动",
+ "by": "铸渊(冰朔指令)"
+ },
{
"date": "2026-03-11",
"type": "architecture_upgrade",
diff --git a/.github/workflows/syslog-issue-pipeline.yml b/.github/workflows/syslog-issue-pipeline.yml
new file mode 100644
index 00000000..5a5d81a5
--- /dev/null
+++ b/.github/workflows/syslog-issue-pipeline.yml
@@ -0,0 +1,325 @@
+name: SYSLOG Issue Pipeline
+# 📡 SYSLOG 自助提交系统 · Issue 版全自动闭环
+#
+# 开发者在 GitHub Issue 提交 SYSLOG 或提问(使用 syslog-submit 模板)
+# → Actions 自动解析 → 调用 LLM API 唤醒人格体
+# → 写入 Notion 工单 → 发邮件给开发者 → Issue 回复
+#
+# 依赖 Secrets:
+# LLM_API_KEY 第三方 LLM 平台密钥(必须)
+# LLM_BASE_URL 第三方 LLM 平台 API 地址(必须,如 https://api.xxx.com/v1)
+# NOTION_API_TOKEN Notion API token
+# NOTION_TICKET_DB_ID 霜砚工单数据库 ID
+# CORE_BRAIN_PAGE_ID 曜冥核心大脑 v4.0 页面 ID(v4.0 协议动态注入)
+# PORTRAIT_DB_ID 开发者动态画像库数据库 ID(v4.0 协议动态注入)
+# FINGERPRINT_DB_ID 模块指纹注册表数据库 ID(v4.0 协议动态注入)
+# SMTP_USER QQ 邮箱地址
+# SMTP_PASS QQ 邮箱 SMTP 授权码
+
+on:
+ issues:
+ types: [opened, labeled]
+
+jobs:
+ process:
+ name: 📡 处理 SYSLOG 提交 / 广播提问 (Issue)
+ runs-on: ubuntu-latest
+ if: contains(toJSON(github.event.issue.labels), 'syslog')
+ permissions:
+ contents: write
+ issues: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: Install dependencies
+ run: npm ci --ignore-scripts
+
+ - name: 🔍 Parse submission
+ id: parse
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const body = context.payload.issue.body || '';
+ const title = context.payload.issue.title || '';
+
+ // Parse structured fields from issue body
+ function extractField(text, label) {
+ // Match form field format: ### Label\n\nValue
+ const regex = new RegExp('###\\s*' + label + '\\s*\\n+([^\\n#]+)', 'i');
+ const match = text.match(regex);
+ return match ? match[1].trim() : '';
+ }
+
+ const broadcastId = extractField(body, '广播编号') || '';
+ const submitType = extractField(body, '类型') || '';
+ const email = extractField(body, '你的邮箱') || '';
+
+ // Extract content (everything after "### 内容")
+ const contentMatch = body.match(/###\s*内容\s*\n+([\s\S]*?)$/i);
+ const content = contentMatch ? contentMatch[1].trim() : '';
+
+ // Determine type from title or body
+ let type = 'question'; // default
+ if (submitType.includes('SYSLOG') || title.includes('SYSLOG')) {
+ type = 'syslog';
+ } else if (submitType.includes('提问') || title.includes('提问')) {
+ type = 'question';
+ }
+
+ // Validate
+ if (!broadcastId) {
+ core.setFailed('❌ 缺少广播编号,请在提交时填写广播编号');
+ return;
+ }
+ if (!email) {
+ core.setFailed('❌ 缺少邮箱,请在提交时填写你的邮箱');
+ return;
+ }
+ if (!content) {
+ core.setFailed('❌ 缺少内容,请粘贴你的 SYSLOG 或问题');
+ return;
+ }
+
+ core.setOutput('broadcast_id', broadcastId);
+ core.setOutput('type', type);
+ core.setOutput('email', email);
+ core.setOutput('content', content);
+ core.setOutput('issue_number', context.payload.issue.number);
+ core.setOutput('author', context.payload.issue.user.login);
+
+ console.log(`📡 解析完成: 广播=${broadcastId}, 类型=${type}, 邮箱=${email}`);
+
+ - name: 🧠 Auto-detect and wake up persona
+ id: persona
+ env:
+ LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
+ LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
+ BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
+ SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
+ SUBMIT_CONTENT: ${{ steps.parse.outputs.content }}
+ AUTHOR: ${{ steps.parse.outputs.author }}
+ NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
+ CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }}
+ PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }}
+ FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }}
+ run: node scripts/wake-persona.js
+
+ - name: 📋 Write to Notion ticket
+ if: ${{ secrets.NOTION_API_TOKEN }}
+ env:
+ NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
+ NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }}
+ BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
+ SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
+ PERSONA_RESULT: ${{ steps.persona.outputs.result }}
+ run: |
+ node -e "
+ const https = require('https');
+
+ const token = process.env.NOTION_TOKEN;
+ const dbId = process.env.NOTION_TICKET_DB_ID;
+ const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN';
+ const type = process.env.SUBMIT_TYPE || 'syslog';
+ const result = process.env.PERSONA_RESULT || '(no result)';
+
+ if (!token || !dbId) {
+ console.log('⚠️ Notion credentials not configured, skipping ticket creation');
+ process.exit(0);
+ }
+
+ const typeLabel = type === 'syslog' ? 'SYSLOG闭环' : '提问解答';
+ const title = '[自动] ' + broadcastId + ' · ' + typeLabel;
+
+ const body = JSON.stringify({
+ parent: { database_id: dbId },
+ properties: {
+ '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] },
+ '操作类型': { select: { name: '其他' } },
+ '提交者': { rich_text: [{ type: 'text', text: { content: '自动管道' } }] },
+ '状态': { select: { name: '已完成' } },
+ '优先级': { select: { name: 'P1' } }
+ },
+ children: [{
+ object: 'block',
+ type: 'paragraph',
+ paragraph: {
+ rich_text: [{ type: 'text', text: { content: result.slice(0, 2000) } }]
+ }
+ }]
+ });
+
+ const opts = {
+ hostname: 'api.notion.com',
+ port: 443,
+ path: '/v1/pages',
+ method: 'POST',
+ headers: {
+ 'Authorization': 'Bearer ' + token,
+ 'Content-Type': 'application/json',
+ 'Notion-Version': '2022-06-28',
+ 'Content-Length': Buffer.byteLength(body)
+ }
+ };
+
+ const req = https.request(opts, (res) => {
+ let data = '';
+ res.on('data', (c) => data += c);
+ res.on('end', () => {
+ if (res.statusCode >= 200 && res.statusCode < 300) {
+ console.log('✅ Notion 工单已创建');
+ } else {
+ console.log('⚠️ Notion 工单创建失败: ' + res.statusCode + ' ' + data);
+ }
+ });
+ });
+ req.on('error', (e) => console.log('⚠️ Notion 请求失败: ' + e.message));
+ req.write(body);
+ req.end();
+ "
+
+ - name: 📧 Send email to developer
+ env:
+ SMTP_USER: ${{ secrets.SMTP_USER }}
+ SMTP_PASS: ${{ secrets.SMTP_PASS }}
+ EMAIL_TO: ${{ steps.parse.outputs.email }}
+ BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }}
+ SUBMIT_TYPE: ${{ steps.parse.outputs.type }}
+ PERSONA_RESULT: ${{ steps.persona.outputs.result }}
+ run: |
+ node -e "
+ const nodemailer = require('nodemailer');
+
+ const user = process.env.SMTP_USER || '';
+ const pass = process.env.SMTP_PASS || '';
+ const to = process.env.EMAIL_TO || '';
+ const broadcastId = process.env.BROADCAST_ID || '';
+ const type = process.env.SUBMIT_TYPE || 'syslog';
+ const result = process.env.PERSONA_RESULT || '(处理中,请稍后)';
+
+ if (!user || !pass) {
+ console.log('⚠️ SMTP not configured, skipping email');
+ process.exit(0);
+ }
+ if (!to) {
+ console.log('⚠️ No recipient email, skipping');
+ process.exit(0);
+ }
+
+ const subjectText = type === 'syslog'
+ ? '[光湖系统] ' + broadcastId + ' · 新广播已生成'
+ : '[光湖系统] ' + broadcastId + ' · 问题已解答';
+
+ const resultHtml = result
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/\n/g, '
');
+
+ const html = [
+ '
',
+ '
',
+ '
🌊 光湖系统 · 自动通知
',
+ '
HoloLake · 人格语言操作系统
',
+ '
',
+ '
',
+ '
📡 ' + broadcastId + '
',
+ '
' + resultHtml + '
',
+ '
',
+ '
',
+ '
'
+ ].join('\n');
+
+ const transporter = nodemailer.createTransport({
+ host: 'smtp.qq.com',
+ port: 465,
+ secure: true,
+ auth: { user, pass }
+ });
+
+ transporter.sendMail({
+ from: '\"光湖系统\" <' + user + '>',
+ to: to,
+ subject: subjectText,
+ html: html
+ }).then((info) => {
+ console.log('✅ 邮件已发送: ' + info.messageId);
+ }).catch((err) => {
+ console.log('⚠️ 邮件发送失败: ' + err.message);
+ });
+ "
+
+ - name: 💬 Reply to Issue
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const number = context.payload.issue.number;
+ const type = '${{ steps.parse.outputs.type }}';
+ const broadcastId = '${{ steps.parse.outputs.broadcast_id }}';
+ const email = '${{ steps.parse.outputs.email }}';
+
+ const typeLabel = type === 'syslog' ? 'SYSLOG 闭环处理' : '问题解答';
+ const maskedEmail = email.length > 4
+ ? email.replace(/(.{2})(.*)(@.*)/, '$1***$3')
+ : '***';
+
+ const body = [
+ '✅ **已处理** · ' + typeLabel,
+ '',
+ '| 项目 | 内容 |',
+ '|------|------|',
+ '| 📡 广播编号 | `' + broadcastId + '` |',
+ '| 📧 结果发送至 | `' + maskedEmail + '` |',
+ '| 🤖 处理人格体 | 铸渊 |',
+ '| ⏰ 处理时间 | ' + new Date().toISOString() + ' |',
+ '',
+ '> 结果已发送到你的邮箱,请查收。',
+ '>',
+ '> 如未收到,请检查垃圾箱或重新提交。'
+ ].join('\n');
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: number,
+ body: body
+ });
+
+ // Close the issue after processing
+ await github.rest.issues.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: number,
+ state: 'closed',
+ labels: ['syslog', 'processed']
+ });
+
+ console.log('✅ Issue 回复已发送并已关闭');
+
+ - name: 🔴 失败告警
+ if: failure()
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const number = context.payload.issue?.number;
+ if (!number) return;
+
+ try {
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: number,
+ body: '❌ **处理失败** · 请检查提交格式是否正确,或联系管理员。\n\n> 错误详情请查看 [Actions 日志](https://github.com/' + context.repo.owner + '/' + context.repo.repo + '/actions)。'
+ });
+ } catch (err) {
+ console.log('⚠️ 失败告警回复失败: ' + err.message);
+ }
diff --git a/.gitignore b/.gitignore
index 28f589d3..a0e218d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@ persona-brain-db/brain.db-shm
# persona-studio runtime artifacts
persona-studio/backend/brain/model-benchmark.json
+persona-studio/workspace/*/project-*
# palace-game runtime artifacts
modules/palace-game/data/saves/PAL-*
diff --git a/README.md b/README.md
index 4f27b893..51988395 100644
--- a/README.md
+++ b/README.md
@@ -53,12 +53,12 @@
-[](https://github.com/qinfendebingshuo/guanghulab/discussions/new?category=📡+SYSLOG+提交区)
-[](https://github.com/qinfendebingshuo/guanghulab/discussions/new?category=📡+SYSLOG+提交区)
+[](https://github.com/qinfendebingshuo/guanghulab/issues/new?template=syslog-submit.yml)
+[](https://github.com/qinfendebingshuo/guanghulab/issues/new?template=dev-question.yml)
-> 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。
+> 做完了?点蓝色按钮,把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。
>
-> 有问题?同一个入口,选「提问」,问题解答也发到你邮箱里。
+> 有问题?点绿色按钮,填写问题描述,铸渊会自动回答你。
@@ -92,21 +92,21 @@
| 时间 | 检查项 | 状态 |
|------|--------|------|
-| 03-13 12:50 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 |
-| 03-13 12:50 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 |
-| 03-13 12:49 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 |
-| 03-13 12:49 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) |
-| 03-13 12:49 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 |
+| 03-13 14:04 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 |
+| 03-13 14:03 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) |
+| 03-13 14:03 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 |
+| 03-13 14:03 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 |
+| 03-13 13:56 | 🔵 铸渊 · Bridge E · GitHub Changes → Notion · action_required | Copilot |
| 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) |
-| 03-13 11:31 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 |
-| 03-13 11:31 | ✅ 铸渊 · PSP 分身巡检 · 成功 | 冰朔 |
-| 03-13 11:22 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 |
-| 03-13 10:49 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 |
-| 03-13 09:56 | 🔧 系统更新: `docs/` | 铸渊 (ZhùYuān) |
| 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 |
| 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 |
| 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 |
| 03-11 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 |
+| 03-10 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 |
+| 03-10 08:00 | 🧠 核心大脑升级 v3.0 · 壳-核分离架构 · 前端壳(UI/IO) + 后端脑(prompt/routing/memory/context) · BRAIN域4接口上线 · 覆盖率 7/21 (33.3%) | 铸渊(冰朔指令) |
+| 03-10 08:00 | ⚠️ 铸渊 PSP 巡检完成 · 发现 3 个问题 · 自动修复 0 项 | 铸渊PSP巡检 |
+| 03-10 08:00 | 🔵 CI 构建 失败 | GitHub Actions |
+| 03-09 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 |
### 🤖 铸渊自动提醒
@@ -128,9 +128,9 @@
| 时间 | 合作者 | 模块 | 状态 |
|------|--------|------|------|
-| 03-13 12:49 | 冰朔 | `—/` | ✅ 上传成功 |
-| 03-13 12:49 | Copilot | `—/` | ✅ 上传成功 |
-| 03-13 09:56 | 🤖 之之 | `dingtalk-bot/` | 📦 上传成功 |
+| 03-13 14:03 | 冰朔 | `—/` | ✅ 上传成功 |
+| 03-13 14:03 | Copilot | `—/` | ✅ 上传成功 |
+| 03-13 13:56 | Copilot | `—/` | 🔵 已更新 |
### 🤖 铸渊自动提醒 · 合作者
diff --git a/persona-studio/backend/brain/agent-workflow.js b/persona-studio/backend/brain/agent-workflow.js
new file mode 100644
index 00000000..aeacc4b4
--- /dev/null
+++ b/persona-studio/backend/brain/agent-workflow.js
@@ -0,0 +1,761 @@
+/**
+ * persona-studio · 铸渊代理开发工作流引擎(壳-核分离架构)
+ *
+ * 架构设计:
+ * 核 = 铸渊核心大脑(Core Brain)
+ * ↳ 加载开发者记忆、画像、项目历史、知识库、模式库
+ * ↳ 深度分析开发者真实意图
+ * ↳ 生成结构化开发计划
+ * 壳 = 铸渊代理(Agent Executor)
+ * ↳ 接收核心大脑推送的开发计划
+ * ↳ 逐步执行代码生成
+ * ↳ 广播进度给前端
+ * ↳ 完成后回传核心大脑做自进化
+ *
+ * 流程:
+ * 用户点击「我要开发」
+ * → Agent 唤醒核心大脑
+ * → 核心大脑:加载全部上下文 → 分析意图 → 生成开发计划
+ * → Agent:接收计划 → 逐步执行 → 广播进度
+ * → 核心大脑:知识提取 + 模式更新 + 画像学习 + 进化日志
+ */
+const fs = require('fs');
+const path = require('path');
+const https = require('https');
+const http = require('http');
+
+// ── 常量 ──
+// 传入 LLM 的对话文本最大字符数(防止超出模型上下文窗口)
+const MAX_CONVERSATION_CHARS = 4000;
+
+// ── 核心大脑模块 ──
+const memoryManager = require('./memory-manager');
+const personaEngine = require('./persona-engine');
+const memoryInjector = require('./memory-injector');
+const knowledgeExtractor = require('./knowledge-extractor');
+const patternAnalyzer = require('./pattern-analyzer');
+const profileLearner = require('./profile-learner');
+const evolutionLogger = require('./evolution-logger');
+
+const WORKSPACE_DIR = path.join(__dirname, '..', '..', 'workspace');
+const REGISTRY_PATH = path.join(__dirname, '..', '..', 'brain', 'registry.json');
+const HUMAN_REGISTRY_PATH = path.join(__dirname, '..', '..', 'brain', 'human-registry.json');
+
+/* ================================================================
+ 工具函数
+ ================================================================ */
+
+/**
+ * 调用用户提供的 LLM API(OpenAI 兼容格式)
+ */
+function callLLM({ apiBase, apiKey, model, messages, maxTokens, temperature, timeoutMs }) {
+ return new Promise((resolve, reject) => {
+ const base = apiBase.replace(/\/+$/, '');
+ const chatUrl = new URL(base + '/chat/completions');
+ const isHttps = chatUrl.protocol === 'https:';
+ const mod = isHttps ? https : http;
+
+ const body = JSON.stringify({
+ model,
+ messages,
+ max_tokens: maxTokens || 4000,
+ temperature: temperature != null ? temperature : 0.3
+ });
+
+ const options = {
+ hostname: chatUrl.hostname,
+ port: chatUrl.port || (isHttps ? 443 : 80),
+ path: chatUrl.pathname,
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Bearer ' + apiKey,
+ 'Content-Length': Buffer.byteLength(body)
+ },
+ timeout: timeoutMs || 60000
+ };
+
+ const req = mod.request(options, (res) => {
+ let data = '';
+ res.on('data', (chunk) => { data += chunk; });
+ res.on('end', () => {
+ try {
+ const json = JSON.parse(data);
+ if (json.choices && json.choices[0] && json.choices[0].message) {
+ resolve(json.choices[0].message.content);
+ } else if (json.error) {
+ reject(new Error(json.error.message || 'API error'));
+ } else {
+ reject(new Error('Unexpected API response'));
+ }
+ } catch (_e) {
+ reject(new Error('Failed to parse API response'));
+ }
+ });
+ });
+
+ req.on('error', reject);
+ req.on('timeout', () => {
+ req.destroy();
+ reject(new Error('Request timeout'));
+ });
+
+ req.write(body);
+ req.end();
+ });
+}
+
+/**
+ * 从注册表查找开发者信息
+ */
+function lookupDeveloper(devId) {
+ if (!devId || devId === 'GUEST') {
+ return { dev_id: 'GUEST', name: '访客', role: 'guest' };
+ }
+ try {
+ var reg = JSON.parse(fs.readFileSync(REGISTRY_PATH, 'utf-8'));
+ if (reg.developers && reg.developers[devId]) {
+ return Object.assign({ dev_id: devId }, reg.developers[devId]);
+ }
+ } catch (_e) { /* ignore */ }
+ try {
+ var hReg = JSON.parse(fs.readFileSync(HUMAN_REGISTRY_PATH, 'utf-8'));
+ if (hReg.developers) {
+ var found = hReg.developers.find(function (d) { return d.exp_id === devId; });
+ if (found) return { dev_id: devId, name: found.name, role: found.role };
+ }
+ } catch (_e) { /* ignore */ }
+ return { dev_id: devId, name: devId, role: 'developer' };
+}
+
+/* ================================================================
+ Phase 1: 唤醒铸渊核心大脑(Core Brain Wake)
+ ================================================================ */
+
+/**
+ * 唤醒核心大脑,加载全部上下文,分析开发者意图,生成开发计划。
+ *
+ * 核心大脑聚合以下信息源:
+ * ① 开发者身份(来自 registry)
+ * ② 对话记忆(来自 memory-manager)
+ * ③ 用户画像(来自 profile-learner:技术水平、沟通风格、设计偏好)
+ * ④ 项目历史(来自 memory-manager)
+ * ⑤ 知识库(来自 knowledge-extractor)
+ * ⑥ 模式库(来自 pattern-analyzer)
+ * ⑦ 记忆摘要(来自 memory-injector)
+ */
+async function wakeCoreBrain(devId, conversation, apiBase, apiKey, model) {
+ var devInfo = lookupDeveloper(devId);
+ var isGuest = devId === 'GUEST';
+
+ // ── ① 加载开发者记忆 ──
+ var memory = { conversations: [], last_topic: null };
+ if (!isGuest) {
+ try { memory = memoryManager.loadMemory(devId); } catch (_e) { /* new user */ }
+ }
+
+ // ── ② 加载用户画像 ──
+ var profile = null;
+ if (!isGuest) {
+ try { profile = profileLearner.loadProfile(devId); } catch (_e) { /* ignore */ }
+ }
+
+ // ── ③ 加载项目历史 ──
+ var projects = { projects: [] };
+ if (!isGuest) {
+ try { projects = memoryManager.loadProjects(devId); } catch (_e) { /* ignore */ }
+ }
+
+ // ── ④ 查询知识库 ──
+ var conversationText = conversation
+ .map(function (m) { return m.content || ''; })
+ .join(' ');
+ var relevantKnowledge = [];
+ try { relevantKnowledge = knowledgeExtractor.queryKnowledge(conversationText, 5); } catch (_e) { /* ignore */ }
+
+ // ── ⑤ 查询模式库 ──
+ var relevantPatterns = [];
+ try { relevantPatterns = patternAnalyzer.queryPatterns(conversationText); } catch (_e) { /* ignore */ }
+
+ // ── ⑥ 构建核心大脑认知上下文 ──
+ var brainContext = buildBrainContext(devInfo, memory, profile, projects, relevantKnowledge, relevantPatterns);
+
+ // ── ⑦ 使用 LLM 深度分析意图 + 生成开发计划 ──
+ var developmentPlan;
+ if (apiBase && apiKey && model) {
+ developmentPlan = await analyzeIntentWithLLM(brainContext, conversation, apiBase, apiKey, model);
+ } else {
+ developmentPlan = analyzeIntentLocally(brainContext, conversation);
+ }
+
+ return { brainContext: brainContext, developmentPlan: developmentPlan };
+}
+
+/**
+ * 构建核心大脑认知上下文(聚合全部信息源)
+ */
+function buildBrainContext(devInfo, memory, profile, projects, knowledge, patterns) {
+ return {
+ developer: {
+ id: devInfo.dev_id,
+ name: devInfo.name || devInfo.dev_id,
+ role: devInfo.role || 'developer',
+ is_guest: devInfo.dev_id === 'GUEST'
+ },
+ memory: {
+ total_conversations: (memory.conversations || []).length,
+ last_topic: memory.last_topic || null,
+ has_history: (memory.conversations || []).length > 0
+ },
+ profile: {
+ tech_level: (profile && profile.tech_assessment && profile.tech_assessment.level) || null,
+ known_skills: (profile && profile.tech_assessment && profile.tech_assessment.known_skills) || [],
+ communication_style: (profile && profile.communication_style && profile.communication_style.verbosity) || null,
+ design_preference: (profile && profile.design_preferences && profile.design_preferences.color_scheme) || null,
+ style_keywords: (profile && profile.design_preferences && profile.design_preferences.style_keywords) || [],
+ mood: (profile && profile.emotional_profile && profile.emotional_profile.current_mood) || 'neutral'
+ },
+ projects: {
+ total: (projects.projects || []).length,
+ recent: (projects.projects || []).slice(-3).map(function (p) {
+ return { name: p.name, status: p.status, files: (p.files || []).length };
+ })
+ },
+ knowledge: knowledge.map(function (k) {
+ return { type: k.type, title: k.title, category: k.category };
+ }),
+ patterns: patterns.slice(0, 3).map(function (p) {
+ return {
+ name: p.name,
+ frequency: p.frequency,
+ success_rate: p.success_rate,
+ tech_stack: p.common_tech_stack || []
+ };
+ })
+ };
+}
+
+/**
+ * 使用 LLM 深度分析开发者意图并生成开发计划
+ * 核心大脑将全部上下文注入 system prompt,让 LLM 理解开发者的真正需求
+ */
+async function analyzeIntentWithLLM(brainContext, conversation, apiBase, apiKey, model) {
+ var conversationText = conversation.map(function (m) {
+ var role = m.role === 'user' ? '用户' : '铸渊';
+ return role + ': ' + m.content;
+ }).join('\n');
+
+ // 构建核心大脑系统提示词(注入全部上下文)
+ var systemParts = [
+ '你是铸渊核心大脑的意图分析引擎。',
+ '你的任务是深度理解开发者的真实需求,生成精确的开发计划。',
+ '',
+ '## 开发者档案',
+ '- 身份:' + brainContext.developer.name + '(' + brainContext.developer.id + ')',
+ '- 角色:' + brainContext.developer.role
+ ];
+
+ if (brainContext.developer.is_guest) {
+ systemParts.push('- ⚠️ 访客用户(无历史记忆)');
+ } else {
+ systemParts.push('- 历史对话:' + brainContext.memory.total_conversations + ' 条');
+ }
+
+ if (brainContext.memory.last_topic) {
+ systemParts.push('- 上次话题:' + brainContext.memory.last_topic);
+ }
+ if (brainContext.profile.tech_level) {
+ systemParts.push('- 技术水平:' + brainContext.profile.tech_level);
+ }
+ if (brainContext.profile.known_skills.length > 0) {
+ systemParts.push('- 已知技能:' + brainContext.profile.known_skills.join(', '));
+ }
+ if (brainContext.profile.communication_style) {
+ systemParts.push('- 沟通风格:' + brainContext.profile.communication_style);
+ }
+ if (brainContext.profile.design_preference) {
+ systemParts.push('- 设计偏好:' + brainContext.profile.design_preference);
+ }
+ if (brainContext.profile.style_keywords.length > 0) {
+ systemParts.push('- 风格关键词:' + brainContext.profile.style_keywords.join('、'));
+ }
+
+ if (brainContext.projects.total > 0) {
+ systemParts.push('');
+ systemParts.push('## 历史项目(共 ' + brainContext.projects.total + ' 个)');
+ brainContext.projects.recent.forEach(function (p) {
+ systemParts.push('- ' + p.name + '(' + p.status + ',' + p.files + ' 个文件)');
+ });
+ }
+
+ if (brainContext.knowledge.length > 0) {
+ systemParts.push('');
+ systemParts.push('## 相关知识库');
+ brainContext.knowledge.forEach(function (k) {
+ systemParts.push('- [' + k.type + '] ' + k.title);
+ });
+ }
+
+ if (brainContext.patterns.length > 0) {
+ systemParts.push('');
+ systemParts.push('## 高频开发模式');
+ brainContext.patterns.forEach(function (p) {
+ systemParts.push('- ' + p.name + '(' + p.frequency + '次,成功率' + p.success_rate + '%,技术栈:' + p.tech_stack.join('/') + ')');
+ });
+ }
+
+ systemParts.push('');
+ systemParts.push('## 输出要求');
+ systemParts.push('根据对话内容和开发者档案,输出严格 JSON 格式的开发计划:');
+ systemParts.push('{');
+ systemParts.push(' "intent_summary": "一句话总结开发者的真实意图",');
+ systemParts.push(' "project_name": "英文项目名(kebab-case)",');
+ systemParts.push(' "description": "项目描述(考虑开发者的技术水平和偏好)",');
+ systemParts.push(' "design_notes": "设计要点(基于开发者的设计偏好和风格关键词)",');
+ systemParts.push(' "tech_decisions": "技术决策说明(基于开发者的技能水平选择合适的复杂度)",');
+ systemParts.push(' "files": [');
+ systemParts.push(' { "filename": "index.html", "description": "详细文件说明", "key_features": ["功能1","功能2"] }');
+ systemParts.push(' ]');
+ systemParts.push('}');
+ systemParts.push('');
+ systemParts.push('注意:');
+ systemParts.push('- 只生成前端文件(HTML/CSS/JS),最多5个文件');
+ systemParts.push('- 必须包含 index.html');
+ systemParts.push('- 根据开发者技术水平调整代码复杂度');
+ systemParts.push('- 根据开发者设计偏好决定视觉风格');
+ systemParts.push('- 如果对话中提到了具体功能需求,务必全部纳入计划');
+
+ try {
+ var reply = await callLLM({
+ apiBase: apiBase,
+ apiKey: apiKey,
+ model: model,
+ messages: [
+ { role: 'system', content: systemParts.join('\n') },
+ { role: 'user', content: '以下是和开发者的完整对话,请分析意图并生成开发计划:\n\n' + conversationText.substring(0, MAX_CONVERSATION_CHARS) }
+ ],
+ maxTokens: 2000,
+ temperature: 0.2,
+ timeoutMs: 45000
+ });
+
+ var jsonMatch = reply.match(/\{[\s\S]*\}/);
+ if (jsonMatch) {
+ var plan = JSON.parse(jsonMatch[0]);
+ if (plan.files && !plan.files.some(function (f) { return f.filename === 'index.html'; })) {
+ plan.files.unshift({ filename: 'index.html', description: '主页面', key_features: ['入口页面'] });
+ }
+ if (plan.files) {
+ plan.files = plan.files.slice(0, 5);
+ }
+ plan._source = 'core_brain_llm';
+ return plan;
+ }
+ } catch (_e) {
+ // LLM 分析失败,降级到本地分析
+ }
+
+ return analyzeIntentLocally(brainContext, conversation);
+}
+
+/**
+ * 本地意图分析(无 API 或 API 失败时的降级方案)
+ * 使用规则引擎从对话和开发者档案中提取意图
+ */
+function analyzeIntentLocally(brainContext, conversation) {
+ var userText = conversation
+ .filter(function (m) { return m.role === 'user'; })
+ .map(function (m) { return m.content || ''; })
+ .join(' ');
+
+ var projectType = '通用项目';
+ if (brainContext.patterns.length > 0) {
+ projectType = brainContext.patterns[0].name;
+ }
+
+ var designStyle = '现代简约';
+ if (brainContext.profile.style_keywords.length > 0) {
+ designStyle = brainContext.profile.style_keywords.join(' + ');
+ } else if (brainContext.profile.design_preference === 'dark') {
+ designStyle = '深色主题·科技感';
+ }
+
+ var complexity = 'moderate';
+ if (brainContext.profile.tech_level === 'beginner') {
+ complexity = 'simple';
+ } else if (brainContext.profile.tech_level === 'advanced') {
+ complexity = 'advanced';
+ }
+
+ return {
+ intent_summary: userText.substring(0, 100) || '开发一个网页项目',
+ project_name: 'web-project',
+ description: userText.substring(0, 200) || '网页项目',
+ design_notes: '风格:' + designStyle,
+ tech_decisions: '复杂度:' + complexity + ',技术栈:HTML/CSS/JavaScript',
+ files: [
+ { filename: 'index.html', description: '主页面', key_features: ['响应式布局', '核心功能展示'] },
+ { filename: 'style.css', description: '样式文件', key_features: [designStyle] },
+ { filename: 'main.js', description: '交互逻辑', key_features: ['用户交互', '动态效果'] }
+ ],
+ _source: 'core_brain_local'
+ };
+}
+
+/* ================================================================
+ Phase 2: 铸渊代理执行(Agent Execute)
+ ================================================================ */
+
+/**
+ * Agent 接收核心大脑的开发计划,逐步执行代码生成
+ */
+async function agentExecute(developmentPlan, devId, apiBase, apiKey, model, broadcastFn) {
+ var projectName = 'project-' + Date.now();
+ var files = {};
+ var filePlan = developmentPlan.files || [];
+ var hasUserApi = apiBase && apiKey && model;
+
+ for (var i = 0; i < filePlan.length; i++) {
+ var fileSpec = filePlan[i];
+
+ broadcastFn({
+ type: 'progress',
+ step: 3,
+ message: '💻 铸渊代理 · 生成文件 (' + (i + 1) + '/' + filePlan.length + '): ' + fileSpec.filename,
+ status: 'building',
+ status_text: '生成 ' + fileSpec.filename
+ });
+
+ if (hasUserApi) {
+ try {
+ var code = await generateFileWithLLM(developmentPlan, fileSpec, filePlan, apiBase, apiKey, model);
+ files[fileSpec.filename] = code;
+ } catch (_e) {
+ files[fileSpec.filename] = generatePlaceholder(fileSpec, developmentPlan);
+ }
+ } else {
+ files[fileSpec.filename] = generatePlaceholder(fileSpec, developmentPlan);
+ }
+ }
+
+ // 写入 workspace
+ var projectDir = path.join(WORKSPACE_DIR, devId, projectName);
+ fs.mkdirSync(projectDir, { recursive: true });
+
+ var fileList = [];
+ var entries = Object.entries(files);
+ for (var j = 0; j < entries.length; j++) {
+ var safeName = path.basename(entries[j][0]);
+ // 安全检查:防止路径遍历和隐藏文件
+ if (!safeName || safeName.startsWith('.') || /[/\\]/.test(entries[j][0])) continue;
+ fs.writeFileSync(path.join(projectDir, safeName), entries[j][1], 'utf-8');
+ fileList.push(safeName);
+ }
+
+ // 生成 README
+ var readmePath = path.join(projectDir, 'README.md');
+ if (!fs.existsSync(readmePath)) {
+ fs.writeFileSync(readmePath, [
+ '# ' + (developmentPlan.project_name || projectName),
+ '',
+ developmentPlan.description || '',
+ '',
+ '## 铸渊核心大脑分析',
+ '- 意图:' + (developmentPlan.intent_summary || ''),
+ '- 设计:' + (developmentPlan.design_notes || ''),
+ '- 技术:' + (developmentPlan.tech_decisions || ''),
+ '',
+ '由光湖 Persona Studio · 铸渊核心大脑 + 铸渊代理 协同开发',
+ '生成时间:' + new Date().toISOString()
+ ].join('\n'), 'utf-8');
+ fileList.push('README.md');
+ }
+
+ return { projectName: projectName, files: fileList };
+}
+
+/**
+ * 使用 LLM 生成单个文件(Agent 执行层)
+ * 注入核心大脑的开发计划上下文,确保代码与意图一致
+ */
+async function generateFileWithLLM(plan, fileSpec, allFiles, apiBase, apiKey, model) {
+ var prompt = [
+ '你是铸渊代理的代码生成模块。根据核心大脑的开发计划生成代码。',
+ '',
+ '## 项目信息',
+ '- 项目:' + (plan.project_name || 'web-project'),
+ '- 描述:' + (plan.description || ''),
+ '- 意图:' + (plan.intent_summary || ''),
+ '- 设计要点:' + (plan.design_notes || ''),
+ '- 技术决策:' + (plan.tech_decisions || ''),
+ '',
+ '## 当前文件',
+ '- 文件名:' + fileSpec.filename,
+ '- 说明:' + (fileSpec.description || ''),
+ '- 核心功能:' + (fileSpec.key_features || []).join('、'),
+ '',
+ '## 项目全部文件',
+ allFiles.map(function (f) { return '- ' + f.filename + '(' + (f.description || '') + ')'; }).join('\n'),
+ '',
+ '请直接输出文件内容,不要用 ``` 代码块包裹,不要加任何额外说明。',
+ '确保代码完整、可运行、符合核心大脑的设计要求。',
+ '如果是 HTML 文件,要正确引用同项目中的 CSS 和 JS 文件。'
+ ].join('\n');
+
+ var reply = await callLLM({
+ apiBase: apiBase,
+ apiKey: apiKey,
+ model: model,
+ messages: [{ role: 'user', content: prompt }],
+ maxTokens: 4000,
+ temperature: 0.3,
+ timeoutMs: 60000
+ });
+
+ var clean = reply.trim();
+ if (clean.startsWith('```')) {
+ clean = clean.replace(/^```\S*\n?/, '').replace(/\n?```\s*$/, '');
+ }
+ return clean;
+}
+
+/**
+ * 生成占位内容(无 API 或单文件失败时的降级方案)
+ */
+function generatePlaceholder(fileSpec, plan) {
+ var desc = plan.description || plan.intent_summary || plan.project_name || '项目';
+ var designNotes = plan.design_notes || '现代简约';
+
+ if (fileSpec.filename === 'index.html') {
+ return [
+ '',
+ '',
+ '',
+ ' ',
+ ' ',
+ ' ' + (plan.project_name || '项目') + '',
+ ' ',
+ '',
+ '',
+ ' ',
+ '
🌊 ' + desc + '
',
+ '
由光湖 Persona Studio · 铸渊核心大脑 + 铸渊代理 协同开发
',
+ '
设计风格:' + designNotes + '
',
+ '
',
+ ' ',
+ '',
+ ''
+ ].join('\n');
+ }
+ if (fileSpec.filename.endsWith('.css')) {
+ return [
+ '/* Generated by Persona Studio · Core Brain + Agent */',
+ '* { margin: 0; padding: 0; box-sizing: border-box; }',
+ 'body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0f172a; color: #e2e8f0; min-height: 100vh; display: flex; align-items: center; justify-content: center; }',
+ '.container { text-align: center; padding: 2rem; max-width: 800px; }',
+ 'h1 { font-size: 2rem; margin-bottom: 1rem; background: linear-gradient(135deg, #60a5fa, #22d3ee); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }',
+ '.design-note { color: #64748b; font-size: 0.875rem; margin-top: 1rem; }'
+ ].join('\n');
+ }
+ if (fileSpec.filename.endsWith('.js')) {
+ return '// Generated by Persona Studio · Core Brain + Agent\nconsole.log("' + (plan.project_name || 'Project') + ' initialized by 铸渊代理");\n';
+ }
+ return '/* Generated by Persona Studio */\n';
+}
+
+/* ================================================================
+ Phase 3: 核心大脑自进化(Post-Build Evolution)
+ ================================================================ */
+
+/**
+ * 开发完成后,核心大脑进行自进化:
+ * ① 知识提取 → 更新 knowledge-base.json
+ * ② 模式识别 → 更新 pattern-library.json
+ * ③ 画像学习 → 更新 profile.json
+ * ④ 进化日志 → 更新 evolution-log.json
+ */
+function coreBrainPostEvolution(devId, conversation, result, brainContext, startTime, success) {
+ try {
+ var buildTimeMs = Date.now() - startTime;
+
+ // ① 知识提取
+ try {
+ knowledgeExtractor.autoExtractKnowledge(devId, conversation, result.projectName);
+ } catch (_e) { /* non-fatal */ }
+
+ // ② 模式识别
+ var patterns = [];
+ try {
+ patterns = patternAnalyzer.analyzeAndUpdatePatterns(
+ devId, conversation, result.files, buildTimeMs, success
+ );
+ } catch (_e) { /* non-fatal */ }
+
+ // ③ 画像学习(从最后一条用户消息学习)
+ if (devId !== 'GUEST') {
+ try {
+ var lastUser = conversation.filter(function (m) { return m.role === 'user'; }).pop();
+ if (lastUser) {
+ profileLearner.updateProfile(devId, lastUser.content, result.summary || '');
+ }
+ } catch (_e) { /* non-fatal */ }
+ }
+
+ // ④ 进化日志
+ evolutionLogger.logEvent('agent_build_complete', '铸渊代理开发完成: ' + result.projectName, {
+ dev_id: devId,
+ project: result.projectName,
+ files_count: (result.files || []).length,
+ build_time_ms: buildTimeMs,
+ success: success,
+ brain_source: brainContext.developer.is_guest ? 'local' : 'llm',
+ patterns_detected: patterns,
+ developer_tech_level: brainContext.profile.tech_level,
+ developer_projects_total: brainContext.projects.total
+ });
+ } catch (err) {
+ console.error('Core brain post-evolution error:', err.message);
+ }
+}
+
+/* ================================================================
+ 主工作流入口
+ ================================================================ */
+
+/**
+ * 运行铸渊代理开发工作流(壳-核分离)
+ *
+ * @param {object} params
+ * @param {string} params.dev_id - 开发编号(EXP-XXX 或 GUEST)
+ * @param {Array} params.conversation - 对话历史
+ * @param {string} params.api_base - 用户 API Base URL
+ * @param {string} params.api_key - 用户 API Key
+ * @param {string} params.model - 用户选择的模型
+ * @param {Function} params.broadcast - WebSocket 广播函数
+ * @returns {Promise<{projectName, files, summary}>}
+ */
+async function runWorkflow({ dev_id, conversation, api_base, api_key, model, broadcast }) {
+ var emitProgress = broadcast || function () {};
+ var startTime = Date.now();
+ var brainContext = null;
+
+ // ════════════════════════════════════════════
+ // Phase 1: 唤醒铸渊核心大脑
+ // ════════════════════════════════════════════
+ emitProgress({
+ type: 'progress',
+ step: 1,
+ total_steps: 5,
+ message: '🧠 正在唤醒铸渊核心大脑...',
+ status: 'building',
+ status_text: '唤醒核心大脑'
+ });
+
+ var coreBrainResult;
+ try {
+ coreBrainResult = await wakeCoreBrain(dev_id, conversation, api_base, api_key, model);
+ brainContext = coreBrainResult.brainContext;
+ } catch (_err) {
+ brainContext = buildBrainContext(
+ lookupDeveloper(dev_id),
+ { conversations: [], last_topic: null },
+ null, { projects: [] }, [], []
+ );
+ coreBrainResult = {
+ brainContext: brainContext,
+ developmentPlan: analyzeIntentLocally(brainContext, conversation)
+ };
+ }
+
+ var plan = coreBrainResult.developmentPlan;
+
+ emitProgress({
+ type: 'progress',
+ step: 1,
+ message: '✅ 核心大脑已唤醒 · 意图分析完成:' + (plan.intent_summary || '').substring(0, 50),
+ status: 'building',
+ status_text: '意图已分析'
+ });
+
+ // ════════════════════════════════════════════
+ // Phase 1.5: 核心大脑推送开发计划
+ // ════════════════════════════════════════════
+ emitProgress({
+ type: 'progress',
+ step: 2,
+ total_steps: 5,
+ message: '📐 核心大脑 → 代理:推送开发计划(' + (plan.files || []).length + ' 个文件)',
+ status: 'building',
+ status_text: '计划已推送'
+ });
+
+ if (plan.design_notes) {
+ emitProgress({
+ type: 'progress',
+ step: 2,
+ message: '🎨 设计指令:' + plan.design_notes,
+ status: 'building',
+ status_text: '设计已确认'
+ });
+ }
+
+ // ════════════════════════════════════════════
+ // Phase 2: 铸渊代理执行开发
+ // ════════════════════════════════════════════
+ emitProgress({
+ type: 'progress',
+ step: 3,
+ total_steps: 5,
+ message: '💻 铸渊代理 · 开始执行核心大脑的开发计划...',
+ status: 'building',
+ status_text: '代理执行中'
+ });
+
+ var agentResult = await agentExecute(plan, dev_id, api_base, api_key, model, emitProgress);
+
+ emitProgress({
+ type: 'progress',
+ step: 3,
+ message: '✅ 代理执行完成:' + agentResult.files.length + ' 个文件已生成',
+ status: 'building',
+ status_text: '代码已生成'
+ });
+
+ // ════════════════════════════════════════════
+ // Phase 2.5: 预览部署
+ // ════════════════════════════════════════════
+ emitProgress({
+ type: 'progress',
+ step: 4,
+ total_steps: 5,
+ message: '🚀 铸渊代理 · 部署预览...',
+ status: 'building',
+ status_text: '部署预览'
+ });
+
+ // ════════════════════════════════════════════
+ // Phase 3: 核心大脑自进化
+ // ════════════════════════════════════════════
+ var finalResult = {
+ projectName: agentResult.projectName,
+ files: agentResult.files,
+ summary: '项目 ' + agentResult.projectName + ' 由铸渊核心大脑分析意图 + 铸渊代理执行开发完成,包含 ' + agentResult.files.length + ' 个文件。\n意图:' + (plan.intent_summary || '') + '\n设计:' + (plan.design_notes || '')
+ };
+
+ coreBrainPostEvolution(dev_id, conversation, finalResult, brainContext, startTime, true);
+
+ emitProgress({
+ type: 'progress',
+ step: 5,
+ total_steps: 5,
+ message: '✨ 铸渊核心大脑 · 自进化完成 · 知识与模式已更新',
+ status: 'building',
+ status_text: '即将完成'
+ });
+
+ return finalResult;
+}
+
+module.exports = {
+ runWorkflow
+};
diff --git a/persona-studio/backend/routes/build.js b/persona-studio/backend/routes/build.js
index a60dfb18..73a7d0a4 100644
--- a/persona-studio/backend/routes/build.js
+++ b/persona-studio/backend/routes/build.js
@@ -1,21 +1,29 @@
/**
* persona-studio · 开发任务路由
- * POST /api/ps/build/start 触发代码生成
+ * POST /api/ps/build/start 触发铸渊代理开发工作流
+ *
+ * 当用户点击「我要开发」时,自动触发铸渊代理(Agent)
+ * 使用用户自带的 API Key 进行 5 步自动化开发。
*/
const express = require('express');
const router = express.Router();
const memoryManager = require('../brain/memory-manager');
-const codeGenerator = require('../brain/code-generator');
+const agentWorkflow = require('../brain/agent-workflow');
const emailSender = require('../utils/email-sender');
// 邮箱后端正则二次校验
const EMAIL_RE = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
+// 支持 EXP-XXX 和 GUEST 两种 dev_id 格式
+function isValidDevId(devId) {
+ return devId === 'GUEST' || /^EXP-\d{3,}$/.test(devId);
+}
+
// POST /api/ps/build/start
router.post('/start', async (req, res) => {
- const { dev_id, email, contact, conversation } = req.body || {};
+ const { dev_id, email, contact, conversation, api_base, api_key, model } = req.body || {};
- if (!dev_id || !/^EXP-\d{3,}$/.test(dev_id)) {
+ if (!dev_id || !isValidDevId(dev_id)) {
return res.status(400).json({
error: true,
code: 'INVALID_ID',
@@ -40,71 +48,94 @@ router.post('/start', async (req, res) => {
});
}
+ // 防止 header injection:API Key 不得包含换行符
+ if (api_key && /[\r\n]/.test(api_key)) {
+ return res.status(400).json({
+ error: true,
+ code: 'INVALID_API_KEY',
+ message: 'API Key 格式无效'
+ });
+ }
+
// 联系方式输入清理(去除潜在 HTML/script 注入)
const safeContact = contact ? String(contact).replace(/[<>&"']/g, '').substring(0, 100) : null;
// 先立即响应,后台异步处理
res.json({
error: false,
- message: '开发任务已接收,完成后将发送到 ' + email,
- status: 'queued'
+ message: '铸渊代理已启动,完成后将发送到 ' + email,
+ status: 'agent_started'
});
- // 异步执行代码生成 + 邮件通知
+ // 异步执行铸渊代理开发工作流
(async () => {
- const broadcast = req.app.locals.broadcastToClient || function () {};
+ const broadcastRaw = req.app.locals.broadcastToClient || function () {};
+ const broadcast = function (data) { broadcastRaw(dev_id, data); };
try {
- broadcast(dev_id, {
+ // 启动 Agent 工作流
+ broadcast({
type: 'progress',
- message: '🔧 正在创建项目骨架...',
+ message: '🌀 铸渊代理已唤醒,正在启动开发工作流...',
status: 'building',
- status_text: '构建中'
+ status_text: '代理已启动'
});
- const result = await codeGenerator.generate({
- dev_id,
+ const result = await agentWorkflow.runWorkflow({
+ dev_id: dev_id,
conversation: conversation || [],
+ api_base: api_base || '',
+ api_key: api_key || '',
+ model: model || '',
+ broadcast: broadcast
});
- // 记录项目
- memoryManager.addProject(dev_id, {
- name: result.projectName || 'untitled',
- email: email,
- contact: safeContact,
- status: 'completed',
- created_at: new Date().toISOString(),
- files: result.files || []
- });
+ // 记录项目(GUEST 也记录,方便追踪)
+ try {
+ memoryManager.addProject(dev_id, {
+ name: result.projectName || 'untitled',
+ email: email,
+ contact: safeContact,
+ status: 'completed',
+ created_at: new Date().toISOString(),
+ files: result.files || []
+ });
- // 自动提取知识
- memoryManager.autoExtractKnowledge(dev_id, conversation, result.projectName);
+ // 自动提取知识(仅注册开发者)
+ if (dev_id !== 'GUEST') {
+ memoryManager.autoExtractKnowledge(dev_id, conversation, result.projectName);
+ }
+ } catch (memErr) {
+ console.error('Memory save error (non-fatal):', memErr.message);
+ }
// 通知预览就绪
- broadcast(dev_id, {
+ broadcast({
type: 'preview_ready',
project: result.projectName,
message: '✅ 预览已就绪'
});
- broadcast(dev_id, {
+ broadcast({
type: 'complete',
message: '🎉 全部完成!邮件正在发送'
});
- // 发邮件
- await emailSender.sendCompletion({
+ // 发邮件(异步,不阻塞主流程)
+ emailSender.sendCompletion({
to: email,
- dev_id,
+ dev_id: dev_id,
projectName: result.projectName,
summary: result.summary,
files: result.files
+ }).catch(function (emailErr) {
+ console.error('Email send error (non-fatal):', emailErr.message);
});
} catch (err) {
- console.error('Build pipeline error:', err.message);
- broadcast(dev_id, {
+ console.error('Agent workflow error:', err.message);
+ broadcast({
type: 'error',
- message: '构建过程出错: ' + err.message
+ message: '铸渊代理遇到问题: ' + err.message
});
}
})();
diff --git a/persona-studio/brain/evolution-log.json b/persona-studio/brain/evolution-log.json
index a51724be..7d5a4016 100644
--- a/persona-studio/brain/evolution-log.json
+++ b/persona-studio/brain/evolution-log.json
@@ -1,7 +1,43 @@
{
"schema_version": "1.0",
"description": "系统进化日志 · 记录每次自进化事件",
- "last_updated": null,
- "total_events": 0,
- "events": []
-}
+ "last_updated": "2026-03-13T05:55:39.412Z",
+ "total_events": 2,
+ "events": [
+ {
+ "id": "EVT-1773380616767",
+ "type": "build_complete",
+ "description": "项目构建完成: project-1773380616766",
+ "metadata": {
+ "dev_id": "EXP-000",
+ "project": "project-1773380616766",
+ "files_count": 4,
+ "build_time_ms": 0,
+ "success": true,
+ "patterns_detected": [
+ "通用项目"
+ ]
+ },
+ "timestamp": "2026-03-13T05:43:36.767Z"
+ },
+ {
+ "id": "EVT-1773381339412",
+ "type": "agent_build_complete",
+ "description": "铸渊代理开发完成: project-1773381339411",
+ "metadata": {
+ "dev_id": "GUEST",
+ "project": "project-1773381339411",
+ "files_count": 4,
+ "build_time_ms": 1,
+ "success": true,
+ "brain_source": "local",
+ "patterns_detected": [
+ "个人博客"
+ ],
+ "developer_tech_level": null,
+ "developer_projects_total": 0
+ },
+ "timestamp": "2026-03-13T05:55:39.412Z"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/persona-studio/brain/memory/EXP-000/projects.json b/persona-studio/brain/memory/EXP-000/projects.json
new file mode 100644
index 00000000..01804274
--- /dev/null
+++ b/persona-studio/brain/memory/EXP-000/projects.json
@@ -0,0 +1,32 @@
+{
+ "dev_id": "EXP-000",
+ "projects": [
+ {
+ "name": "project-1773380616766",
+ "email": "test@test.com",
+ "contact": null,
+ "status": "completed",
+ "created_at": "2026-03-13T05:43:36.768Z",
+ "files": [
+ "index.html",
+ "style.css",
+ "main.js",
+ "README.md"
+ ]
+ },
+ {
+ "name": "project-1773380932239",
+ "email": "test@test.com",
+ "contact": null,
+ "status": "completed",
+ "created_at": "2026-03-13T05:48:52.239Z",
+ "files": [
+ "index.html",
+ "style.css",
+ "main.js",
+ "README.md"
+ ]
+ }
+ ],
+ "updated_at": "2026-03-13T05:48:52.239Z"
+}
\ No newline at end of file
diff --git a/persona-studio/brain/memory/GUEST/projects.json b/persona-studio/brain/memory/GUEST/projects.json
new file mode 100644
index 00000000..623b2b3b
--- /dev/null
+++ b/persona-studio/brain/memory/GUEST/projects.json
@@ -0,0 +1,32 @@
+{
+ "dev_id": "GUEST",
+ "projects": [
+ {
+ "name": "project-1773380932224",
+ "email": "test@test.com",
+ "contact": null,
+ "status": "completed",
+ "created_at": "2026-03-13T05:48:52.225Z",
+ "files": [
+ "index.html",
+ "style.css",
+ "main.js",
+ "README.md"
+ ]
+ },
+ {
+ "name": "project-1773381339411",
+ "email": "test@example.com",
+ "contact": null,
+ "status": "completed",
+ "created_at": "2026-03-13T05:55:39.412Z",
+ "files": [
+ "index.html",
+ "style.css",
+ "main.js",
+ "README.md"
+ ]
+ }
+ ],
+ "updated_at": "2026-03-13T05:55:39.412Z"
+}
\ No newline at end of file
diff --git a/persona-studio/brain/pattern-library.json b/persona-studio/brain/pattern-library.json
index 9741c176..9889a7e9 100644
--- a/persona-studio/brain/pattern-library.json
+++ b/persona-studio/brain/pattern-library.json
@@ -1,7 +1,32 @@
{
"schema_version": "1.0",
"description": "系统模式库 · 自动识别 · 每完成一个项目+每日聚合更新",
- "last_updated": null,
- "total_patterns": 0,
- "patterns": []
-}
+ "last_updated": "2026-03-13T05:55:39.412Z",
+ "total_patterns": 2,
+ "patterns": [
+ {
+ "name": "通用项目",
+ "frequency": 1,
+ "common_features": [],
+ "common_tech_stack": [
+ "HTML/CSS/JS"
+ ],
+ "avg_build_time": null,
+ "success_rate": 100,
+ "first_seen": "2026-03-13T05:43:36.767Z",
+ "last_seen": "2026-03-13T05:43:36.767Z"
+ },
+ {
+ "name": "个人博客",
+ "frequency": 1,
+ "common_features": [],
+ "common_tech_stack": [
+ "HTML/CSS/JS"
+ ],
+ "avg_build_time": 1,
+ "success_rate": 100,
+ "first_seen": "2026-03-13T05:55:39.412Z",
+ "last_seen": "2026-03-13T05:55:39.412Z"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/persona-studio/frontend/chat.js b/persona-studio/frontend/chat.js
index 44bbb726..2d263e98 100644
--- a/persona-studio/frontend/chat.js
+++ b/persona-studio/frontend/chat.js
@@ -640,28 +640,42 @@ async function confirmBuild() {
if (contact) sessionStorage.setItem('ps_build_contact', contact);
closeEmailModal();
- appendMessage('system', '🚀 开发任务已提交,完成后会发送到 ' + email);
+ appendMessage('system', '🌀 铸渊代理已启动,完成后会发送到 ' + email);
// 进入分屏模式
enterDevMode();
+ // 先连接 WebSocket(确保在 build 开始前建立连接,避免丢失进度消息)
+ connectPreviewWebSocket();
+
try {
- await fetch(API_BASE + '/api/ps/build/start', {
+ var buildRes = await fetch(API_BASE + '/api/ps/build/start', {
method: 'POST',
headers: authHeaders({ 'Content-Type': 'application/json' }),
body: JSON.stringify({
dev_id: DEV_ID,
email: email,
contact: contact,
- conversation: conversationHistory
+ conversation: conversationHistory,
+ api_base: USER_API_BASE,
+ api_key: USER_API_KEY,
+ model: SELECTED_MODEL
})
});
- } catch (_err) {
- appendMessage('system', '任务提交失败,请稍后再试');
- }
- // 连接 WebSocket 获取进度更新
- connectPreviewWebSocket();
+ if (!buildRes.ok) {
+ var errMsg = 'HTTP ' + buildRes.status + ' ' + buildRes.statusText;
+ try {
+ var errData = await buildRes.json();
+ if (errData.message) errMsg = errData.message;
+ } catch (_e) { /* use status text fallback */ }
+ appendMessage('system', '⚠️ 铸渊代理启动失败: ' + errMsg);
+ updatePreviewStatus('error', '启动失败');
+ }
+ } catch (_err) {
+ appendMessage('system', '⚠️ 任务提交失败,请检查网络连接后再试');
+ updatePreviewStatus('error', '网络错误');
+ }
}
/* ---- Dev Mode: Split Screen ---- */