Commit a128a2ff625ca4ee20000cdc7af63f01f8df2829

Authored by yibo
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.
data/system/agents/master/agent.md
... ... @@ -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 89 ```bash
90 90 # 1. 一键创建公å¸ç©ºå£³
91 91 node bin/lemon.js company create --id <å…¬å¸ID> --name "<å…¬å¸åç§°>" --desc "<业务æè¿°ï¼Œè¶Šè¯¦ç»†è¶Šå¥½>"
92 92  
93   -# 2. ä¸ºè¯¥é¦–å®¶å…¬å¸æ‰‹åŠ¨æ‹›è˜ CEO(将其招入公å¸ï¼‰
  93 +# 2. ä¸ºå…¬å¸æ‰‹åŠ¨æ‹›è˜å›¢é˜Ÿï¼ˆä»Ž Template 库雇佣)
94 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 19 // POST /api/company/create
20 20 router.post('/create', async (req, res) => {
21 21 try {
22   - const { id, name, description, skipBootstrap } = req.body;
  22 + const { id, name, description } = req.body;
23 23 if (!id || !name) return res.status(400).json({ error: 'id 和 name 为必填项' });
24 24  
25 25 // 校验 id 格式 (小写字母、数字、-)
... ... @@ -29,64 +29,7 @@ router.post(&#39;/create&#39;, async (req, res) =&gt; {
29 29  
30 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 33 } catch (err) {
91 34 res.status(400).json({ error: err.message });
92 35 }
... ...
web/src/components/AppNav.vue
... ... @@ -5,8 +5,8 @@
5 5 <span class="nav-title">LemonBoss</span>
6 6 </div>
7 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 10 </router-link>
11 11  
12 12 <router-link to="/templates" class="nav-link" :class="{ active: $route.path.startsWith('/templates') }">
... ...
web/src/views/AgentChat.vue
... ... @@ -5,10 +5,10 @@
5 5  
6 6 <!-- 第1列: Agent 列表 (始终可见) -->
7 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 9 <div class="agent-list">
10 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 12 <div
13 13 v-for="a in agents" :key="a.id"
14 14 class="agent-card" :class="{ active: agentId === a.id }"
... ... @@ -255,7 +255,12 @@ const groupedAgents = computed(() =&gt; {
255 255 agentList.value.forEach(a => {
256 256 const comp = a.companyId || 'system'
257 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 265 if (!groups[comp]) groups[comp] = []
261 266 groups[comp].push(a)
... ...