feat: 铸渊代理开发工作流 · 壳-核分离架构 (Core Brain + Agent)
- 新建 agent-workflow.js: 铸渊核心大脑唤醒 + 铸渊代理执行的壳-核分离架构 - Phase 1: 核心大脑加载开发者记忆/画像/项目/知识库/模式库,深度分析意图 - Phase 2: 代理接收核心大脑的开发计划,逐步执行代码生成 - Phase 3: 核心大脑自进化(知识提取+模式识别+画像学习+进化日志) - 更新 build.js: 支持 GUEST 模式、接收用户 API 凭证、使用 Agent 工作流 - 更新 chat.js: 传递用户 API 凭证、修复 WebSocket 时序竞态、增强错误反馈 - 更新 .gitignore: 排除 workspace 生成文件 - 更新核心大脑记忆: 记录本次恢复事件 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
9f29eed97d
commit
0fb07ab66a
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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-*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,756 @@
|
|||
/**
|
||||
* persona-studio · 铸渊代理开发工作流引擎(壳-核分离架构)
|
||||
*
|
||||
* 架构设计:
|
||||
* 核 = 铸渊核心大脑(Core Brain)
|
||||
* ↳ 加载开发者记忆、画像、项目历史、知识库、模式库
|
||||
* ↳ 深度分析开发者真实意图
|
||||
* ↳ 生成结构化开发计划
|
||||
* 壳 = 铸渊代理(Agent Executor)
|
||||
* ↳ 接收核心大脑推送的开发计划
|
||||
* ↳ 逐步执行代码生成
|
||||
* ↳ 广播进度给前端
|
||||
* ↳ 完成后回传核心大脑做自进化
|
||||
*
|
||||
* 流程:
|
||||
* 用户点击「我要开发」
|
||||
* → Agent 唤醒核心大脑
|
||||
* → 核心大脑:加载全部上下文 → 分析意图 → 生成开发计划
|
||||
* → Agent:接收计划 → 逐步执行 → 广播进度
|
||||
* → 核心大脑:知识提取 + 模式更新 + 画像学习 + 进化日志
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const https = require('https');
|
||||
const http = require('http');
|
||||
|
||||
// ── 核心大脑模块 ──
|
||||
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, 4000) }
|
||||
],
|
||||
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('.')) 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
|
||||
};
|
||||
|
|
@ -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 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
|
||||
});
|
||||
|
||||
// 记录项目
|
||||
// 记录项目(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
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"schema_version": "1.0",
|
||||
"description": "系统进化日志 · 记录每次自进化事件",
|
||||
"last_updated": "2026-03-13T05:43:36.767Z",
|
||||
"total_events": 1,
|
||||
"last_updated": "2026-03-13T05:55:39.412Z",
|
||||
"total_events": 2,
|
||||
"events": [
|
||||
{
|
||||
"id": "EVT-1773380616767",
|
||||
|
|
@ -19,6 +19,25 @@
|
|||
]
|
||||
},
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -13,7 +13,20 @@
|
|||
"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:43:36.768Z"
|
||||
"updated_at": "2026-03-13T05:48:52.239Z"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"schema_version": "1.0",
|
||||
"description": "系统模式库 · 自动识别 · 每完成一个项目+每日聚合更新",
|
||||
"last_updated": "2026-03-13T05:43:36.767Z",
|
||||
"total_patterns": 1,
|
||||
"last_updated": "2026-03-13T05:55:39.412Z",
|
||||
"total_patterns": 2,
|
||||
"patterns": [
|
||||
{
|
||||
"name": "通用项目",
|
||||
|
|
@ -15,6 +15,18 @@
|
|||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -640,28 +640,39 @@ 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 errData = {};
|
||||
try { errData = await buildRes.json(); } catch (_e) { /* ignore */ }
|
||||
appendMessage('system', '⚠️ 铸渊代理启动失败: ' + (errData.message || 'HTTP ' + buildRes.status));
|
||||
updatePreviewStatus('error', '启动失败');
|
||||
}
|
||||
} catch (_err) {
|
||||
appendMessage('system', '⚠️ 任务提交失败,请检查网络连接后再试');
|
||||
updatePreviewStatus('error', '网络错误');
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Dev Mode: Split Screen ---- */
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
# project-1773380616766
|
||||
|
||||
## 需求描述
|
||||
Make a hello world page
|
||||
|
||||
> 模板项目(AI 模型尚未配置,请管理员设置 MODEL_API_KEY)
|
||||
|
||||
生成时间:2026-03-13T05:43:36.766Z
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>project-1773380616766</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>🌊 project-1773380616766</h1>
|
||||
<p>由光湖 Persona Studio 生成</p>
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1 +0,0 @@
|
|||
console.log("Project initialized by Persona Studio");
|
||||
|
|
@ -1 +0,0 @@
|
|||
body { font-family: sans-serif; padding: 2rem; }
|
||||
Loading…
Reference in New Issue