Session prose local media paths display through a same-origin file route
会话正文本地媒体路径通过同源文件路由显示
Assistant prose can reference an image by its filesystem path, but browsers cannot read Host files. A renderer limited to absolute HTTP(S) destinations leaves those references as inert alt text. Issue #3662 records this display gap.
English
Problem
Assistant prose can reference an image by its filesystem path, but browsers cannot read Host files. A renderer limited to absolute HTTP(S) destinations leaves those references as inert alt text. Issue #3662 records this display gap.
Decision
Local media paths in Session prose render through a same-origin file route. This note owns the renderer vocabulary and its placement; authenticated filesystem reads owns the current serving policy and supersedes the workspace/media restrictions described below.
ui-primitives owns the MarkdownPathImages vocabulary on MarkdownText. Like fileMentions, it applies only after a message settles so frozen streaming blocks cannot cache a vocabulary handler. The settled pass rewrites image destinations outside the remote-URL allowlist and emits only absolute http(s), blob, or data results. Without a vocabulary, local destinations retain inert alt text. Failed loads replace the image with authored alt text, or its original destination when alt is empty; a different source can load again.
ui-chat supplies a page-stable localPathMediaUrl vocabulary through AssistantMarkdown. It maps absolute POSIX paths to api/file?path=… resolved against document.baseURI, so the request stays under whatever mount the served document came from. Relative and protocol-relative paths, Windows-style paths, and non-HTTP page transports such as Electron file:// remain inert.
session-controller owns the SessionMediaReferences contribution beside SessionFileReferences. It registers through connection.fetch, which applies the same browser authentication and trust checks as /api RPC. The fixed same-origin endpoint gives the synchronous renderer a stable URL without an asynchronous capability negotiation.
Alternatives considered
Typert gateway or workspace controller ownership. The gateway owns Remote RPC dispatch, while the workspace controller owns registry lifecycle. Neither owns file-byte presentation; Session Controller is the consumer serving Session prose.
Session RPC followed by blob/data URLs. Attachment images can use an asynchronous fetch, but this Markdown vocabulary must synchronously resolve a destination during a memoized render pass.
Image-only endpoints. One file route can serve images, audio, and video without separate URL vocabularies. The current implementation returns complete bounded files; Markdown audio/video player nodes remain independent work.
Byte-signature validation in the route. The model-facing read_image tool owns image admission checks. Display responses describe content by MIME lookup and let browser decoding reject corrupt payloads, avoiding a duplicate signature checker.
Workspace/media-only access (superseded). The original policy restricted canonical paths to registered workspace roots and allowed image/video/audio MIME categories except SVG. Regular-file checks before opening rejected pipes and devices; an opened-handle identity comparison narrowed replacement races. These restrictions bounded authenticated access and avoided a per-request interactive authorization flow. They also excluded temporary screenshots and remote files; the successor note records the replacement policy and why those restrictions are not retained.
Consequences
The Client vocabulary cannot bypass Host authentication or the filesystem provider. The original restricted route distinguished an existing outside-workspace path from an absent path, exposing existence even while refusing its bytes; the successor policy instead permits ordinary provider-readable files.
Windows-style authored paths remain unsupported by the Client vocabulary. Trajectory and tool-card Markdown consumers do not supply this vocabulary, and audio/video Markdown nodes do not render players. These are renderer limitations, independent of the file route's readable MIME types.
The archived model-readable image paths note owns the model-facing behavior; this note owns user-facing display and does not supersede it.
Testing
Renderer tests cover settled and streaming gates, reference-style images, protocol rechecks, failed-load fallback, and replacement sources. Chat tests cover the vocabulary and component wiring. The browser scenario in apps/web/tests/markdown-images.e2e.ts boots the shipped Web composition with a seeded Session and checks actual loading and fallback text. A model-driven recorded Session round trip remains separate from this UI expectation; the successor note names current route coverage.
中文
Problem
Assistant 正文可能通过文件系统路径引用图片,但浏览器无法读取 Host 文件。仅允许绝对 HTTP(S) 目标的渲染器会把这些引用保留为静态 alt 文本。Issue #3662 记录了这一展示缺口。
Decision
Session 正文中的本地媒体路径通过同源文件路由渲染。本记录拥有渲染器词表及其归属;鉴权文件系统读取拥有当前文件服务策略,并取代下文的工作区与媒体限制。
ui-primitives 拥有 MarkdownText 上的 MarkdownPathImages 词表。与 fileMentions 一样,它只在消息稳定后生效,使冻结的流式块无法缓存词表处理函数。稳定渲染过程重写远程 URL 白名单之外的图片目标,并只输出绝对 http(s)、blob 或 data 结果。没有词表时,本地目标保留静态 alt 文本。加载失败会把图片替换为作者提供的 alt 文本;alt 为空时显示原始目标路径;不同来源仍可重新加载。
ui-chat 通过 AssistantMarkdown 提供页面稳定的 localPathMediaUrl 词表。它把绝对 POSIX 路径映射到相对 document.baseURI 解析的 api/file?path=…,因此请求始终停留在所服务文档来源的那个挂载之下。相对路径、协议相对路径、Windows 风格路径,以及 Electron file:// 等非 HTTP 页面传输保持静态回退。
session-controller 在 SessionFileReferences 旁拥有 SessionMediaReferences 贡献。它通过 connection.fetch 注册;该通道执行与 /api RPC 相同的浏览器鉴权和信任检查。固定同源端点让同步渲染器获得稳定 URL,无需异步能力协商。
Alternatives considered
由 Typert gateway 或 workspace controller 拥有。 gateway 拥有 Remote RPC 分发,workspace controller 拥有注册表生命周期。两者都不拥有文件字节展示;Session Controller 是服务 Session 正文的消费方。
先经 Session RPC 获取,再使用 blob/data URL。 附件图片可以异步获取,但此 Markdown 词表必须在记忆化渲染过程中同步解析目标。
图片专用端点。 单一文件路由即可服务图片、音频和视频,无需独立 URL 词表。当前实现返回有界完整文件;Markdown 音视频播放器节点仍是独立工作。
路由中的字节签名校验。 面向模型的 read_image 工具拥有图片准入检查。展示响应通过 MIME 查询描述内容,由浏览器解码拒绝损坏载荷,避免重复实现签名检查器。
仅限工作区与媒体的访问(已取代)。 原策略把规范路径限制在已注册工作区根目录内,并允许除 SVG 外的 image/video/audio MIME 类别。打开前的普通文件检查拒绝管道与设备;已打开句柄的身份比较收窄替换竞态。这些限制约束了鉴权后的访问范围,并避免每次请求的交互授权流程。它们也排除了临时截图与远程文件;后续记录说明替代策略及不保留这些限制的理由。
Consequences
客户端词表无法绕过 Host 鉴权或文件系统提供方。原受限路由区分了工作区外已存在路径与缺失路径,即使拒绝其字节仍暴露存在性;后续策略则允许提供方可读的普通文件。
客户端词表仍不支持作者提供的 Windows 风格路径。轨迹与工具卡片 Markdown 消费方不提供此词表,音视频 Markdown 节点也不渲染播放器。这些属于渲染器限制,与文件路由可读的 MIME 类型无关。
已归档的模型可读图片路径记录拥有模型侧行为;本记录拥有用户侧展示,不取代它。
Testing
渲染器测试覆盖稳定与流式门禁、引用式图片、协议复查、加载失败回退和来源替换。聊天测试覆盖词表与组件连接。apps/web/tests/markdown-images.e2e.ts 浏览器场景使用已播种 Session 启动交付的 Web 组合,检查实际加载与回退文本。模型驱动的记录 Session 往返仍独立于此 UI 期望;后续记录说明当前路由覆盖。