# 输出与报告参考

## 默认输出

- 抓取结果默认写入 skill 根目录 `inquiries.json`，抓取日志和 `outputs/runtime/accio_scrape_state.json` 也继续留在 skill 根目录。
- Markdown / PDF 导出都由配置控制，默认关闭：`scripts/config.py` 中 `DEFAULT_EXPORT_MARKDOWN = False`、`DEFAULT_EXPORT_PDF = False`。需要启用 Markdown 文件时可运行报告脚本加 `--md`，或设置 `ACCIO_EXPORT_MARKDOWN=1`；需要启用 PDF 时可加 `--pdf`，或设置 `ACCIO_EXPORT_PDF=1`。
- 文件导出关闭时，报告脚本返回 `report_text`；如果正文太长，stdout 会省略正文并返回 `report_text_path`，必须读取该内部正文文件后再生成最终回复。不写 Markdown/PDF 交付物文件；最终回复不得写入 `## 报告文件`、Markdown/PDF 链接、文件路径或未生成提示等交付物内容。启用文件导出时，报告默认写入 Agent 共享工作区专属子目录 `alibaba-inquiry-analyst-output`；共享工作区无法从 CLI/env/state 定位时，才回退到 skill 根目录。
- `ACCIO_REPORT_OUTPUT_DIR` 表示最终报告目录本身；`ACCIO_PROJECT_DIR` 表示 Agent 共享工作区根目录，manager 会自动追加 `alibaba-inquiry-analyst-output`。
- 共享工作区里的历史 Markdown/PDF 只能作为交付物路径参考，不能反推为本轮抓取数据；本轮数据仍以 skill 根目录 `inquiries.json` 和 manager state 校验为准。
- `report_text_path` 只用于上游 skill 与 Accio Work/下游 skill 的内部正文交接，文件保存在 `outputs/runtime/`，manager 入口会清理超过 72 小时的 `*_report_text.txt`。下游读取失败时必须重新生成报告，不得展示内部路径或用旧摘要补写。
- `--stdout-json` 会把完整 JSON 输出到 stdout，并且不写文件

## Accio Work 完整报告输出

Accio Work 最终面向用户的报告默认必须是完整报告，不输出简约版本；排版应模仿 Accio Work 业务汇报风格，而不是直接粘贴宽 Markdown 表格。

## 查询新鲜度门槛

当用户要求“查询/查一下/抓取/看一下/今日询盘/今日单独询盘/昨日询盘”等新查询时，报告生成前必须满足：

- 本轮已经通过 `scripts\accio_scrape_manager.py start` 启动目标窗口抓取，并通过 `scripts\accio_scrape_manager.py status` 轮询到可报告结果，再运行 `scripts\accio_scrape_manager.py finish` 完成报告和清理；或在长超时工具调用里通过 `watch --force --max-minutes auto` 等到可报告结果。
- `start` 和 `status` / `finish` / `watch` 必须分开成多次工具调用；禁止把它们合并成 `start && watch`，否则会占住外层 Bash 并触发 120 秒工具超时。
- `inquiries.json` 是本轮 manager 抓取命令生成的结果，不是对话开始前已有的旧文件。
- 抓取前后应确认 `inquiries.json` 的修改时间已更新；如果修改时间没有更新，必须把本次结果视为未抓取成功。
- `inquiries.json` 中的 `start_time` / `end_time` 或 `scope_desc` 与用户请求的目标窗口一致。
- `status == "ok"`，且 manager 校验为 `reportable == true`。

不满足以上任一条件时，禁止输出报告。应直接说明阻塞原因，例如 CDP 未连接、登录态失效、抓取失败、或无法确认数据为本轮新抓取。

禁止行为：

- 直接运行 `scripts\scrape_inquiries.py` 作为 Accio Work 查询入口。
- 只运行 `scripts\accio_generate_report.py`，不先运行 manager 抓取。
- 直接读取旧 `inquiries.json` 后当作本次查询结果。
- 根据模型推断、缓存记忆或当前日期手写“0 条询盘”报告。
- 在没有新抓取产物时，用“根据美西时间查询”这类文字包装一个报告。

## Bash 超时处理

如果 Bash 工具提示 `timed out after 120s`：

- 不读取旧 `inquiries.json`，不生成报告。
- 不重复启动同一个直跑 scraper。
- 如果已经通过 manager start 启动过任务，优先继续运行快速返回的状态轮询：

```powershell
python -X utf8 scripts\accio_scrape_manager.py status
```

- 当 `status` 返回可报告结果后，再单独运行：

```powershell
python -X utf8 scripts\accio_scrape_manager.py finish
```

- 短超时 agent shell 里未加 `--force` 的 watch 会直接返回 `blocked`；只有当前 Bash 工具调用能显式设置足够长的超时时，才单独运行 `python -X utf8 scripts\accio_scrape_manager.py watch --force --max-minutes auto`。
- 如果此前误用了 `scripts\scrape_inquiries.py` 直跑并超时，则放弃该次结果，重新按统一入口执行 manager `start` / `status` / `finish`。
- 如果 manager watch 返回 `watch_timeout` 且提示进程仍在运行，只继续运行 `watch` 或 `status`，不要重新 `start`。

