verify-attachment-question.mjs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /**
  2. * 验证「把附件地址拼进 question 文本」这条链路(方案②)。
  3. *
  4. * 背景(2026-09-18):新接口 /api/chat 只收 {thread_id, question},多字段 422,
  5. * 旧协议的 transmission.files 发不出去;改为把 OSS 地址拼进 question。
  6. *
  7. * 不变量:
  8. * ① 没有附件时**必须原样返回**问题(不能凭空多个换行 —— 那会改变所有普通提问)
  9. * ② 有附件时:原文在前、每条 URL 各占一行、**不加**任何自定义措辞
  10. * ③ 空/无效 URL 被过滤(上传失败的文件不该混进问题里)
  11. *
  12. * 怎么跑(在项目根目录):
  13. * npx esbuild harness/tools/_entry-attachments.ts --bundle --format=esm \
  14. * --outfile=harness/tools/_attachments.mjs
  15. * node harness/tools/verify-attachment-question.mjs
  16. */
  17. import { buildQuestionWithAttachments } from './_attachments.mjs';
  18. let pass = 0;
  19. let fail = 0;
  20. const check = (name, cond, extra = '') => {
  21. if (cond) {
  22. pass++;
  23. console.log(' ok ' + name);
  24. } else {
  25. fail++;
  26. console.log(' FAIL ' + name + ' ' + extra);
  27. }
  28. };
  29. const Q = '帮我看看这份材料符合条件吗';
  30. const U1 = 'https://bucket.oss-cn-shanghai.aliyuncs.com/upload/a.png';
  31. const U2 = 'https://bucket.oss-cn-shanghai.aliyuncs.com/upload/b.pdf';
  32. console.log('【1】没有附件时:必须原样返回');
  33. check('undefined → 原文', buildQuestionWithAttachments(Q, undefined) === Q);
  34. check('null → 原文', buildQuestionWithAttachments(Q, null) === Q);
  35. check('空数组 → 原文', buildQuestionWithAttachments(Q, []) === Q);
  36. check('全是空串 → 原文(不要多个换行)', buildQuestionWithAttachments(Q, ['', ' ', null]) === Q, JSON.stringify(buildQuestionWithAttachments(Q, ['', ' ', null])));
  37. console.log('\n【2】有附件时:原文在前、URL 各一行');
  38. check('单个附件', buildQuestionWithAttachments(Q, [U1]) === `${Q}\n${U1}`, JSON.stringify(buildQuestionWithAttachments(Q, [U1])));
  39. check('多个附件按顺序', buildQuestionWithAttachments(Q, [U1, U2]) === `${Q}\n${U1}\n${U2}`);
  40. check('**原文完整保留在前面**', buildQuestionWithAttachments(Q, [U1]).startsWith(Q + '\n'));
  41. check('**不添加自定义措辞**(只有原文与 URL)', !/附件|文件|attachment/i.test(buildQuestionWithAttachments(Q, [U1]).slice(Q.length)));
  42. console.log('\n【3】脏数据过滤');
  43. check('混入空值只保留有效 URL', buildQuestionWithAttachments(Q, [U1, '', null, U2]) === `${Q}\n${U1}\n${U2}`);
  44. check('URL 前后空格被去掉', buildQuestionWithAttachments(Q, [` ${U1} `]) === `${Q}\n${U1}`);
  45. console.log(`\n===== 通过 ${pass} 项,失败 ${fail} 项 =====`);
  46. process.exit(fail ? 1 : 0);