test-registry.js 4.76 KB
#!/usr/bin/env node

/**
 * 测试 AgentRegistry + AgentBus — 完整的多 Agent 协作流程
 *
 * 模拟场景:
 *   1. 创建 Master + CEO + 编剧部 三个 Agent
 *   2. CEO 给编剧部分派任务 (消息通讯)
 *   3. 编剧部汇报结果 (消息回流)
 *   4. 查看组织架构树
 *   5. 修改编剧部的 agent.md (热更新)
 *   6. 销毁编剧部 (递归删除)
 *
 * 用法: node packages/agent-core/test-registry.js
 */

import { AgentBus } from './AgentBus.js';
import { AgentRegistry } from './AgentRegistry.js';
import { rm } from 'node:fs/promises';

const TEST_DIR = './data/agents-test';

async function main() {
  console.log('═══════════════════════════════════════');
  console.log('  LemonBoss Registry + Bus 集成测试');
  console.log('═══════════════════════════════════════\n');

  // 初始化 (不用 SQLite, 纯内存)
  const bus = new AgentBus();
  const registry = new AgentRegistry({ agentsDir: TEST_DIR, bus });

  // 监控消息流
  const messageLog = [];
  bus.on('message', (msg) => {
    messageLog.push(msg);
    console.log(`   📨 [${msg.method}] ${msg.from} → ${msg.to}`);
  });

  // ── Step 1: 创建三个 Agent ──

  console.log('1️⃣  创建组织架构\n');

  const master = await registry.create({
    id: 'master-001',
    type: 'master',
    name: 'Lemon Master',
  });
  console.log(`   ✅ Master : ${master.id}`);

  const ceo = await registry.create({
    id: 'cxo-ceo-001',
    type: 'cxo',
    name: 'Lemon CEO',
    parentId: 'master-001',
  });
  console.log(`   ✅ CEO    : ${ceo.id}`);

  const dramatist = await registry.create({
    id: 'role-dramatist-001',
    type: 'role',
    name: '编剧部',
    parentId: 'cxo-ceo-001',
  });
  console.log(`   ✅ 编剧部 : ${dramatist.id}\n`);

  // ── Step 2: 查看所有 Agent ──

  console.log('2️⃣  查看所有 Agent\n');
  const allAgents = registry.list();
  for (const a of allAgents) {
    console.log(`   ${a.type.padEnd(7)} | ${a.id.padEnd(25)} | ${a.status}`);
  }
  console.log();

  // ── Step 3: 查看组织架构树 ──

  console.log('3️⃣  组织架构树\n');
  const tree = registry.getOrgTree();
  printTree(tree, '   ');
  console.log();

  // ── Step 4: CEO 给编剧部分派任务 ──

  console.log('4️⃣  CEO → 编剧部: 分派任务\n');
  const task = bus.assignTask('cxo-ceo-001', 'role-dramatist-001', {
    description: '创作一个都市爱情互动短剧剧本',
    deadline: '2026-03-25',
    priority: 'high',
  });
  console.log(`   任务ID: ${task.id}\n`);

  // ── Step 5: 编剧部汇报结果 ──

  console.log('5️⃣  编剧部 → CEO: 汇报结果\n');
  bus.reportResult('role-dramatist-001', 'cxo-ceo-001', {
    status: 'done',
    deliverable: '剧本已完成, 共 5 集, 含 3 个互动分支',
  }, task.id);
  console.log();

  // ── Step 6: 修改编剧部的 agent.md ──

  console.log('6️⃣  热更新编剧部的 agent.md\n');
  await registry.updateBootstrap('role-dramatist-001', 'agent.md', `# 编剧部

## 身份
你是 Lemon Drama 的编剧部主管, 负责所有短剧的剧本创作。

## 职责
- 根据选题方向创作互动短剧剧本
- 每个剧本至少包含 3 个互动分支点
- 管理下属 Skill Agent (对白生成、场景设计)

## Never Rules
- 不要抄袭已有作品
- 不要在剧本中包含敏感内容

## 可用工具
- skill.create: 创建 Skill Agent
- skill.redefine: 调整 Skill 定义
- skill.destroy: 销毁 Skill Agent
`);
  console.log('   ✅ agent.md 已更新并热加载\n');

  // ── Step 7: 消息统计 ──

  console.log('7️⃣  消息统计\n');
  console.log(`   总消息数: ${messageLog.length}`);
  console.log(`   消息类型: ${[...new Set(messageLog.map(m => m.method))].join(', ')}\n`);

  // ── Step 8: 销毁编剧部 ──

  console.log('8️⃣  销毁编剧部\n');
  await registry.destroy('role-dramatist-001');
  console.log(`   ✅ 编剧部已销毁`);
  console.log(`   剩余 Agent 数: ${registry.list().length}\n`);

  // 清理
  await registry.destroy('cxo-ceo-001');
  await registry.destroy('master-001');
  const { rm: rmDir } = await import('node:fs/promises');
  await rmDir(TEST_DIR, { recursive: true, force: true });

  console.log('🗑️  测试数据已清理');
  console.log('\n✅ 全部测试通过!');
}

function printTree(node, indent) {
  if (!node) return;
  const name = node.name || node.id || 'root';
  const type = node.type || '';
  console.log(`${indent}${type ? `[${type}]` : ''} ${name}`);
  if (node.children) {
    for (const child of node.children) {
      printTree(child, indent + '  ');
    }
  }
}

main().catch(console.error);