Skip to content

fix(media): 图片直接预览,视频由 Agent 获取路径自主查看 - #7970

Merged
MagicLizi merged 4 commits into
mainfrom
dash/media-agent-preview
Oct 30, 2026
Merged

MagicLizi merged 4 commits into
mainfrom
dash/media-agent-preview

Conversation

@dashhuang

@dashhuang dashhuang commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

这次改了什么

摘要

媒体生成成功后,Agent 之前只拿到受管地址;工具说明又规定只有用户询问存储位置才能取得文件路径,导致 Agent 无法主动检查自己的成果。

图片成功结果现在附带最多两张模型可见预览,已有任务图片可用 inspect 查看。需要查看或分析视频时,Agent 可主动用已有 resolve_local_path 取得文件路径,自行选择抽帧、分析工具或脚本,沿用当前任务的权限处理。

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

  • 关联 Issue / 需求:Agent 能主动检查媒体成果,不要求用户先询问文件位置。
  • 本 PR 包含:图片 MCP image 内容块、当前任务图片检查、媒体工具与能力目录说明、对应回归和媒体规则。
  • 明确不包含:Core 视频解码器、隐藏抽帧窗口、ffmpeg 依赖、视频并发调度、自动验收声音、付费重生成。
  • 用户可见变化:Agent 可以先检查生成图片;需要视频文件时自主取路径并选择查看方式。展示给用户仍用可播放的受管地址。
  • 是否存在 breaking change:无。新增图片 inspect;原有生成字段与路径解析接口保留,插件协议无变化。

UI 变化

不涉及。

  • 引用的设计规范:不涉及。

怎么验证的

自动验证

  • pnpm --dir packages/cindy-tools exec vitest run src/__tests__/ghostMcp.test.ts:96 项通过。
  • pnpm --dir apps/desktop exec vitest run src/main/cindy-media/__tests__/mediaInspection.test.ts src/main/cindy-brain/__tests__/ghostModelImages.test.ts:23 项通过。
  • pnpm --dir apps/desktop exec vitest run src/main/__tests__/inlineImageCompressor.test.ts:3 项通过,验证既有压缩接口保持兼容。
  • pnpm --dir apps/desktop run typecheck、pnpm --dir packages/cindy-tools exec tsc --noEmit、pnpm --dir packages/lizi-mcps exec tsc --noEmit:通过。
  • pnpm check:test-hygiene、pnpm check:dev-docs、git diff --check:通过。

测试价值:

  • mediaInspection.test.ts:调用真实 inspectMedia / previewGeneratedImages,用临时图片文件及内存账本验证像素、归属撤销、损坏文件、批量限制和付费成果保留。原生成测试只验证地址;最小输入是一个任务图片引用,压缩期间撤销任务/账号/引用时必须丢弃像素。另用合法 PNG 加超限字节、4096×4097 像素 PNG 先复现旧实现仍返回预览,再验证超限不影响原始生成成功;高熵 PNG 验证新缩略链路返回可解码、符合字节预算的 WebP。视频输入在读取文件前提示使用路径工具。unit;单独运行 1.01 秒。
  • ghostMcp.test.ts:调用真实 handleMedia,验证 image 内容块与 JSON 元数据分离、失败时不返回像素,以及受管图片/视频路径交接。原测试只验证 JSON;最小输入是带一张预览的完成结果。unit;单独运行 0.630 秒。
  • 既有 ghostWorkdirGate 与 invocationService 覆盖路径解析及 Ask / Auto / Full Access、远程任务、撤权处理;本次没有修改这些路径授权判据。

手工验证

自审完整 diff,确认能力目录和 media 工具不再要求用户先询问路径。内置视频解码器已移除;此前对该解码器的 MP4/WebM smoke 不作为当前视频查看链路的验收证据。

未执行的验证

未运行完整 Agent 创作会话、Windows/Linux 实机或 SSH 跨主机视频分析。Host 路径不保证能在 SSH 工作区直接读取,工具明确标注所属电脑;本次不增加跨主机文件传输。整仓测试交由 CI,本地执行影响面对应的定向测试与类型检查。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:

