Skip to content

Chat: draw ```svg fences as themed figures, as Mermaid fences are #2441

Closed

Description

@affeek

Problem

omp asks its model to draw diagrams and mockups as ```svg fences: its system prompt says the fence "renders inline as an image" and gives a small color vocabulary (currentColor, `var(--fg)`, `--muted`, `--border`, `--surface`, `--accent`, `--success`, `--warning`, `--error`, `--c1`…`--c6`) on a transparent background. omp's own TUI rasterizes these fences in Kitty or iTerm-style terminals. Inside a herdr pane it has no image protocol, and in Ovis Chat the fence shows as a plain code block, so the figure the answer is built around is never seen.

Proposal

Chat draws a svg fence the way it already draws a mermaid one:

  • The figure is an <img> from a data:image/svg+xml URL, never markup in the page, so a script, event handler or external reference in agent output does nothing. CSP already allows img-src data:.
  • Before the URL is made, the color tokens resolve to the current theme's roles (--fg → --text, --muted → --text-dim, --surface → --bg-elevated, --c1…--c6 → the syntax roles, and so on). The root gets color for currentColor, a sans-serif font, the SVG namespace and a size from its viewBox, because an image document inherits none of these. A theme change redraws it.
  • A fence that is not a whole <svg>…</svg> yet (still streaming), or an image that fails to decode, stays the code block it is.
  • The enlarge button and the existing Mermaid lightbox (zoom, pan, fit) work for it unchanged.

Where

Chat and prompt cards

Where it exists today

omp's TUI draws these fences inline as themed images (packages/tui/src/chat/svg-source.ts, prepareSvg), so an omp answer reads differently in a Kitty or Ghostty terminal than in Ovis. In Ovis, Mermaid fences already get this treatment (#782).

Workarounds and alternatives

Today the only way to see the figure is to copy the fence into a file and open it. Injecting the SVG into the DOM through a sanitizer was the alternative; the <img> route needs no sanitizer dependency and cannot run anything.

Implementation

I have a branch ready, rebased on main at 0.4.21: main...affeek:ovis:feat/chat-svg-fences (src/lib/svgFigure.ts with unit tests, SvgFigure beside MermaidDiagram in Markdown.tsx, an optional src on MermaidLightbox, CSS, a changelog fragment, and a THIRD_PARTY_NOTICES entry for the adapted token resolution, MIT). bun run check fast: workflow syntax, generated types and themes, typecheck and build pass; the unit run fails only in server/conversation.test.ts, server/voice.test.ts and scripts/install-node-fallback.test.ts, which also fail on an unchanged 0.4.20 checkout on my machine. I checked it in a browser against a live omp chat, inline and in the lightbox. I will open the PR once you agree to the feature.
The branch and this request were prepared by my AI coding agent.

Activity

  1. added a commit that references this issue on Oct 31, 2026
    37a009f
  2. added a commit that references this issue on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions