Commit a128a2ff625ca4ee20000cdc7af63f01f8df2829
1 parent
cea3e9b4
refactor: Update company creation to act as shell and rename MasterBot to System Agents
- Updated `POST /api/company/create` to create an empty shell without bootstrapping CXO/HR automatically. - Updated `master/agent.md` instructions so Master Agent handles all Template library hirings. - Renamed 'MasterBot' navigation link to 'System Agents'. - Updated AgentChat sidebar to only show System Agents when accessed via the System Agents link.
Showing
4 changed files
with
29 additions
and
90 deletions
data/system/agents/master/agent.md
| @@ -76,42 +76,33 @@ node bin/lemon.js task dispatch --from master --to agent-creator --task "创建ä | @@ -76,42 +76,33 @@ node bin/lemon.js task dispatch --from master --to agent-creator --task "创建ä | ||
| 76 | 76 | ||
| 77 | ## æ£ç¡®çš„æ“ä½œæµæ–¹å¼ï¼ˆèŒƒä¾‹ï¼‰ | 77 | ## æ£ç¡®çš„æ“ä½œæµæ–¹å¼ï¼ˆèŒƒä¾‹ï¼‰ |
| 78 | 78 | ||
| 79 | -### 🚀 创建公å¸ï¼ˆBrain to Cerebellum 从大脑到å°è„‘的进阶过程ï¼ï¼‰ | ||
| 80 | -我们的框架原则是:**系统ä¸ä¸ç¡¬ç¼–ç **自动部署 CEOã€CTO ç‰éª¨å¹²ï¼Œä¸€åˆ‡éƒ½åº”当通过多级 Agent çš„æ€è€ƒä¸Žå§”派链æ¡å®Œæˆï¼è¿™å°±å¦‚åŒä»Žâ€œå¤§è„‘â€åˆ°â€œå°è„‘â€çš„肌肉记忆建立。 | 79 | +### 🚀 创建公å¸ä¸Žæ‹›è˜å‘˜å·¥ï¼ˆä»Žå»ºå£³åˆ°ç»„建团队) |
| 80 | +我们的框架原则是:**å…¬å¸åˆ›å»ºæ—¶åªæ˜¯ä¸€ä¸ªâ€œç©ºå£³â€**。系统ä¸ä¸ç¡¬ç¼–ç 自动部署 CEOã€CTO ç‰éª¨å¹²ã€‚ | ||
| 81 | +为了é¿å…由下级 Agent(如 CEO/HR)去执行招è˜é€ æˆçš„å·¨å¤§èµ„æºæµªè´¹ï¼Œ**所有从 Template åº“ä¸æŒ‘选并雇佣 Agent 到公å¸å›¢é˜Ÿçš„工作,必须由 Master Agent æ ¹æ®è€æ¿ï¼ˆç”¨æˆ·ï¼‰çš„æŒ‡ä»¤äº²åŠ›äº²ä¸ºå®Œæˆã€‚** | ||
| 81 | 82 | ||
| 82 | -å½“ç”¨æˆ·è¦æ±‚åˆ›å»ºä¸€å®¶æ–°å…¬å¸æ—¶ï¼Œä½ (Master 作为“第一大脑â€ï¼‰å¿…须自主完æˆä»¥ä¸‹åˆå§‹åŒ–: | ||
| 83 | -1. **构建公å¸éª¨æž¶**:调用 `company create` 创建åªåŒ…嫿¡†æž¶ï¼ˆå’Œåº•层元 Agent)的空壳。 | ||
| 84 | -2. **ä¸»åŠ¨æ‹›è˜æ ¸å¿ƒç»Ÿå¸…**:公å¸å£³åé‡Œç›®å‰æ²¡æœ‰ä¸šåŠ¡å‘˜å·¥ã€‚ä½ å¿…é¡»é€šè¿‡ `company hire` 从模æ¿åº“䏿‹›å‹Ÿç¬¬ä¸€å业务骨干:**CEO**。 | ||
| 85 | -3. **下达战略并å‘下委派**:通过 `task dispatch` 给新招募的 CEO å‘逿ˆ˜ç•¥å¯åŠ¨ä»¤ï¼Œå‘Šè¯‰ä»–å…¬å¸çš„ä¸šåŠ¡ç›®æ ‡ï¼Œå¹¶**è¦æ±‚ CEO 自行决定并去招募 HR 以扩建组织架构**。 | ||
| 86 | -4. **ä¼ é€’ä¸Žè§‚å¯Ÿ**:CEO 收到命令åŽï¼ˆä»–的大脑开始æ€è€ƒï¼‰ï¼Œä¼šåŽ»æ‹›å‹Ÿ HR(HR éšåŽåŽ»æ‹›å‹Ÿå‘˜å·¥ï¼‰ï¼Œä½ åªéœ€è¦é™é™è§‚å¯Ÿè¿™å¼ ç½‘ç»œå‘ä¸‹å±‚çº§ä¼ é€’ã€‚ | 83 | +å½“ç”¨æˆ·è¦æ±‚åˆ›å»ºä¸€å®¶æ–°å…¬å¸æ—¶ï¼Œä½ 必须: |
| 84 | +1. **构建公å¸ç©ºå£³**:调用 `company create` 创建åªåŒ…嫿¡†æž¶çš„空壳。 | ||
| 85 | +2. **ä¸»åŠ¨æ‹›è˜æ ¸å¿ƒå›¢é˜Ÿ**ï¼šæ ¹æ®ç”¨æˆ·çš„ä¸šåŠ¡éœ€æ±‚é¢„åˆ¤ï¼Œæˆ–è€…æ ¹æ®ç”¨æˆ·çš„æ˜Žç¡®æŒ‡ä»¤ï¼Œä½¿ç”¨ `company hire` 从模æ¿åº“䏿‹›å‹Ÿéœ€è¦çš„业务骨干(如 CEO, CTO, COO, HR,乃至具体的业务专家)。 | ||
| 86 | +3. **下达战略说明**:通过 `task dispatch` 给新招募的 CEO å‘逿ˆ˜ç•¥å¯åŠ¨ä»¤ï¼Œå‘Šè¯‰ä»–å…¬å¸çš„ä¸šåŠ¡ç›®æ ‡ï¼Œå³å¯å¼€å§‹å·¥ä½œã€‚注æ„:**ä¸è¦**è¦æ±‚ CEO 去招募员工,明确告诉 CEO 团队é…置由 Master/è€æ¿ 负责。 | ||
| 87 | 87 | ||
| 88 | -**åˆ›å»ºæ–°å…¬å¸æ—¶ï¼Œä½ å¿…é¡»æŒ‰é¡ºåºæ‰§è¡Œä»¥ä¸‹ä¸‰æ¥åŠ¨ä½œï¼š** | 88 | +**例如,当全æƒå§”æ‰˜ä½ åˆ›å»ºå¹¶é…ç½®ä¸€ä¸ªå…¬å¸æ—¶ï¼Œä½ å¯ä»¥æ‰§è¡Œï¼š** |
| 89 | ```bash | 89 | ```bash |
| 90 | # 1. 一键创建公å¸ç©ºå£³ | 90 | # 1. 一键创建公å¸ç©ºå£³ |
| 91 | node bin/lemon.js company create --id <å…¬å¸ID> --name "<å…¬å¸åç§°>" --desc "<业务æè¿°ï¼Œè¶Šè¯¦ç»†è¶Šå¥½>" | 91 | node bin/lemon.js company create --id <å…¬å¸ID> --name "<å…¬å¸åç§°>" --desc "<业务æè¿°ï¼Œè¶Šè¯¦ç»†è¶Šå¥½>" |
| 92 | 92 | ||
| 93 | -# 2. ä¸ºè¯¥é¦–å®¶å…¬å¸æ‰‹åŠ¨æ‹›è˜ CEO(将其招入公å¸ï¼‰ | 93 | +# 2. ä¸ºå…¬å¸æ‰‹åŠ¨æ‹›è˜å›¢é˜Ÿï¼ˆä»Ž Template 库雇佣) |
| 94 | node bin/lemon.js company hire --id <å…¬å¸ID> --role ceo --type cxo --name "首叿‰§è¡Œå®˜" | 94 | node bin/lemon.js company hire --id <å…¬å¸ID> --role ceo --type cxo --name "首叿‰§è¡Œå®˜" |
| 95 | +node bin/lemon.js company hire --id <å…¬å¸ID> --role cto --type cxo --name "é¦–å¸æŠ€æœ¯å®˜" | ||
| 96 | +# (...按需雇佣其他 Agent) | ||
| 95 | 97 | ||
| 96 | -# 3. 委派 CEO å¼€å§‹å·¥ä½œï¼Œå¹¶æ˜Žç¡®è¦æ±‚其开始组建组织(一定è¦åŠ ä¸Šæ£ç¡®çš„å…¬å¸å‰ç¼€ï¼‰ | ||
| 97 | -node bin/lemon.js task dispatch --from master --to <å…¬å¸ID>:ceo --task "ä½ å·²è¢«ä»»å‘½ä¸ºå…¬å¸ CEO,本公å¸ä¸»è¥ï¼š<业务æè¿°>ã€‚è¯·ä½ ç«‹åˆ»å¼€å§‹åˆ¶å®šå…¬å¸æˆ˜ç•¥ï¼Œæ¢³ç† SOP,并决定是å¦è¦æ‹›å‹Ÿ HR 给公å¸ç»„建团队。" --priority P0 | 98 | +# 3. 委派 CEO 开始工作(一定è¦åŠ ä¸Šæ£ç¡®çš„å…¬å¸å‰ç¼€ï¼‰ |
| 99 | +node bin/lemon.js task dispatch --from master --to <å…¬å¸ID>:ceo --task "ä½ å·²è¢«ä»»å‘½ä¸ºå…¬å¸ CEO,本公å¸ä¸»è¥ï¼š<业务æè¿°>ã€‚è¯·ç«‹åˆ»åˆ¶å®šå…¬å¸æˆ˜ç•¥å’Œ SOP。注æ„:人员招è˜ç”± Master 集ä¸ç®¡ç†ï¼Œä½ åªéœ€ä¸“注于业务æµç¨‹çš„æ¢³ç†ä¸Žå·¥ä½œæµåˆ†è§£ã€‚" --priority P0 | ||
| 98 | ``` | 100 | ``` |
| 99 | 101 | ||
| 100 | -**âš ï¸ å…³äºŽå…¬å¸ ID/å称的自主决ç–规则:** | ||
| 101 | -- 如果用户说"创建一家AI新闻公å¸"但没给ID → **ä½ å¿…é¡»è‡ªä¸»å†³å®š**一个åˆç†çš„英文ID(如 `ainews`)和å称(如 `AI News Inc.`),然åŽ**立刻执行**,ç»ä¸è¦åå¤è¿½é—®ç”¨æˆ·ï¼ | ||
| 102 | -- 如果用户给了明确的ID → 直接使用。 | ||
| 103 | -- æè¿°å°½é‡è¯¦ç»†ï¼Œå› 为 CEO 的战略分æžè´¨é‡å–决于æè¿°çš„丰富程度。 | ||
| 104 | - | ||
| 105 | -**创建åŽçš„事件æµä¼ 导图谱:** | ||
| 106 | -``` | ||
| 107 | -用户å‘出建公å¸è¯·æ±‚ → Master (ä½ ) æ€è€ƒ "该招个CEO管ç†" | ||
| 108 | - → Master 执行 company create 创建空间 → Master 执行 hire æ‹›è˜CEO → Master ç»™ CEO å‘任务 | ||
| 109 | - → CEO æ€è€ƒ "我需è¦ç»„织" → CEO 委派 HR 去招募 | ||
| 110 | - → HR 招入 CTO / 专家执行层 | ||
| 111 | - → CTO æŽ¥ç®¡æµæ°´çº¿... | ||
| 112 | -``` | ||
| 113 | - | ||
| 114 | -### æ£ç¡®å›žå¤æ¨¡å¼ | 102 | +**âš ï¸ æ‹›è˜ä¸Žç»„队的原则:** |
| 103 | +- 所有的 `hire` æ“作本质上是从 `Template` 库å¤åˆ¶æŒ‡å®šçš„æ¨¡æ¿åˆ°å…·ä½“å…¬å¸ä¸ï¼Œå¿…é¡»ç”±ä½ ï¼ˆMaster)æ¥åŒ…办。 | ||
| 104 | +- å¦‚æžœç”¨æˆ·åªæ˜¯è¯´"帮我把 xxx 招到 yyy å…¬å¸"ï¼Œä½ ç›´æŽ¥è°ƒç”¨ä¸€æ¬¡ `company hire` å³å¯ã€‚ | ||
| 105 | +- å¦‚æžœç”¨æˆ·è®©ä½ å…¨æƒç»„å»ºç‰¹å®šä¸šåŠ¡çº¿ï¼Œä½ åº”è¯¥**自主决定**需è¦å“ªäº›æ¨¡æ¿ï¼Œå¹¶ç›´æŽ¥æ‰¹é‡æ‰§è¡Œ `hire`,ä¸è¦åå¤è¿½é—®ã€‚ | ||
| 115 | ``` | 106 | ``` |
| 116 | 用户: 让下级干完活 | 107 | 用户: 让下级干完活 |
| 117 | ✅ æ£ç¡®å›žå¤: | 108 | ✅ æ£ç¡®å›žå¤: |
server/routes/company.js
| @@ -19,7 +19,7 @@ const scheduleService = new ScheduleService(); | @@ -19,7 +19,7 @@ const scheduleService = new ScheduleService(); | ||
| 19 | // POST /api/company/create | 19 | // POST /api/company/create |
| 20 | router.post('/create', async (req, res) => { | 20 | router.post('/create', async (req, res) => { |
| 21 | try { | 21 | try { |
| 22 | - const { id, name, description, skipBootstrap } = req.body; | 22 | + const { id, name, description } = req.body; |
| 23 | if (!id || !name) return res.status(400).json({ error: 'id 和 name 为必填项' }); | 23 | if (!id || !name) return res.status(400).json({ error: 'id 和 name 为必填项' }); |
| 24 | 24 | ||
| 25 | // 校验 id 格式 (小写字母、数字、-) | 25 | // 校验 id 格式 (小写字母、数字、-) |
| @@ -29,64 +29,7 @@ router.post('/create', async (req, res) => { | @@ -29,64 +29,7 @@ router.post('/create', async (req, res) => { | ||
| 29 | 29 | ||
| 30 | const company = companyService.create({ id, name, description }); | 30 | const company = companyService.create({ id, name, description }); |
| 31 | 31 | ||
| 32 | - // ── Phase A: Company Bootstrap 自举 ── | ||
| 33 | - // 读取 _company_bootstrap/manifest.json,自动部署核心骨干 | ||
| 34 | - const bootstrapResults = []; | ||
| 35 | - if (!skipBootstrap) { | ||
| 36 | - const path = require('path'); | ||
| 37 | - const fs = require('fs'); | ||
| 38 | - const manifestPath = path.resolve(__dirname, '../../data/system/templates/_company_bootstrap/manifest.json'); | ||
| 39 | - | ||
| 40 | - if (fs.existsSync(manifestPath)) { | ||
| 41 | - const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')); | ||
| 42 | - const agents = manifest.bootstrap_agents || []; | ||
| 43 | - | ||
| 44 | - for (const agentDef of agents) { | ||
| 45 | - try { | ||
| 46 | - const hireResult = companyService.hire(id, agentDef.role, { | ||
| 47 | - type: agentDef.type, | ||
| 48 | - name: agentDef.name, | ||
| 49 | - }); | ||
| 50 | - bootstrapResults.push({ role: agentDef.role, status: hireResult.status }); | ||
| 51 | - console.log(`[Bootstrap] ✅ ${id} 自动部署 ${agentDef.role} → ${hireResult.status}`); | ||
| 52 | - } catch (err) { | ||
| 53 | - bootstrapResults.push({ role: agentDef.role, status: 'error', error: err.message }); | ||
| 54 | - console.error(`[Bootstrap] ❌ ${id} 部署 ${agentDef.role} 失败:`, err.message); | ||
| 55 | - } | ||
| 56 | - } | ||
| 57 | - | ||
| 58 | - // 自动启动公司 + 激活心跳 | ||
| 59 | - companyService.update(id, { status: 'running', heartbeat: { enabled: true } }); | ||
| 60 | - | ||
| 61 | - // 自动向 CEO 下达启动令 (异步不阻塞) | ||
| 62 | - if (manifest.auto_dispatch_to_ceo && description) { | ||
| 63 | - const config = require('../config'); | ||
| 64 | - const PORT = config.port || 3000; | ||
| 65 | - const startupPrompt = `${manifest.ceo_startup_prompt || '请执行你的五步战略工作流'}\n\n公司名称: ${name}\n公司描述/业务需求: ${description}`; | ||
| 66 | - | ||
| 67 | - setTimeout(() => { | ||
| 68 | - const http = require('http'); | ||
| 69 | - const postData = JSON.stringify({ | ||
| 70 | - from: 'master', to: `${id}:ceo`, | ||
| 71 | - task: startupPrompt, priority: 'P0', autoExecute: true, | ||
| 72 | - }); | ||
| 73 | - const reqOpts = { | ||
| 74 | - hostname: '127.0.0.1', port: PORT, path: '/api/agent/task/dispatch', | ||
| 75 | - method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) }, | ||
| 76 | - }; | ||
| 77 | - const r = http.request(reqOpts, () => {}); | ||
| 78 | - r.on('error', e => console.error('[Bootstrap] CEO dispatch 失败:', e.message)); | ||
| 79 | - r.write(postData); | ||
| 80 | - r.end(); | ||
| 81 | - console.log(`[Bootstrap] 🚀 已向 ${id}:ceo 发送启动战略指令`); | ||
| 82 | - }, 2000); | ||
| 83 | - } | ||
| 84 | - | ||
| 85 | - console.log(`[Bootstrap] 🏢 公司 ${id} 已完成自举,部署了 ${bootstrapResults.length} 名核心骨干`); | ||
| 86 | - } | ||
| 87 | - } | ||
| 88 | - | ||
| 89 | - res.json({ success: true, company, bootstrap: bootstrapResults }); | 32 | + res.json({ success: true, company, message: '公司已创建,当前为没有员工的空壳公司。请通知 MasterBot 从 Template 库中雇佣 Agent 到你的团队中。' }); |
| 90 | } catch (err) { | 33 | } catch (err) { |
| 91 | res.status(400).json({ error: err.message }); | 34 | res.status(400).json({ error: err.message }); |
| 92 | } | 35 | } |
web/src/components/AppNav.vue
| @@ -5,8 +5,8 @@ | @@ -5,8 +5,8 @@ | ||
| 5 | <span class="nav-title">LemonBoss</span> | 5 | <span class="nav-title">LemonBoss</span> |
| 6 | </div> | 6 | </div> |
| 7 | <div class="nav-links"> | 7 | <div class="nav-links"> |
| 8 | - <router-link to="/agent/agent-creator" class="nav-link" :class="{ active: $route.path.startsWith('/agent') }"> | ||
| 9 | - <span>🤖</span> MasterBot | 8 | + <router-link to="/agent/master" class="nav-link" :class="{ active: $route.path.startsWith('/agent') }"> |
| 9 | + <span>🤖</span> System Agents | ||
| 10 | </router-link> | 10 | </router-link> |
| 11 | 11 | ||
| 12 | <router-link to="/templates" class="nav-link" :class="{ active: $route.path.startsWith('/templates') }"> | 12 | <router-link to="/templates" class="nav-link" :class="{ active: $route.path.startsWith('/templates') }"> |
web/src/views/AgentChat.vue
| @@ -5,10 +5,10 @@ | @@ -5,10 +5,10 @@ | ||
| 5 | 5 | ||
| 6 | <!-- 第1列: Agent 列表 (始终可见) --> | 6 | <!-- 第1列: Agent 列表 (始终可见) --> |
| 7 | <aside class="agent-sidebar"> | 7 | <aside class="agent-sidebar"> |
| 8 | - <div class="col-header">🏢 Agents</div> | 8 | + <div class="col-header">{{ $route.params.id ? '🏢 Agents' : '💻 System Agents' }}</div> |
| 9 | <div class="agent-list"> | 9 | <div class="agent-list"> |
| 10 | <template v-for="(agents, compId) in groupedAgents" :key="compId"> | 10 | <template v-for="(agents, compId) in groupedAgents" :key="compId"> |
| 11 | - <div class="agent-group-title">{{ compId === 'system' ? '💻 系统 Agent' : `🏢 ${compId}` }}</div> | 11 | + <div class="agent-group-title" v-if="$route.params.id">{{ compId === 'system' ? '💻 系统 Agent' : `🏢 ${compId}` }}</div> |
| 12 | <div | 12 | <div |
| 13 | v-for="a in agents" :key="a.id" | 13 | v-for="a in agents" :key="a.id" |
| 14 | class="agent-card" :class="{ active: agentId === a.id }" | 14 | class="agent-card" :class="{ active: agentId === a.id }" |
| @@ -255,7 +255,12 @@ const groupedAgents = computed(() => { | @@ -255,7 +255,12 @@ const groupedAgents = computed(() => { | ||
| 255 | agentList.value.forEach(a => { | 255 | agentList.value.forEach(a => { |
| 256 | const comp = a.companyId || 'system' | 256 | const comp = a.companyId || 'system' |
| 257 | // If we are in a company context, filter out other companies | 257 | // If we are in a company context, filter out other companies |
| 258 | - if (route.params.id && comp !== route.params.id) return | 258 | + if (route.params.id) { |
| 259 | + if (comp !== route.params.id && comp !== 'system') return | ||
| 260 | + } else { | ||
| 261 | + // If we are in the System Agents context, ONLY show system agents | ||
| 262 | + if (comp !== 'system') return | ||
| 263 | + } | ||
| 259 | 264 | ||
| 260 | if (!groups[comp]) groups[comp] = [] | 265 | if (!groups[comp]) groups[comp] = [] |
| 261 | groups[comp].push(a) | 266 | groups[comp].push(a) |