影响与回滚

  • 图片检查只接受当前账号、当前任务的 session-attachment 受管引用,读取前后和批量返回前复核,校验文件内容指纹。自动最多两张、总内联预算 140 KB。读取前沿用模型图片 6 MiB 输入上限;源图最多 16,777,216 像素,直接从 Buffer 解码,超预算时先缩到最长边 1280,再仅对缩略图调整质量。达标后才编码 Base64,避免原图重复复制、解码。超限保留原始成果,Agent 可取路径自行分析。
  • 路径用途说明允许为完成当前任务主动分析媒体,但既有权限流程不变:Ask 确认、Auto 按实时审批负责人、本地 Full Access 自动允许;远程任务不借此自动取得控制端路径。路径仍会进入任务记录。
  • 存量插件影响:无;不改插件批准状态、manifest、安装布局或协议。没有数据库迁移或新增依赖。
  • 回滚 / 降级方式:移除图片预览和 inspect 路由、还原工具说明;原始媒体与生成状态保留,预览失败不会重新付费生成。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名
  • UI 改动已在「UI 变化」注明不涉及
  • 未提交凭证、令牌或授权文件
  • 已核对受影响的文档并同步旧结论
  • 已确认测试结果或说明未执行原因

@dashhuang
dashhuang requested a review from a team as a code owner October 29, 2026 22:47
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T03:57:44.476622Z d7f0a46 New commits
🔒 Security Review ✅ Completed 2026-10-30T04:00:50.709399Z d7f0a46 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The PR changes how Agents inspect generated and task-owned media.

整体可以合并;建议修正未知时长视频无法返回首帧的问题。

Findings

  1. P2 未知时长视频无法取首帧 ▶
Fix with agent prompt
### Issue 1
apps/desktop/src/main/cindy-media/videoInspection.ts:66
`extractVideoFrames` 会把没有有限时长元数据的视频直接判为越界,连默认请求零秒也不例外。浏览器 `MediaRecorder` 生成的 WebM 可以正常解码,但 `video.duration` 仍为 `Infinity`;此时首帧已经加载,这里的判断却让整个检查返回 `VIDEO_PREVIEW_FAILED`。原视频交付不受影响,但 Agent 无法查看画面。

建议区分“时长未知”和“时间越界”,允许读取已加载的首帧,并补充对应回归测试。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

本 PR 让 Agent 直接查看当前任务的受管媒体,不再先获取本机路径。

  • Successful image requests and polls now include previews for the Agent.
  • The Agent can inspect images and selected video frames from its current task.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[图片生成成功或 poll 完成] --> B[提交当前任务媒体引用]
  B --> C[最多预览两张图片]
  D[inspect 当前任务受管地址] --> E[检查账号与任务引用]
  C --> E
  E --> F[读取并核对文件指纹]
  F --> G{媒体类型}
  G -->|图片| H[检查图片并适配大小]
  G -->|视频| I[隐藏沙箱窗口抽帧]
  I --> H
  H --> J[再次核对账号与任务引用]
  J --> K[MCP 文字元数据与图片内容块]
Loading

Reviews (1) · Last reviewed commit: "fix(media): 让 Agent 直接检查生成图片和视频帧" · Reviewed by Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ae8f91d03b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
@dashhuang
dashhuang force-pushed the dash/media-agent-preview branch from ae8f91d to 987b32c Compare October 30, 2026 03:40
@dashhuang dashhuang changed the title fix(media): 让 Agent 直接查看生成图片与视频帧 fix(media): 图片直接预览,视频由 Agent 获取路径自主查看 Oct 30, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 987b32c2d0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
@MagicLizi

Copy link
Copy Markdown
Contributor

Review report · PR #7970 fix(media): 图片直接预览,视频由 Agent 获取路径自主查看

  • head d7f0a46e222236375a03fa3bae0764ad10f82fd8 / base 1dbff37a891f3d4c660f326084876e09598d80bf / baseRef main
  • diffHash 3e8d174d9dcd6cb11e3eb0b2649bc191d1d351d572941bf280023096e2c935b0
  • 审查档位:heavy(危险写法软命中 4 处,已逐条定性,见「恶意代码与数据外发专项」)
  • 维护者确认门:rules / pluginBase / arch 三类触发均已由最终维护者集合成员 zqchris 以 GitHub Approve 放行(authorIsMaintainer,无遗留标签/确认 issue)。

Findings

没有 P0/P1。

(heavy 档专项定性,均非缺陷,记录如下供复核:)

  1. mediaInspection.ts:readMedia 的 fs.open/read:O_RDONLY|O_NOFOLLOW、stat.isFile()、size 上限 6 MiB 先于分配、读取后逐字节 sha256 与受管地址核对、文件增长/替换判 MEDIA_SOURCE_CHANGED;错误文案不含宿主路径与解码器诊断。安全。
  2. Buffer.alloc(stat.size + 1) 以文件 size 为界:size 已被 6 MiB(GHOST_MODEL_IMAGE_MAX_BYTES)截断,分配有界。安全。
  3. Base64 转换:只对 ≤140 KB(GHOST_MODEL_IMAGE_BUDGET_BYTES)达标后的预览做编码,原图不进 Base64,不塞 JSON 文字。安全。
  4. sharp 解码不受信字节:limitInputPixels: 16_777_216、failOn: 'warning',输出走最长边 1280 缩略图 + 既有 compressInlineImage 阶梯,最终 byteLength <= targetBytes 才返回,否则丢弃预览。安全。

