Skip to content

Rich message rendering ​

Contract between the Liminal harness (what the model may emit) and each UI shell (what users actually see).

Harness output ​

The harness streams assistant text on the text channel (channel: "assistant"). The system prompt (packages/tools/src/systemPrompt.ts) encourages:

FormatUse case
GFM markdownProse, tables, task lists, > [!NOTE] callouts, fenced code
Raw HTMLGradient cards, flex layouts, KPI blocks, “Bottom line” panels
```html fencesSame as raw HTML; preferred for large blocks; streams live on web/desktop
Images![](https://…) or data:image/…
VideoBare YouTube/Vimeo URLs or links
User attachments ```attached_images block (vision workflow) + generic files via composer (see Compose dock & attachments)

Tool rows, harness trace, and working-state snapshots are not rich-rendered.

Persistent desktop widgets (weather panels, calculators, live dashboards) are not chat HTML — the agent uses spawn_app and separate OS windows. See Liminal desktop apps.

Web UI (reference) ​

Implementation: packages/web/client/liminalMarkdown.tsx, App.tsx assistant case.

  • GFM via remark-gfm
  • Inline HTML via rehype-raw + rehype-sanitize
  • Fenced HTML via HtmlEmbedBlock + streaming fence split (liminalMarkdownUtils.ts)
  • Prism for code fences; html/htm/xhtml fences → live HTML
  • Custom img, YouTube/Vimeo iframes, alert blockquotes

Desktop UI ​

Implementation: apps/liminal_desktop/lib/ui/rich_message/.

CapabilityDesktop
GFMflutter_markdown + ExtensionSet.gitHubWeb
Fenced HTMLHtmlEmbedView (WebView, JS off, sanitized)
Inline HTMLflutter_widget_from_html (sanitized)
Code fencesflutter_highlight (non-html langs)
Imageshttps:, data:image/*, workspace /media?path=
VideoYouTube/Vimeo embed WebView
User image attachsend_message.attachments → same wire block as web
Streaming HTML fenceDart port of extractStreamingHtmlFence

Security ​

  • No arbitrary JavaScript in assistant HTML embeds
  • Block file://, javascript:, blob: in untrusted URLs
  • Workspace media only via sidecar GET /media (path under chat workspace root, token-gated)
  • Size caps aligned with DEFAULT_IMAGE_ATTACHMENT_LIMITS

Versioning ​

Render contract changes should update this doc and keep web + desktop in sync. Shared TS utils live in liminalMarkdownUtils.ts; Dart port in liminal_markdown_utils.dart.

Liminal AI · Beta docs (v0.1.2) · Marketing: vireondynamics.com/liminal · Compare: vireondynamics.com/liminal/compare