AllInTest 正式测试报告预览 / 发送
路径约定
| 资源 | 优先 | fallback |
|---|---|---|
| 本 Skill | .cursor/skills/qamate-allintest-report-skill/SKILL.md |
.cursor/qamate/skills/qamate-allintest-report-skill/SKILL.md |
| CLI | .cursor/skills/qamate-allintest-report-skill/scripts/allintest_report_cli.py |
同上(setup 复制后路径一致) |
与 qamate-allintest-skill 分工:后者管 allintest-mcp-server 通用查询与 reqzone;正式邮件报告预览/发送 走本 skill。
调用优先级
① qamate-cli call allintest-mcp-server <tool> ← 本框架 Agent 默认(Shell)
② Cursor MCP(nacos-mcp-router / CallMcpTool) ← qamate-cli 不可用或失败时
③ scripts/allintest_report_cli.py ← ①② 都失败时(需 allintest.report 配置)
✗ 手写 curl / 直连 AllInTest REST ← 禁止
| 优先级 | 方式 | 何时用 |
|---|---|---|
| ① 默认 | qamate-cli call allintest-mcp-server <工具名> --param ... |
本工程 Cursor Agent 首选 |
| ② 回退 | Cursor CallMcpTool → allintest-mcp-server 同名工具 |
qamate-cli 未装 / 鉴权失败 / 明确报错后 |
| ③ 末级 | python .../allintest_report_cli.py <子命令> |
①② 均不可用;需业务仓配 allintest.report |
| 禁止 | 手写 HTTP / curl | — |
说明(给框架 vs 其他使用方):
- allintest-mcp-server 始终是能力面:工具语义(
prepareFormalReportPreviewByName等)不变;其他使用方 / 非 Cursor Agent 可直接走 MCP,不必强制 qamate-cli。 - 本 skill 只约束本仓库 Agent:先
qamate-cli(本机 CLI 自己发现 MCP,不依赖 IDE 面板状态),不行再用 Cursor 内嵌 MCP,最后才本地脚本。 - 不要把「优先 qamate-cli」写成「禁止 MCP」——MCP 合法且与 qamate-cli 调的是同一套工具。
执行约定:
- 先 Shell:
qamate-cli call ...(建议--format json) - ① 失败 → 再
GetMcpTools/CallMcpTool调同名工具 - ①② 都失败 → 配好
allintest.report后走 ③ - 工具语义名不变:
prepareFormalReportPreviewByName/reviseFormalReportMail/refreshFormalReportPreview/mutateFormalReportContent/sendFormalReport
职责边界
| 本 skill | 不做 |
|---|---|
经 qamate-cli → MCP → 本地 CLI 调 prepare / refresh / mutate / revise / send,原样输出 mail_review.reviewText |
写 output.pingback/*-test-report-preview.md |
reportData={},依赖服务端按 PMS 自动拉数 |
额外拉 Issue/Bug/周期凑摘要 |
返回 preview_url、report_id、confirm_token |
本地 JSON 缓存当报告数据源 |
固定执行顺序(禁止扩展)
入口门禁(优先于一切模式判定)
进入本 skill 须同时满足:
- 用户话术含 「报告」,或 上下文正在续办正式邮件报告会话(已有
confirm_token/reviewText/report_id) - 不命中下方排除词(命中则转交对应 skill,不得进入本 skill)
| 排除词(话术含以下表述) | 转交 |
|---|---|
| 自动化报告 | qamate-atlas-report-skill |
| atlas 报告 / Atlas 报告 | qamate-atlas-report-skill |
| pingback 报告 / Pingback 报告 | 业务仓 Pingback 测试报告 skill |
| 视图报告 | 业务仓 Pingback 测试报告 skill |
> 无「报告」二字且非续办会话 → 不进入本 skill(与其它能力的路由由各 skill 自行处理,本 skill 不写列举)。
入口判定(每轮必做,先于模式 A/B/C/D/E):
用户话术
├─ 不含「报告」且无 confirm_token / report_id 续办 → 不进入本 skill
├─ 含排除词(自动化报告 / atlas 报告 / pingback 报告 / 视图报告)→ 不进入本 skill
├─ 同时明确「修改/流转状态到 {TARGET_STATUS}」与「发送报告」
│ → 复合意图:暂存 target_status;后续 prepare 必须传 targetStatus,邮件成功后自动流转
├─ 模式 B / C / D / E 专用话术,且上下文有 confirm_token 或 report_id
│ → 对应模式(报告类型已绑定,不再问类型)
├─ 含「增加 / 追加 / 添加 / 改成 / 修改 / 更新 / 删除 / 清空 / 去掉」
│ +「报告内容 / 正文 / 第 N 部分 / 字段名 / 测试风险 / 测试结论 / 测试开始时间 …」
│ 且上下文有 confirm_token 或 report_id → 模式 E(正文增删改)
├─ 上下文刚返回 need_select_template,用户回复序号/report_id/否 → 模式 S(多模板选择续办)
├─ 上下文刚返回 need_confirm_default_template,用户回复「是/否」→ 模式 T(默认模板确认续办)
├─ report_type 未明确(见模式 R 判定)→ 模式 R(报告类型消歧,禁止 prepare / send)
├─ 含「预览 / 看一下 / 报告预览 / 测试报告预览 / 日报预览 / 产品准入报告预览」
│ 且类型已明确 → 模式 A(预览;若返回待选择/待确认则转模式 S/T)
├─ 仅「改完正文 / 刷新预览 / 重新预览 / 正文已修改 / 更新预览链接」(无具体变更内容)
│ 且上下文有 confirm_token 或 report_id → 模式 D(正文修改后再预览)
├─ 含「确认发送」且持有本轮 confirm_token → 模式 C(发送)
├─ 含「发送 / 发报告 / 发邮件 / 发出 / 邮寄」且未满足上一行
│ 且类型已明确 → 模式 0(发送意图消歧,禁止直接 prepare / send)
├─ 含「生成 / 产出 / 出 … 报告」且类型已明确 → 模式 A(生成即预览;待选择/待确认则转模式 S/T)
└─ 其他(如「正式测试报告 <ISSUE>」,类型已明确)→ 模式 A(预览,默认)
消歧顺序(类型未明时):模式 R →(若发送/生成导向)模式 0 → 模式 A →(若多模板)模式 S /(若无模板)模式 T → 模式 C。
模式 R:报告类型消歧(泛称「报告」强制)
当用户说「生成 / 发送 / 预览 {ISSUE} 的报告」「发 {ISSUE} 正式报告」等,仅使用泛称「报告 / 正式报告 / 邮件报告」、未出现可映射的具体类型词时,必须先确认报告类型,禁止静默默认「测试报告」。
可跳过模式 R(类型已明确)—— 用户话术含以下任一:
| 用户表达 | report_type |
|---|---|
| 测试报告 / 测试通过报告 / 正式测试报告 | 测试报告 |
| 日报 / 测试日报 | 日报 |
| 产品准入报告 | 产品准入报告 |
还须跳过模式 R 的情况:
- 本轮上下文用户已选择报告类型(同一 issue 续办)
- 模式 B / C / D:已有
confirm_token/report_id,类型随既有草稿锁定
必须向用户展示类型选择(可用 AskQuestion 或等效结构化选项):
| 选项 | 用户表达示例 | report_type |
|---|---|---|
| 测试报告 | 「测试报告」「测试通过报告」 | 测试报告 |
| 日报 | 「日报」「测试日报」 | 日报 |
| 产品准入报告 | 「产品准入报告」「准入报告」 | 产品准入报告 |
消歧话术模板(可微调措辞,选项含义不得变):
您要为 {ISSUE_KEY} 生成哪种类型的正式报告?
1. 测试报告 — 常规版本/需求测试结论邮件报告
2. 日报 — 测试日报
3. 产品准入报告 — 产品准入阶段报告
请回复「测试报告」「日报」或「产品准入报告」。
硬性规则:
- 模式 R 未完成前:不得调用 prepare / send,不得因历史习惯默认 testReport
- 用户选定类型后暂存
report_type;若原话术还含发送/生成导向且未确认发送 → 继续模式 0 - 用户选定类型且话术含「预览 / 看一下」→ 直接模式 A
- 用户一句话同时给出类型 + 动作(如「AIPRODUCTDEV-9354 日报预览」)→ 跳过模式 R
模式 0:意图消歧(发送/生成类话术强制)
当用户说「发送 AIPRODUCTDEV-9354 的测试报告」「生成 XXX 报告」「发 XXX 报告邮件」等发送/生成导向话术,且报告类型已通过模式 R 或用户话术明确,但同时不满足以下任一条件时,必须先消歧,禁止调用 prepare / send:
- 用户已明确说「确认发送」,且上下文有本轮有效
confirm_token - 用户本轮已明确选择「直接发送」(见下)
- 用户话术已明确为预览(含「预览 / 看一下 / 报告预览」等)→ 直接模式 A,不走模式 0
必须向用户展示二选一(可用 AskQuestion 或等效结构化选项):
| 选项 | 用户表达示例 | 后续路径 |
|---|---|---|
| 报告预览 | 「报告预览」「先看预览」「预览」 | → 模式 A:仅 prepare,原样输出 reviewText,不 send |
| 直接发送 | 「直接发送」「跳过预览直接发」 | → 模式 A 后立即模式 C:prepare 拿 confirm_token → 同一轮调用 send |
消歧话术模板(可微调措辞,选项含义不得变):
您希望如何处理 {ISSUE_KEY} 的{REPORT_TYPE_LABEL}?
1. 报告预览 — 生成邮件预览(reviewText / preview_url),审核后再决定是否发送
2. 直接发送 — 从服务端拉取报告数据并立即发送邮件(仍会先 prepare 再 send)
请回复「报告预览」或「直接发送」。
{REPORT_TYPE_LABEL} 取本轮已确定的类型自然语言(如「测试报告」「日报」),勿写死「测试报告」。
硬性规则:
- 模式 0 未完成前:不得因用户首句含「发送」就调用
sendFormalReport或 CLIsend - 用户选「报告预览」后:即使后续又说「发送」,也须先完成预览;发送须等用户看完 preview 后说「确认发送」
- 用户选「直接发送」后:prepare → send 可同一轮串行;主回复改为发送结果摘要(含 report_id / 发送状态),不必再全文贴 reviewText
- 解析出
issue_key/business_name/report_type(若已明确)后可暂存上下文,但不得提前调接口
模式 A:预览(默认)
- 解析输入:
pms(issue_key,必填)、business_name(可空,默认从 issue 前缀推断)、report_type(须已明确:来自用户话术类型词或模式 R 选择;泛称「报告」未消歧前不得进入本模式)、user_name(默认user-config/user.config.json)。若用户明确提出“修改状态到 X 并发送报告”,额外解析target_status=X;仅发送报告时不得推断或传该参数。 - 优先 Shell 执行
qamate-cli;失败再用 Cursor MCP 同名工具;再失败才本 skill CLI:
qamate-cli call allintest-mcp-server prepareFormalReportPreviewByName \
--param userName=wangkena \
--param issueKey=ENCODEDEV-2505 \
--param businessName=ENCODEDEV \
--param reportType=测试报告 \
--param targetStatus=测试通过 \
--format json
targetStatus 只用于上述复合意图;普通报告预览/发送必须省略。
末级回退(①② 都失败时):本 skill CLI,需已配 allintest.report:
python .cursor/skills/qamate-allintest-report-skill/scripts/allintest_report_cli.py prepare-by-name \
--pms <ISSUE_KEY> \
--business-name <REQZONE_OR_BUSINESS_NAME> \
--report-type "测试报告" \
--target-status "测试通过"
普通报告预览/发送省略 --target-status。
- 检查返回:
- 若code == 403且msg == 准出校验未通过→ 立即终止,向用户展示data.tip与data.AccessInfo中的失败项;不得继续 prepare / send
- 该准出卡点仅适用于单需求报告;版本报告没有准出要求
- 复合意图必须检查data.post_send_action:应含目标状态和当前用户可用流转;缺失表示后端能力未就绪,必须终止且不得 send
- 若data.status == need_select_template→ 立即转模式 S,列出候选模板让用户选
- 若data.status == need_confirm_default_template→ 立即转模式 T,询问是否用默认模板
- 禁止静默选定模板或静默用 206 - 正常预览成功时:按下方 「reviewText 展示契约」 输出(模式 A / B / D 均适用)
模式 S:多模板选择(匹配到多个模板)
触发:模式 A(或 prepareFormalReportPreviewByName / prepare-by-name)返回:
{
"code": 200,
"data": {
"status": "need_select_template",
"reqzone": "VIDEODEV",
"businessName": "视频云",
"inputReportType": "测试报告",
"message": "匹配到多个报告模板,请选择其一",
"candidates": [
{"reportId": 210, "reportName": "视频云测试报告", "reportType": "testReport"},
{"reportId": 237, "reportName": "视频云测试报告-精简", "reportType": "testReport"}
]
}
}
必须暂停并向用户展示全部候选(可用 AskQuestion 或编号列表)。话术模板:
{REQZONE}({BUSINESS_NAME})匹配到多个「{REPORT_TYPE_LABEL}」模板,请选择其一:
1. {reportName_1}(report_id={id_1})
2. {reportName_2}(report_id={id_2})
…
请回复序号或 report_id;取消则回复「否」。
| 用户回复 | 后续 |
|---|---|
| 序号 / report_id / 模板名(能唯一映射到候选) | 再次 qamate-cli(失败则 MCP)调 prepareFormalReportPreviewByName,传 selectedReportId=<选中的 reportId>(末级 CLI:--selected-report-id);成功后按 reviewText 展示契约输出 |
| 否 / 取消 | 终止本轮报告生成;不得 prepare / send |
硬性规则:
- 未获用户明确选择前:不得 prepare / send,不得静默取第一个候选
- 暂存上下文:
issue_key/business_name/report_type/candidates selectedReportId必须来自本轮candidates中的reportId
模式 T:默认模板确认(业务线未配置模板)
触发:模式 A(或 prepare-by-name / prepareFormalReportPreviewByName)返回:
{
"code": 200,
"data": {
"status": "need_confirm_default_template",
"reqzone": "CLOUDSERVDEV",
"businessName": "用户云UGC",
"inputReportType": "测试报告",
"defaultReportId": 206,
"defaultReportName": "默认测试报告模板"
}
}
必须暂停并向用户确认(可用 AskQuestion 或等效二选一)。话术模板(字段可替换,措辞按此):
{REQZONE}({BUSINESS_NAME})未配置「{REPORT_TYPE_LABEL}」模板。
是否使用默认测试报告模板(report_id={DEFAULT_REPORT_ID})生成报告预览?
回复「是」继续,「否」则本次不生成报告。
示例:
CLOUDSERVDEV(用户云UGC)未配置「测试报告」模板。
是否使用默认测试报告模板(report_id=206)生成报告预览?
回复「是」继续,「否」则本次不生成报告。
| 用户回复 | 后续 |
|---|---|
| 是 / 继续 / 用默认模板 | 再次 qamate-cli(失败则 MCP)调 prepareFormalReportPreviewByName,并传 useDefaultTemplate=true(末级 CLI:--use-default-template);成功后按 reviewText 展示契约输出 |
| 否 / 不用 / 取消 | 终止本轮报告生成;不得 prepare / send;简短说明已取消即可 |
硬性规则:
- 未获用户「是」前:不得带默认模板 prepare,不得静默使用 report_id=206
- 暂存上下文:
issue_key/business_name/report_type/defaultReportId,供用户确认后续办 - 模式 T 未完成前:不得进入模式 C 发送
模式 B:修订邮件(用户要改主题/收件人/抄送)
优先 qamate-cli;失败则 Cursor MCP;再失败才 CLI:
qamate-cli call allintest-mcp-server reviseFormalReportMail \
--param confirmToken=<TOKEN> \
--param subject="新主题" \
--param addReceivers=a@qiyi.com \
--param removeReceivers=b@qiyi.com \
--format json
末级 CLI:
python .cursor/skills/qamate-allintest-report-skill/scripts/allintest_report_cli.py revise \
--confirm-token <TOKEN> \
--subject "新主题" \
--add-receivers "a@qiyi.com" \
--remove-receivers "b@qiyi.com"
输出新的 reviewText 与 新 confirm_token(旧 token 作废)。
模式 D:正文修改后再预览
场景:用户已在 Evaluate 预览页(preview_final_report_formail)编辑并保存报告正文,需要 Agent 把最新预览链接再次发给用户 review。
与模式 B 区分:
模式 B revise-mail |
模式 D refresh-preview |
|
|---|---|---|
| 改什么 | 邮件主题 / 收件人 / 抄送 | Evaluate 页里的报告正文 |
| 是否重渲染 | 否 | 是(服务端对同一 report_id 再 render) |
| 预览链接 | 通常不变 | 回写最新 preview_url 到 reviewText |
进入条件:
- 用户话术含:「改完正文了」「刷新预览」「重新预览」「正文已修改」「更新预览链接」「再发一次预览」等
- 上下文有上一轮预览的
confirm_token(首选);若无 token 但有report_id,提示用户说明是续审同一报告或重新 prepare
禁止:
- 不得再次
prepare-by-name(会新建report_id,丢失用户在 Evaluate 页的编辑) - 不得用模式 B
revise-mail代替(它不 re-render 正文) - 不得 send
步骤:
- 取上下文最新
confirm_token(用户若贴了多个,用最近一轮预览返回的) - 优先 qamate-cli;失败则 Cursor MCP 同名工具;再失败才 CLI:
qamate-cli call allintest-mcp-server refreshFormalReportPreview \
--param confirmToken=<LATEST_TOKEN> \
--param userName=wangkena \
--format json
末级 CLI:
python .cursor/skills/qamate-allintest-report-skill/scripts/allintest_report_cli.py refresh-preview \
--confirm-token <LATEST_TOKEN>
- 回复用户时:按 「reviewText 展示契约」 输出;并明确提示 旧 confirm_token 已作废;若还要改正文,改完后再说「刷新预览」
缺 confirm_token 时:说明需要上一轮预览会话;可问用户是否重新生成预览(模式 A,会新建报告,原 Evaluate 编辑会丢失)。
模式 E:正文增 / 改 / 删(章节或字段)
场景:用户要求 Agent 直接修改报告正文(非邮件主题/收件人),如「在测试风险下增加 xxx」「把测试开始时间改成 2026-06-20」「清空项目背景」。
与模式 B / D 区分:
| 模式 B | 模式 D | 模式 E | |
|---|---|---|---|
| 改什么 | 邮件主题/收件人/抄送 | 仅 re-render 已手改正文 | 编程修改 Evaluate 正文 |
| qamate-cli 工具 | reviseFormalReportMail |
refreshFormalReportPreview |
mutateFormalReportContent |
进入条件:
- 用户话术含增删改动词 + 章节名/字段名/「第 N 部分」/「报告正文」等
- 上下文有最新
confirm_token(首选)
Agent 解析规则:
- 出现具体字段名(如「测试开始时间」「项目背景」「PMS 链接」)→
targetType=field,fieldName归一化 - 出现章节名 / 「第 N 部分」→
targetType=section,如二、测试风险、四、测试情况 - 动词 →
operation:增加/追加/添加→add;改成/修改/更新/设为→update;删除/清空/去掉→delete - 默认
autoRefresh=true
禁止:
- 不得用
reviseFormalReportMail改正文 - 不得用
prepare续改(会新建report_id) - 不得打开浏览器操作 Evaluate 页(有 qamate-cli / MCP 时必须走工具,禁止浏览器)
步骤:
- 取上下文最新
confirm_token - 优先 qamate-cli;失败则 Cursor MCP;再失败才 CLI:
qamate-cli call allintest-mcp-server mutateFormalReportContent \
--param confirmToken=<LATEST_TOKEN> \
--param operation=add \
--param targetType=section \
--param sectionHeading="二、测试风险" \
--param content="xxx" \
--format json
末级 CLI:
python .cursor/skills/qamate-allintest-report-skill/scripts/allintest_report_cli.py mutate-content \
--confirm-token <LATEST_TOKEN> \
--operation add \
--target-type section \
--section-heading "二、测试风险" \
--content "xxx"
- 按 reviewText 展示契约 输出;提示 旧 confirm_token 已作废
模式 C:确认发送
进入条件(满足其一):
- 模式 A 预览后,用户明确说「确认发送」,且持有最新
confirm_token - 模式 0 中用户已选「直接发送」:本轮 prepare 返回的
confirm_token即可 send,无需再等「确认发送」
若草稿包含 post_send_action,确认文案必须明确说明“发送邮件成功后会将需求从 {from} 流转到 {target_status}”;用户确认的是邮件发送和状态流转两个动作。
优先 qamate-cli;失败则 Cursor MCP;再失败才 CLI:
qamate-cli call allintest-mcp-server sendFormalReport \
--param confirmToken=<LATEST_TOKEN> \
--format json
末级 CLI:
python .cursor/skills/qamate-allintest-report-skill/scripts/allintest_report_cli.py send \
--confirm-token <LATEST_TOKEN>
检查发送结果:
data.status == ok且transition.status == succeeded/skipped:报告发送与状态处理完成data.status == partial_success:邮件已发送,但状态流转失败或处理中;必须原样说明,不得重发邮件- 普通报告草稿没有
transition字段:只发送邮件,不修改需求状态
配置
见 references/config.md。
- 走 qamate-cli / Cursor MCP(①②):token 在 allintest-mcp-server 侧;业务工程
qamate.config.json不必写service_token。 - 走末级 CLI 直连 AllInTest(③):才需要在
user-config/qamate.config.json配置allintest.report.base_url+service_token。
高级路径(仅用户明确提供时)
| 用户提供的参数 | 命令 |
|---|---|
businessId + reportType |
末级 CLI:prepare-by-type --business-id ... |
tempId / 模板 ID |
末级 CLI:prepare --temp-id ... |
| 用户已确认默认模板 | qamate-cli / MCP prepareFormalReportPreviewByName + useDefaultTemplate=true;末级:prepare-by-name --use-default-template |
| 用户已选定多模板之一 | qamate-cli / MCP prepareFormalReportPreviewByName + selectedReportId=<id>;末级:prepare-by-name --selected-report-id <id> |
报告类型映射
| 自然语言 | 服务端优先 reportType(版本上下文) | 回退 |
|---|---|---|
| 测试报告 / 测试通过报告 | 单需求:testReport;编码版本:testReportVersion;极速版可 testReport_{platform} |
testReport |
| 版本测试报告 | testReportVersion |
testReport |
| 灰度报告 / 版本灰度报告 | grayReportVersion |
grayReport |
| 上线报告 / 版本上线报告 | onlineReportVersion |
onlineReport |
| 日报 / 测试日报 | dailyReport |
— |
| 产品准入报告 | productAccessReport |
— |
版本上下文判定:传 versionName / --version-name,或 issueKey/--pms 为版本号(非 ISSUE-123),或话术含「版本/灰度/上线」。
CLI 的 --report-type 传自然语言即可(服务端 canonical 化)。版本类示例:
python allintest_report_cli.py prepare-by-name \
--pms 6.0.0705 --business-name ENCODEDEV \
--report-type "测试报告" --version-name 6.0.0705
输出契约
成功时 CLI stdout 优先输出:
mail_review.reviewText(语义原文;展示给用户时须按下方展示契约格式化)preview_urlreport_idconfirm_token
需要调试完整 JSON 时加 --json。
reviewText 展示契约(强制)
AllInTest 服务端 reviewText 已含 \n 换行(通常 6 行:标题、主题、正文链接、收件人、抄送人、审核提示)。Agent 回复用户 时须按下方固定样式输出,禁止压成一行。
步骤:
- 首行摘要 + 正文链接(在 reviewText 块之外):先用一行说明本轮结果(如
{ISSUE} 的正式测试报告预览已生成(模式 A)。),空一行后单独输出可点击的正文编辑链接(不得塞进下方 reviewText 段):
- 正文链接 = Evaluate 报告编辑页:http://evaluate.qa.qiyi.domain/evaluate/preview_final_report/?report_id={report_id}
- 格式:正文链接:[<url>](<url>)(链接文字即完整 URL)
- 空一行后再输出 reviewText 段(步骤 1 起) - 取
mail_review.reviewText(或 CLI stdout 中的 reviewText 段) - 若仍为 JSON 转义字面量(可见
\n两字符),先还原为真实换行 - 禁止用
```text/```代码块包裹整段主回复(代码块内 URL 不可点击) - 用 Markdown 普通文本 + 行尾两个空格硬换行 输出(每行末尾
␠␠再换行),保证「邮件主题 / 正文 / 收件人」分行且不挤成一段 - 必须把预览 URL 写成可点击 Markdown 链接(展示层改写,不改 AllInTest 存储的
reviewText):
-邮件正文:后的 URL →[<url>](<url>)(链接文字即完整 URL,禁止写成「打开预览」等短文案)
- 元数据preview_url:后的 URL → 同样写成[<url>](<url>) - reviewText 6 行之后 空一行,再输出元数据(若 reviewText 未含):
-preview_url: [<url>](<url>)
-report_id: ...
-confirm_token: ... - 禁止再包一层 Agent 摘要;禁止写
*-test-report-preview.md - 禁止在 reviewText 各字段之间追加空行(仅元数据前允许 1 个空行)
展示示例(固定样式;下列每行末尾实际输出时带两个空格硬换行):
AIPRODUCTDEV-9085 的正式测试报告预览已生成(模式 A)。
正文链接:http://evaluate.qa.qiyi.domain/evaluate/preview_final_report/?report_id=110078
【报告预览(未发送)】
邮件主题:【测试报告】VIDEODEV-5832-nexguard水印方案下线
邮件正文:http://evaluate.qa.qiyi.domain/evaluate/preview_final_report_formail/?report_id=109997
收件人:wangkena@qiyi.com;liuhe@qiyi.com;liuyu11@qiyi.com;baifengwei@qiyi.com;yanyanli@qiyi.com
抄送人:iig_ipd_videocloud@qiyi.com;shaohua@qiyi.com
请审核以上信息;报告内容需要调整请直接说明,确认无误请回复“确认发送”。
preview_url: http://evaluate.qa.qiyi.domain/evaluate/preview_final_report_formail/?report_id=109997
report_id: 109997
confirm_token: \<token\>
> 语义与换行数均与服务端 reviewText 一致;展示层用硬换行保真分行,并用 [url](url) 使预览链接可点击且文字即为完整 URL;不改 AllInTest 存储格式。
硬性约束
- 调用路径:本框架 Agent 默认 qamate-cli → 失败再用 Cursor MCP → 再失败用
allintest_report_cli.py;禁止手写 HTTP。其他使用方可直接 MCP,不必强制 qamate-cli。 - 入口:话术须含「报告」或续办 confirm_token 会话;命中自动化/pingback/视图/atlas 报告排除词 → 不得进入
- 泛称「报告」(未含测试报告/日报/产品准入报告等类型词,且无上下文类型)→ 必须先走模式 R,禁止静默默认 testReport
- 匹配到多个模板(
status=need_select_template)→ 必须先走模式 S,列出全部候选让用户选,禁止静默取第一个 - 业务线未配置模板(
status=need_confirm_default_template)→ 必须先走模式 T,禁止静默使用默认模板 206 - 发送导向首句(含「发送 / 发报告 / 发邮件 / 生成 … 报告」且无 confirm_token、且非明确预览话术)→ 类型明确后须走模式 0,禁止直接 send
- 预览阶段(模式 A / D / E / 用户选「报告预览」)不得 调用
send - 用户在 Evaluate 改完正文后 不得 重新 prepare(模式 A)代替 refresh(模式 D)
- 模式 E 改正文 不得 用 revise-mail 或浏览器代替
mutateFormalReportContent - 不得 调用 Pingback 视图、Bug 查询、周期接口「补充报告内容」
- 不得 写入
output.pingback/或任何*-test-report-preview.md - Windows 执行 Python 前确保 UTF-8:优先
python跑 skill 脚本,避免 PowerShell 内嵌长python -c - 测试报告预览类任务:不输出 qamate-reply-spec 的「本轮摘要」;主回复按 reviewText 展示契约 格式化输出
参考
- 调用契约(qamate-cli / MCP / CLI):
references/api-contract.md - MCP 扩展设计(refresh + mutate):
references/report-mcp-extension-design.md - 配置示例:
references/config.md - 与 Pingback 测试报告区分:
references/disambiguation.md