This commit is contained in:
Awen 2026-03-13 14:49:43 +08:00
commit 0ab3c09016
18 changed files with 1413 additions and 79 deletions

View File

@ -0,0 +1,54 @@
name: "📡 提交系统日志 / 提问"
description: "做完了?提交你的 SYSLOG。有问题在这里提问。"
title: "BC-XXX-XXXSYSLOG"
labels: ["syslog", "pending"]
assignees: []
body:
- type: markdown
attributes:
value: |
## 📡 SYSLOG 自助提交 / 广播提问
> 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。
>
> 有问题?把问题粘贴进去,填上邮箱,点提交。解答会发到你邮箱里。
**标题格式**`BC-XXX-XXXSYSLOG` 或 `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

View File

@ -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",

View File

@ -1,7 +1,7 @@
# 冰朔主控神经系统 · 核心主控大脑 v1.0
> 本文件为冰朔主控神经系统的总控脑文件。
> 最后编译时间2026-03-13T04:49:20.482Z
> 最后编译时间2026-03-13T06:03:28.752Z
---
@ -56,7 +56,7 @@
### 仓库统计
- 功能模块10 个
- Workflow36
- Workflow37
---
@ -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 | 前后端结构存在,端到端对话链路待验证 |

View File

@ -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",

View File

@ -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",

View File

@ -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"
],

View File

@ -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 |

View File

@ -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",

View File

@ -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 页面 IDv4.0 协议动态注入)
# PORTRAIT_DB_ID 开发者动态画像库数据库 IDv4.0 协议动态注入)
# FINGERPRINT_DB_ID 模块指纹注册表数据库 IDv4.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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\n/g, '<br>');
const html = [
'<div style=\"font-family:sans-serif;max-width:700px;margin:0 auto;padding:24px;background:#0f172a;color:#e2e8f0;border-radius:12px\">',
'<div style=\"text-align:center;padding:16px 0;border-bottom:1px solid #334155\">',
'<h2 style=\"color:#60a5fa;margin:0\">🌊 光湖系统 · 自动通知</h2>',
'<p style=\"color:#94a3b8;font-size:14px;margin:8px 0 0\">HoloLake · 人格语言操作系统</p>',
'</div>',
'<div style=\"padding:20px 0\">',
'<p style=\"color:#22d3ee;font-weight:bold\">📡 ' + broadcastId + '</p>',
'<div style=\"background:#1e293b;padding:16px;border-radius:8px;margin:12px 0;line-height:1.8\">' + resultHtml + '</div>',
'</div>',
'<div style=\"border-top:1px solid #334155;padding:16px 0;text-align:center\">',
'<a href=\"https://github.com/qinfendebingshuo/guanghulab\" style=\"display:inline-block;padding:8px 20px;background:linear-gradient(135deg,#3b82f6,#22d3ee);color:#fff;text-decoration:none;border-radius:6px;font-weight:600\">↩ 回到仓库继续开发</a>',
'<p style=\"color:#64748b;font-size:12px;margin:12px 0 0\">🌀 铸渊 · 代码守护人格体 · 自动发送</p>',
'</div>',
'</div>'
].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);
}

1
.gitignore vendored
View File

@ -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-*

View File

@ -53,12 +53,12 @@
<div align="center">
[![提交系统日志](https://img.shields.io/badge/📡_提交系统日志-点这里-blue?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/discussions/new?category=📡+SYSLOG+提交区)
[![遇到问题](https://img.shields.io/badge/❓_遇到问题-点这里提问-green?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/discussions/new?category=📡+SYSLOG+提交区)
[![提交系统日志](https://img.shields.io/badge/📡_提交系统日志-点这里-blue?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/issues/new?template=syslog-submit.yml)
[![遇到问题](https://img.shields.io/badge/❓_遇到问题-点这里提问-green?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/issues/new?template=dev-question.yml)
> 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。
> 做完了?点蓝色按钮,把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。
>
> 有问题?同一个入口,选「提问」,问题解答也发到你邮箱里
> 有问题?点绿色按钮,填写问题描述,铸渊会自动回答你
</div>
@ -92,21 +92,21 @@
<!-- BINGSHUO_BULLETIN_START -->
| 时间 | 检查项 | 状态 |
|------|--------|------|
| 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 | ✅ 每日巡检 ✅ 通过 | 冰朔 |
<!-- BINGSHUO_BULLETIN_END -->
### 🤖 铸渊自动提醒
@ -128,9 +128,9 @@
<!-- COLLABORATOR_BULLETIN_START -->
| 时间 | 合作者 | 模块 | 状态 |
|------|--------|------|------|
| 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 | `—/` | 🔵 已更新 |
<!-- COLLABORATOR_BULLETIN_END -->
### 🤖 铸渊自动提醒 · 合作者

View File

@ -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 APIOpenAI 兼容格式
*/
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 [
'<!DOCTYPE html>',
'<html lang="zh-CN">',
'<head>',
' <meta charset="UTF-8">',
' <meta name="viewport" content="width=device-width, initial-scale=1.0">',
' <title>' + (plan.project_name || '项目') + '</title>',
' <link rel="stylesheet" href="style.css">',
'</head>',
'<body>',
' <div class="container">',
' <h1>🌊 ' + desc + '</h1>',
' <p>由光湖 Persona Studio · 铸渊核心大脑 + 铸渊代理 协同开发</p>',
' <p class="design-note">设计风格:' + designNotes + '</p>',
' </div>',
' <script src="main.js"></script>',
'</body>',
'</html>'
].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
};

View File

@ -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,34 +48,50 @@ router.post('/start', async (req, res) => {
});
}
// 防止 header injectionAPI 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
});
// 记录项目
// 记录项目GUEST 也记录,方便追踪)
try {
memoryManager.addProject(dev_id, {
name: result.projectName || 'untitled',
email: email,
@ -77,34 +101,41 @@ router.post('/start', async (req, res) => {
files: result.files || []
});
// 自动提取知识
// 自动提取知识(仅注册开发者)
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
});
}
})();

View File

@ -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"
}
]
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}
]
}

View File

@ -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 ---- */