数据外发核对:预览像素只进 MCP image 内容块随工具结果交给当前模型;不进 JSON 文本、不新建媒体副本、不自动发 IM、无新增网络目的地、无新增第三方依赖(sharp、better-sqlite3、drizzle 均为既有依赖;security-scan 确认本 PR 未新增/升级依赖)。错误返回与 preview_errors 均为稳定文案,不含路径。

Rule coverage

按 rule-map 命中读取并逐项核对(只审本 PR 新增/修改代码):

  • AGENTS.md(仓库边界、安全底线、Git 交付):只动客户端仓;未触碰凭证/密钥路径。
  • docs/dev-rules/development-workflow.md(P0/P1/P2 口径、验证真实性):PR 模板三段齐、验证命令已由本审查独立复跑(见 Verification),未发现虚报。
  • docs/dev-rules/media-storage-and-protocols.md(媒体、cindy-media://、路径揭示、引用回收):
    • 默认不向 Renderer/插件/远端暴露绝对路径 —— inspect 只返回像素与受管地址,错误与结果均无 absPath(测试断言结果不含临时根路径);路径揭示仍唯一走既有 resolve_local_path + requestMediaPathRevealConfirm(Ask/Auto/Full Access 流程未改动)。
    • 只认 cindy-media://blobs/ 本机受管副本:parseBlobUrl + resolveSafe 严格校验,外部 URL、绝对路径、../ 穿越在读文件前拒绝(测试覆盖)。跨任务引用拒绝(MEDIA_NOT_IN_TASK)。
    • 引用归属:readSessionMedia 用单条 join 查询同时观察会话状态(deleted/cleared 代次)与 session-attachment 引用,读取前/读取后/批量返回前均复核;账号、任务实例、DB snapshot 任一变化即丢像素(7 种撤销竞态测试覆盖)。
    • 预览失败不影响已付费成果:unavailable() 保留原 xdt_image_urls 与成功状态,文案明确「不要重新生成」。符合规则文档本次同步改写的口径。
    • 规则文档本次修改(inspect 无需先揭示路径、主动取路径分析媒体)属审查判据变更,已由维护者确认门放行;正文与实现一致(140 KB 预算、6 MiB 输入上限、16,777,216 像素、1280 缩略、最多两张、超限省略预览保留成果)。
  • docs/dev-rules/electron-security-and-process-boundaries.md / engineering-conventions.md(Desktop main):main 进程内新增纯函数模块,无新增 IPC/BrowserWindow/WebView 面;日志只在既有压缩器 warn(字节数等元数据,无像素/路径内容)。
  • docs/dev-rules/architecture-invariants.md(apps/desktop/src/main/、共享 package 依赖方向):cindy-tools 只新增 action 判别联合与 MCP 结果组装,不反向依赖 desktop;desktop 经既有 callMedia dep 注入。方向不变。
  • docs/dev-rules/credentials-and-local-storage.md:无凭证;测试用 fs.mkdtemp 临时目录并在 afterEach 清理,不落敏感 fixture。
  • docs/dev-rules/plugin-security-and-authoring.md(插件基座:ghost.ts / mcpServer.ts / types.ts):
    • 存量插件兼容红线:全部为加法变更。action 枚举新增 inspect(旧值不变);handleMedia 返回体的 JSON 文本字段只增不减(previews/preview_errors/previews_omitted/preview_hint 为新增键,modelImages 从 JSON 剥离、只走 image 内容块,与 ghost_call 既有 McpGhostCallResult 形态一致);CindyMediaToolRequest 判别联合加分支,唯一消费方 invocationService 已同步拒绝 inspect 直连(防御纵深,强制走 Host 授权入口)。旧插件调用旧行为不变,无需重装/重批。
    • 插件基座改动已过白名单确认门(pluginBase 触发由 zqchris Approve 放行)。
  • docs/dev-rules/remote-and-mobile-adaptation.md:inspectionContext.isCurrent 复用 getLiveSessionGrantState 的会话实例活性;远程任务不借此取得控制端路径(resolve_local_path 既有审批未动);无新增 IPC channel。
  • packages/maker-core 不在改动范围;工具说明(D_MEDIA、capabilities.ts)与实际行为一致,无「之后一定弹确认卡」类误导表述。

Verification

实际执行(本 worktree,命令退出码如实记录):

  • node scripts/security-scan.mjs --base 1dbff37a:exit 0。依赖扫描:本 PR 未新增/升级第三方依赖,无需 audit;semgrep(仅新增代码,p/javascript + p/nodejs):0 条。
  • pnpm --dir packages/cindy-tools exec vitest run src/__tests__/ghostMcp.test.ts:96 passed(与 PR 声称一致)。
  • pnpm --dir apps/desktop exec vitest run src/main/cindy-media/__tests__/mediaInspection.test.ts src/main/cindy-brain/__tests__/ghostModelImages.test.ts:23 passed(一致)。
  • pnpm --dir apps/desktop exec vitest run src/main/__tests__/inlineImageCompressor.test.ts:3 passed(既有压缩接口兼容,一致)。
  • pnpm --dir apps/desktop run typecheck / pnpm --dir packages/cindy-tools exec tsc --noEmit / pnpm --dir packages/lizi-mcps exec tsc --noEmit:exit 0。
  • pnpm check:test-hygiene(PASS, 359 files)、pnpm check:dev-docs(0 skipped/todo)、git diff --check 1dbff37a..HEAD:通过。
  • CI:pr-design-basis / client-ci / PR fix(media): 图片直接预览,视频由 Agent 获取路径自主查看 #7970 全部 completed+success(双源判 pass)。
  • 未执行:完整 Agent 创作会话、Windows/Linux 实机、SSH 跨主机视频分析(PR 已如实声明;O_NOFOLLOW 在 Windows 退化为 0,但返回字节仍强制 sha256 与受管地址一致,无内容外泄面)。UI 证据不适用(无 UI 改动)。

Intent alignment

  • 描述来源:当前 PR body(fix(media),关联需求「Agent 能主动检查媒体成果,不要求用户先询问文件位置」);读取时间 2026-10-30T06:5xZ。body 随修复改写过(现明确「不包含 Core 视频解码器」),已按下述提交历史对照。
  • 初始实现:efde6c0fa8c47ac82cd61f2d5b563e7dadf28629(「让 Agent 直接检查生成图片和视频帧」,含 videoInspection.ts 隐藏解码窗抽帧,图片 48 MiB / 视频 64 MiB 上限,经 fitGhostModelImages 转 Base64 重编码)。实际读取该 revision 代码核对。
  • 待合并 head:d7f0a46e222236375a03fa3bae0764ad10f82fd8(4 个提交,均在本 PR 内)。
  • 对照结论(一致,视频实现方式合理收窄,不判偏离):
原目标/初始行为 最终行为与影响 代码/提交证据 变化依据
Agent 可主动检查生成图片(初始:48 MiB 上限、整图转 Base64 重编码) 图片可主动 inspect + 自动附最多两张预览;改为 6 MiB 输入上限 + Buffer 直接解码 16,777,216 像素上限 + 1280 缩略链路 efde6c0f → d7f0a46e22(mediaInspection.ts、inlineImageCompressor.ts:prepareInlineImagePreview) Codex P1(PRRT_kwDOTgdRUs6x1qrC,48 MiB 反复复制/解码可致主进程卡顿崩溃)+ 作者修复说明;同目标的安全加固
Agent 可主动看视频帧(初始:Core 内 videoInspection.ts 隐藏 Chromium 解码窗抽帧) Core 不解码视频;Agent 用 resolve_local_path 取路径后自行选择抽帧/分析工具,权限流程不变 4146887c → 987b32c2d0(删除 videoInspection.ts 87 行及解码窗豁免登记) Codex P1(PRRT_kwDOTgdRUs6x6Nhg,64 MiB 视频整段进 Base64/data URL + 隐藏渲染进程解码、并发放大)与 Greptile P2(未知时长视频);均绑定具体资源/DoS 证据,属安全加固下对同一目标的实现替换
不要求用户先询问文件位置才能检查成果 inspect 无需先揭示路径;主动分析媒体可调 resolve_local_path,仍走 Ask/Auto/Full Access 审批 mcpServer.ts D_MEDIA、docs/dev-rules/media-storage-and-protocols.md 183-218 需求原文即此目标;权限判据未放宽(requestMediaPathRevealConfirm 未改动)
成果交付不受检查影响 预览失败/超限保留 xdt_image_urls 与成功状态,不引导重复付费 previewGeneratedImages.unavailable() PR body 与回归测试一致

多轮 Codex/Greptile 意见均限于内存/DoS 与解码健壮性,未改变产品方向;已 Resolve 的 3 条 thread 的修复承诺与最终代码逐条相符(视频抽帧确已整体移除、输入上限确已改为 6 MiB/像素上限/缩略链路)。无确认偏离,无需用户裁定事项。存疑项:无(初始实现 4 个提交完整可核验)。

Overall

pass —— 没有 P0/P1;原意一致性复核完成,无待裁定方向问题。建议按仓库策略合并。

@MagicLizi
MagicLizi merged commit 08c0a10 into main Oct 30, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants