feat(chat): 数字员工产出文件可下载(捕获/存储/消息卡片/下载端点) - #55
Conversation
|
您好,我们目前已将新版能力进行了更新,回复卡片相关功能修改后我们继续评审 |
004b405 to
575c626
Compare
|
已按新版能力重写本 PR(commit 575c626,基于最新 main 6f72f96)。 变化说明新版 harness v2 的 artifact 管线(workspace_file artifact + HarnessArtifactDownloads 卡片 + 带 sha256 校验/路径安全的下载端点)已经覆盖了产出下载的主链路,因此原实现整体撤下:
重构后的实现(3 处小改 + 测试)
验证
前端无需改动——artifact 进 |
按 harness v2 重构本 PR:新版管线(workspace_file artifact + HarnessArtifactDownloads 卡片 + 安全下载端点)已覆盖产出下载主链路, 原 AgentOutputFile 表/outputs 目录/独立下载端点/消息 metadata 挂载全部 撤下,只保留本 PR 的核心增量——自动补登兜底: - runner:_execute_plan 在 structured 回写工作区相对 artifact_dir (仅 workspace_root 存在时;试运行不落工作区则不带) - invoker:模型未在结果 JSON 声明 artifacts 且运行成功时,自动扫描 artifact_dir 把净产出文件登记为 workspace_file artifact(≤20 个、 跳过空文件、拒绝越出 TaskFrame 工作区的路径;每个文件仍经 open_harness_artifact 校验+sha256),并记 general_skill_artifacts_auto_declared 事件 - prompt 修正:repair prompt 的 OUTPUT_DIR 与实际环境变量 ARTIFACT_DIR 不一致(main 预存在);两个 prompt 补充自动补登语义说明 测试:runner 回写字段/有 workspace 与否;兜底补登(sha256/大小/来源断言)、 显式声明不重复、失败运行不补登、逃逸路径拒绝;全量 1303 passed、ruff 零告警
main 的 4bdab76(legacy 清理)丢了 staticmethod,实例调用即 TypeError, 新会话首轮必炸;实例调用验证+相关测试 75 passed
553dc3e to
3f3d905
Compare
|
指定 artifact_dir: "attachments" 后,已有的 attachments/user-input.txt 会被登记成技能生成的下载产物。这样可能把用户上传文件、此前运行的文件错误地当作本次输出。 模型运行的cache文件,中间文件,这些都是没有必要返回给用户的内容,解决了产出丢失是否会造成无关产出过多且重复全目录扫描? |
维护者复核指出:模型在输出 JSON 自报 artifact_dir(如共享目录 attachments)会劫持兜底扫描,把用户上传/历史文件登记成产出;且缓存/ 中间文件不应进下载区。 - runner:artifact_dir 由 setdefault 改为强制注入,模型自报值一律覆盖, 兜底扫描目录永远指向本次运行的专属产物目录 - artifacts.py 新增 is_noise_artifact_path(点开头/__pycache__/tmp·part· log 后缀),兜底扫描排除缓存与中间文件 - 回归测试:模型自报劫持被覆盖、噪音文件全部排除、越界路径仍拒绝
|
感谢复核,两个问题都属实且已修复(commit 1a00a22): 1. artifact_dir 可被模型劫持(用户上传/历史文件被误登记) 根因:runner 用 2. cache/中间文件不应进下载区 兜底扫描新增噪音过滤( 全量 1332 passed、ruff 零告警。 |
概述
数字员工产出的文件(如通用技能生成的 PPT)从"死在临时目录"变成可下载的一等产出:runner 捕获 → 磁盘+DB 持久化 → assistant 消息挂载 → 聊天内点击下载。
参考 Clawith 的工作区模型后按我们的产品形态取舍:产出回聊天(对话即交付),不做独立 Workspace 面板。
实现
产出捕获(runner)
_execute_plan执行后扫描工作区,捕获净新增文件(排除物化进去的技能包输入与 runner 脚本;单文件 ≤12MB、单次 ≤20 个);output_sink持久化;失败/被废弃尝试的产出随临时目录清理;run_dir此前从不清理,现在执行后一律rmtree。存储(
AgentOutputFile+output_files.py)outputs/(不内联 base64——PPT 数 MB 会撑爆消息表);output_sink回调贯穿三条运行路径:agent_loop 流式聊天、SOP 内general_skill.*工具调用、通用技能运行测试页;output_files进消息 metadata),幂等。下载
GET /api/chat/outputs/{file_id}/download:仅产出归属人或管理员,FileResponse直出;outputs 根外路径拒绝(防逃逸);测试
_execute_plan产出收集 + 临时目录确认删除;output_sink参数;全量 1249 passed、ruff 零告警、前端 build 通过。说明