## 登录跳转处理

如果抓取日志、manager `status` / `finish` / `watch` 返回 `login_required`，或页面地址已经跳转到 `https://login.alibaba.com/`：
- 立即停止本轮抓取，不重试、不杀掉后再重新 start 同一请求。
- 不读取旧 `inquiries.json`，不运行 `scripts\accio_generate_report.py`，不输出任何报告。
- 明确提示用户：请在新打开的浏览器里完成阿里国际站登录，然后重新运行查询。
- 保留浏览器窗口给用户登录；登录完成后再从统一入口重新执行 `accio_scrape_manager.py start` / `status` / `finish`。

当用户要求“报告”“完整列表”“完整报告”“列表”“统计”“分析”，或抓取后需要直接反馈结果时：

1. 先完成查询新鲜度门槛和报告前校验。
2. 运行统一报告脚本：

```powershell
python -X utf8 scripts\accio_generate_report.py
```

3. 读取脚本返回 JSON 里的 `report_text`；若返回 `report_text_omitted=true` 或没有完整 `report_text`，必须读取 `report_text_path`。只有启用 Markdown 导出时才读取 `output` 文件。
4. 最终回复必须基于底稿输出完整 1-6 模块正文，但要改写成 Accio Work 风格业务汇报：1/2/4/6 用要点，3 必须原样使用 `report_text` 中“负责人跟进看板”的表格，或使用脚本 JSON 返回的 `assignee_followup` 字段渲染；禁止从第 5 模块买家明细、买家标题、对话内容或模型记忆重新聚合负责人列表，避免把买家名误当负责人。5 用逐条卡片。
5. 只有本轮启用 Markdown 或 PDF 导出时，最终回复末尾才保留“报告文件”区块，并输出 Accio Work 可直接点击打开的 `file:///` 链接。文件导出关闭时不要输出报告文件区块、文件路径或未生成提示。Markdown 链接格式统一为 `[📄 打开 Markdown 报告](file:///C:/...)`；PDF 只有本轮明确启用且成功生成时才额外出现。

禁止用临时手写表格替代正式报告；禁止只输出“序号/买家/国家/负责人/摘要/回复状态”这类简约列表；禁止只给统计摘要后结束；禁止写“以下是报告摘要”后省略第 5 模块。
禁止在全量明细中使用“部分摘要”作为标题或内容替代；禁止插入 `...` 省略行；禁止只展示前几条和最后一条。

完整报告至少包含：

- 总览统计
- 商机类型分布（TM 商机 vs 询盘商机）
- 负责人跟进看板
- 待跟进重点
- 全量询盘明细，且不省略任何询盘行
- 每条询盘展示全对话前五句有效消息，并基于该条基本信息和前五句对话生成 1-2 句自然中文摘要
- 数据完整性说明
- 报告文件链接（仅在本轮启用 Markdown 或 PDF 导出时出现；Markdown/PDF 都关闭时省略）

第 5 模块输出规则：
- 底稿中的“摘要素材”不是最终正文；最终回复必须将它改写成 `摘要：...`。
- 每条询盘卡片必须显式展示用户等级；时间行必须标注北京时间，例如 `时间（北京时间）：创建 07:22；最后更新 11:11`。
- 前五句对话按全对话最早 5 条有效消息展示，买家、卖家、自动回复都计入。
- 即使详情抓取失败，也要展示该询盘卡片，并用可用的 `last_message` 或列表信息生成谨慎摘要。

只有用户明确说“只要简版/只要一句话/不要完整报告”时，才可以额外给简版；默认仍应保留完整报告正文。报告文件链接仅在本轮启用 Markdown 或 PDF 导出时出现。

## 顶层字段

当前结果保留这些核心字段：

- `status`
- `date`
- `generated_at`
- `mode`
- `scope_desc`
- `filter_category`
- `filter_assignee`
- `filter_buyer_name`
- `depth`
- `max_detail`
- `start_time`
- `end_time`
- `total`
- `detail_count`
- `detail_skipped`
- `unreplied_count`
- `skipped`
- `failed`
- `partial`
- `warnings`
- `pages_loaded`
- `pages_checked`
- `batch`
- `inquiries`

其中：

- 默认今日查询通常不输出 `start_time` / `end_time`
- 显式时间窗查询会输出 `start_time` / `end_time`

## 已删除字段

旧排序、旧日期简写和旧查询策略字段不再出现在新结果里。

## 报告前校验

正式报告前至少确认：

- `status == "ok"`
- `partial != true`
- `total == len(inquiries)`
- 没有重复 `inquiry_id`
- 目标窗口与过滤条件和用户请求一致

少量详情补跑失败仍可在内部视为可报告结果，但不应重新引入旧技术字段解释口径。
