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