/** * agent 提示词里印的端口必须是真的。 * * 为什么要一条守卫:`packages/agent-core/base/` 下那几份是**所有 agent 的工具说明** * (composed 进每个 agent 的提示词),里面印着 `curl http://localhost:3000/api/agent/...`, * 而实际端口是 **3010**(server/config.js)。agent 照着打就连不上,而它拿到的是 * 连接被拒、不是一句「端口错了」—— 它多半会去猜别的原因。 * * 这不是假想:批 5 回填出来的历史派单正文里,有人手写了 * 「完成后调用 report_task 汇报给 innovator(端口 3010,不是 3000)」来纠正它 —— * 说明这个错误已经真咬过人,而且是靠人肉在每条任务书里打补丁。 * * 判据刻意宽松:只禁 `localhost:3000`(那个确定是错的),不去校验「必须等于 * config.port」—— 端口可被 PORT 覆盖,写死校验反而会在部署环境里误报。 */ import { describe, it, expect } from 'vitest'; import { createRequire } from 'module'; import fs from 'fs'; import path from 'path'; const require_ = createRequire(import.meta.url); const ROOT = path.resolve(__dirname, '../../..'); const SCAN = ['packages/agent-core/base', 'system/agents']; // agent 目录下会长出运行态产物:Python venv、node_modules、下载的浏览器驱动…… // 那些是**第三方文件,不是提示词**,扫进来只会拿 playwright 的 ThirdPartyNotices 当违例 // (实测第一版就是这么红的)。守卫要盯的是人写给 agent 看的东西。 const SKIP_DIR = /(^|\/)(node_modules|\.git|dist|coverage|venv|\.venv|site-packages|__pycache__|workspace|conversations|train)(\/|$)/; function walk(dir, out = []) { if (!fs.existsSync(dir) || SKIP_DIR.test(dir)) return out; for (const e of fs.readdirSync(dir, { withFileTypes: true })) { const full = path.join(dir, e.name); if (e.isDirectory()) walk(full, out); else if (/\.(md|json|txt)$/.test(e.name)) out.push(full); } return out; } describe('agent 提示词里的端口', () => { const files = SCAN.flatMap((d) => walk(path.join(ROOT, d))); it('扫描样本非空 —— 防止路径写错时本测试退化成永远通过', () => { // 少了这条前置断言,SCAN 里的路径一旦写错就会以「零违例」的形式全绿, // 而一条永远通过的守卫和没有守卫是一回事。 expect(files.length).toBeGreaterThan(50); }); it('不许再出现 localhost:3000(实际端口是 3010)', () => { const offenders = []; for (const f of files) { const src = fs.readFileSync(f, 'utf-8'); src.split('\n').forEach((line, i) => { if (line.includes('localhost:3000') || line.includes('127.0.0.1:3000')) { offenders.push(`${path.relative(ROOT, f)}:${i + 1} → ${line.trim().slice(0, 90)}`); } }); } expect(offenders).toEqual([]); }); it('config.port 的缺省确实是 3010(守卫的前提,变了要先改这里)', () => { const cfg = require_('../../config'); expect(cfg.port).toBe(3010); }); });