[Feature] 为 assistant 任务结果增加统一的交付物预览与附件操作区
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 401
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
## 使用场景
用户让 Cindy 完成生成海报、图片、视频、音频、3D 模型或导出文件等任务时,当前聊天通常只能看到 Markdown 文本、工具过程,或某个工具结果里的单张媒体。用户需要自己从正文或工具调用中判断“最终产物是什么、文件在哪里、如何打开”。
对比 Codex 的任务输出体验,用户期望一次任务完成后看到清晰的结果交付区:运行摘要、主产物缩略图、点击放大、下载/复制/Open in 等操作,以及源文件和支持文件附件卡片。
## 现状
桌面端已经具备很多底层能力,但这些能力没有被统一到 assistant 最终回复:
- `ChatImageView` / `ImageLightbox` 已支持点击放大、gallery、缩放、复制、另存为、默认应用打开和发送到对话。
- `cindy-media://` 媒体总仓、媒体引用账本和媒体 IPC 已存在。
- `AgentActionRow` / `MessageStream` 能从 tool result 顶层的 `xdt_image_url(s)`、`xdt_video_urls`、`xdt_audio_tracks`、`_xdt_model_files` 提取并渲染媒体。
- Ghost 卡片支持沙箱 HTML、图片 lightbox 和 `data-ghost-action` 交互。
- 但 `ChatMessage` 没有通用的 assistant-side `artifacts/deliverables` 字段,`images/files` 主要是用户输入附件。
- `AssistantMessage` 普通路径只有 Markdown,Ghost 路径只有自绘 HTML 卡片,没有统一的“主产物 + 附件列表 + 操作行”。
- Ghost 卡片持久化/推送目前主要保存 `callId/ghostId/html/height/state`,没有产物清单、文件名、MIME、尺寸、来源或动作能力。
- 媒体落库目前主要通过扫描消息内容挂 `session-attachment` 引用,能够保住字节,但没有消息级交付物语义。
- `maker-shared/payloadSummary` 已能解析部分媒体 action,但桌面端仍使用自己的媒体解析器,desktop/mobile 对同一 tool result 的 action 展示存在分叉。
相关代码:
- `apps/desktop/src/renderer/lib/ccAgent.types.ts`
- `apps/desktop/src/renderer/lib/makerChatStore.ts`
- `apps/desktop/src/renderer/components/chat/AssistantMessage.tsx`
- `apps/desktop/src/renderer/components/chat/AgentActionRow.tsx`
- `apps/desktop/src/renderer/components/chat/MessageStream.tsx`
- `apps/desktop/src/main/cindy-brain/cardService.ts`
- `apps/desktop/src/main/cindy-brain/cardStoreDb.ts`
- `apps/desktop/src/main/cindy-media/chatAttachments.ts`
## 诉求
为 assistant 的一次 turn 建立统一的交付物投影,使不同来源的产物(tool result、Ghost、Codex/Claude 生成文件、导出文件)都可以用同一套结构渲染:
1. 结果摘要和运行元数据,例如耗时、技能/模式、完成状态。
2. 一个或多个主产物预览,图片/视频可点击进入现有 lightbox。
3. 统一操作行:Preview、Download/Save as、Open in、Copy、Reveal 等。
4. Supporting files 附件卡片:显示文件名、MIME/大小,并提供没有预览时的文件 fallback。
5. 可折叠的 provenance/details:来源工具、源文件、派生关系、hash 等。
6. 历史回放、远程会话和 Ghost 卡片场景保持一致。
7. 对旧消息和旧的 `xdt_*` 字段保持兼容,不能因没有 manifest 而丢失现有媒体。
建议的最小数据形态类似:
```ts
type AssistantArtifact = {
id: string;
role: 'primary' | 'supporting' | 'source';
uri: string;
filename: string;
mime: string;
bytes?: number;
width?: number;
height?: number;
durationMs?: number;
previewUri?: string;
actions?: Array<'preview' | 'download' | 'open' | 'copy' | 'reveal'>;
provenance?: {
sourceAssets?: string[];
tool?: string;
sha256?: string;
};
};
```
第一阶段可以将 manifest 投影到现有 `ChatMessage`/assistant content,不必立即引入远端 server;长期可演进为独立的 message-artifacts 表,并复用现有 `cindy-media` blob/ref 生命周期。
## 建议方案
- 增加 assistant turn 的结构化 output/artifact manifest,并在 live event、消息落库、历史 map 三条路径保持一致。
- 新增通用 `DeliverableStrip`/artifact renderer,复用现有 `ChatImageView`、`ImageLightbox`、文件预览和 media IPC。
- 将现有 `xdt_image_urls` 等字段适配为 artifact,旧工具无需立即改造。
- Ghost 的 card-update 除 HTML 外携带可选 artifact manifest;HTML 保留自定义视觉和插件动作,宿主负责标准附件区。
- 统一 desktop 与 mobile 对 `_xdt_actions`、媒体动作和远程取件状态的安全解析;动作需要 allowlist、inflight 锁和失败态。
- 操作能力由客户端按本机/远程环境过滤,服务端只提供产物语义和安全引用;不要让服务端决定本机具体“Open in”应用。
## 验收标准
- 生成一张图片时,完成消息下方出现稳定的主产物缩略图;点击进入现有图片 lightbox,历史重开后仍可用。
- 同一 turn 生成多张图片时,显示缩略图集合,并支持 gallery/左右切换。
- 生成图片、视频、音频、3D 模型和普通文件时,均有统一附件卡片;不可预览的文件有明确的下载/打开 fallback。
- `Open in`、Save as、Copy、Reveal 等操作在本地、远程和不可用场景正确显示/禁用,并提供错误反馈。
- Ghost 卡片既保留自绘 HTML/交互,又能在卡片下方显示标准化 supporting artifacts。
- 旧的 Markdown 图片和 `xdt_*` tool result 行为不回归;没有 manifest 的消息继续按现有路径渲染。
- assistant live streaming、消息持久化、历史回放、session share 和远程 device-link 至少各有一条测试覆盖。
- 不把 base64 大文件塞进普通 assistant 文本;产物字节继续复用 `cindy-media`。
## 范围说明
这是 desktop/shared packages 的体验与消息投影问题,主 issue 应在 `makecindy/cindy-temp`。当前 `cindy-server` 主要承载认证、设备互联和 Slack hook,不是本地 Maker 聊天 renderer;只有未来要让 artifact 跨 Slack/device-link 传输时,才需要在 `cindy-protocol` 增加相应的跨端契约。
Contributor guide
Research direction
Start by tracing the artifact and message paths in ccAgent.types.ts, makerChatStore.ts, AssistantMessage.tsx, AgentActionRow.tsx, and MessageStream.tsx, then review cardService.ts, cardStoreDb.ts, and chatAttachments.ts. Compare existing xdt_* parsing, Ghost persistence, and media IPC behavior. Done means a compatible assistant artifact projection works across live messages, persistence, history, Ghost cards, and the stated media/file acceptance cases with tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- desktop, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100