feat(swads): add daily image report workflow

This commit is contained in:
Jeffrey Wu
2026-09-07 11:34:00 +08:00
parent f39f6ac881
commit 5c61371d7e
38 changed files with 2537 additions and 52 deletions
+10
View File
@@ -53,3 +53,13 @@ flowchart TB
## Failure and shutdown
Run timeout 和用户 cancel 使用不同 reasonApproval wait 监听同一 AbortSignal。删除先 abort,再 cancel pending approval,关闭订阅与 SSE,调用 Pi `dispose()`,清凭证/附件,最后在 canonical sessions root 校验后删除 cwd。单个 SSE 断开不取消 Run。
## SW Ads daily report
`SkillCatalog.expandCommand` 将精确 `/swads-daily-report` 按需转换为 Pi `<skill>` block,自由文本参数保留,`user.message` 保持原文。Catalog/模型自动匹配不加载该 Skill 正文;`disable-model-invocation` 排除自动发现提示。`skill.requested/loaded``source` 区分 command 和 readcommand 不伪造 toolCallId。只读 Skill resources 在已发现根目录内校验 realpath、普通文件和 symlink 边界。
Pi tools 增加 `swads_cli``render_swads_daily_report`,原有工具和审批不变。`SwadsGateway` 在服务启动时读取并校验环境配置,每个命令创建独立 MCP client/transport,初始化后使用短时能力缓存(60 秒,capabilities 强制刷新),调用结束关闭连接。命令 enum 映射固定远端名,参数先经过本地 strict schema/64 KiB/深度 10 检查,再经远端 inputSchema 验证;需要显式 readOnlyHint,拒绝 destructiveHint。单次调用 30 秒默认超时,响应 2 MiB 上限,AbortSignal 来自当前 Run。Gateway 工具不会注册到 Agent。
每个 Session 的 `SwadsReportTools` 记录当前 Run 的 whoami/catalog/query 成功证据,缺失或必需查询失败禁止 render。Skill 根据返回 columns 名称归一化真实指标,日期、账户、归因和样本限制写入 strict `ReportData`。ReportStore 拥有 accountKey/hash、reportId/UUID 和输出路径,临时目录完整写入后 rename。Chrome 从环境或固定系统路径发现,通过 execFile 启动,5200/9000/24000 三档画布,检查底边与结尾标记后裁切;不完整则降级。
render tool completion 由 Pi adapter 映射到 `report.generated { assistantMessageId, artifact }`。事件只含相对 URL/安全标识/warning,既没有文件正文也没有绝对路径。Web reducer 合并同 Run 的临时 assistant ID,从同源接口获取 PNG 并创建 blob URL,再追加到指定消息(兼容本地 HTTP 部署下 assistant-ui 的图片 URL 校验);Markdown、图片 Dialog 与下载 Tool UI 分工呈现。生成图片是展示产物,不进入模型输入,不受 vision capability 限制。报告 Store 位于 Session Store 之外,重置和删除会话不会删除报告。
+8
View File
@@ -39,3 +39,11 @@ multipart 流有字节上限;扩展名、MIME、magic bytes 三重匹配。Sha
## Required production isolation
不可信 Skill、仓库、脚本、附件解析或无人值守 Agent 必须在 Docker(配合 seccomp/AppArmor 和无特权用户)、VM、micro-VM 或远程 Sandbox 运行,并施加 CPU/内存/磁盘/时间/网络配额。Project Trust 不能替代这些措施。
## SW Ads read-only facade and artifacts
- `SWADS_MCP_TOKEN` 仅存在服务端配置和出站 Authorization Header。URL 不允许凭据/query/fragmentfetch 禁止 redirect,避免 Header 转发。Gateway 原始错误正文、Headers 和 Token 不进入模型/SSE/日志/下载,返回固定 `SWADS_*` 错误分类。响应中的 Token 精确值及敏感键在模型交付前脱敏。
- `swads_cli` 只允许约定九个 command。参数拒绝任意 URL/Header/Token/tool name 和未知顶层字段;语义 query 允许有界嵌套 JSON,但不能提供传输控制项。Tool 必须存在并声明只读;非只读 `runtime_findings` 禁止执行。缺少所需 TikTok 能力时 fail closed,不用 mock 数据兜底。
- `render_swads_daily_report` 不接收路径、命令或 Chrome 参数。strict schema 限制字符串/数组长度、真实 ISO 日期、有限数值/null、倍率/百分比与恰好三条建议。动态 HTML 字段全部转义,CSS 无外部字体;CSP 禁止脚本/网络资源,Chrome 使用独立临时 profile、固定参数和进程超时。
- Artifact URL 仅按 accountKey、ISO 日期、UUID 和 png/html/json enum 定位;逐段拒绝 symlink,无目录枚举。PNG inline、HTML/JSON attachment,准确 MIME、nosniff、限制性 CSP、private no-store。随机 ID 不是身份授权,现有单进程无认证应用仅适合内部/本地边界;公网多租户部署需要独立授权设计。
- JSON/HTML 即使 PNG 失败仍保留。PNG 超时、缺浏览器、截断分别返回 warning;取消 Run 则清理未发布临时目录。报告不随 Session 删除,部署方需管理持久目录容量。