describe-role-definition-truncation.test.js 3.18 KB
/**
 * 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');
  });
});