/** * Unit Test — describeRoleDefinition 截断可见性(本体装配静默坑修复) * * 原实现把 agent.md 悄悄切到前 2000 字:职能说明如果排在文件后半(本体写得长一点 * 就很常见),workgraph-planning 拿到的角色定义里根本没有这句话,而它不会知道 * 自己看到的是被切过的半截——「硬约束不前置就等于没写」。 * * 这里锁的是:截断了就必须带⚠️提示 + 完整路径;没截断(原文本来就短)就什么都不多说。 * 用真实 system/agents/ 目录起一个 zz- 前缀的临时本体(同款手法见 * base-graduation-gate.test.js 的 zz-hire-test-co),跑完删掉,不留痕迹—— * locator.bodyDir() 没有 env 覆盖点,读的就是真实仓库路径,测试只能顺着这条路走。 */ import { describe, it, expect, afterEach } from 'vitest'; import fs from 'fs'; import path from 'path'; const REPO_ROOT = path.resolve(__dirname, '../../..'); const AGENTS_ROOT = path.join(REPO_ROOT, 'system', 'agents'); describe('describeRoleDefinition 截断可见性', () => { const testAgentId = 'zz-test-role-trunc'; const testAgentDir = path.join(AGENTS_ROOT, testAgentId); afterEach(() => { fs.rmSync(testAgentDir, { recursive: true, force: true }); }); it('agent.md 超过 2000 字时,截断段落带⚠️提示 + 完整路径', () => { fs.mkdirSync(testAgentDir, { recursive: true }); const longContent = `# ${testAgentId}\n` + 'x'.repeat(2500); fs.writeFileSync(path.join(testAgentDir, 'agent.md'), longContent); delete require.cache[require.resolve('../../services/graph-engine.js')]; const engine = require('../../services/graph-engine.js'); const result = engine.describeRoleDefinition({ systemAgentId: testAgentId, companyId: null }); expect(result).toContain(`⚠️ 原文共 ${longContent.length} 字,已截断到前 2000 字`); expect(result).toContain(path.join(testAgentDir, 'agent.md')); // 截断本身没变——2000 字上限仍是故意的,摘录长度不应该被这次修复顺带改掉 const excerpt = result.split(':\n')[1].split('\n(⚠️')[0]; expect(excerpt.length).toBe(2000); }); it('agent.md 不超过 2000 字时,不带任何截断提示', () => { fs.mkdirSync(testAgentDir, { recursive: true }); const shortContent = `# ${testAgentId}\n短本体`; fs.writeFileSync(path.join(testAgentDir, 'agent.md'), shortContent); delete require.cache[require.resolve('../../services/graph-engine.js')]; const engine = require('../../services/graph-engine.js'); const result = engine.describeRoleDefinition({ systemAgentId: testAgentId, companyId: null }); expect(result).not.toContain('⚠️'); expect(result).toContain('短本体'); }); it('本体不存在时回落到明确的「未找到」提示,不是截断逻辑的边缘情况', () => { delete require.cache[require.resolve('../../services/graph-engine.js')]; const engine = require('../../services/graph-engine.js'); const result = engine.describeRoleDefinition({ systemAgentId: 'zz-does-not-exist-role-trunc', companyId: null }); expect(result).toContain('未找到该本体的 agent.md'); }); });