# Optional chat Markdown

> ROM 0.1.5. [Release artifacts](https://git.cybernomad.it/pmikstacki/ROM/releases/tag/v0.1.5).
> Matching package version: 0.1.0-alpha.8. Archive SHA-256: bf6620cd2467f45ce5afc5e803f88bb2401f9c609c58616aaf14b9f887876255.
> Guide origin: package archive.


Import `ChatMarkdown` from `rom-ui/chat/markdown`.
The default `rom-ui/chat` entry retains plain text and does not import the renderer.

Install `svelte-streamdown@4.2.1` in the consuming application with pnpm.
Set the application's `pnpm.overrides.katex` to `0.18.2`.
The installed candidate qualifies this version combination. An upstream dependency range alone does not select the patched KaTeX version.

Supply plain text as `content` and the session's current authority token.
Supply exact HTTPS origins through `allowedOrigins` to enable links.
With no approved origins, model text cannot create a navigable link.
Relative application links remain text. Credentials in link URLs are rejected.
The adapter disables raw HTML and renders image alternatives without fetching images.
Math and diagram tokens remain literal content unless the host supplies the optional rich components.

The renderer accepts up to 16384 UTF-16 code units by default.
Longer content remains complete plain text. The fallback does not truncate the message.
`maxChars` can select a positive safe integer up to 262144.
An invalid limit also selects the plain-text fallback.
The tested limit does not establish performance at the largest permitted value.

```svelte
<script lang="ts">
  import { ChatMarkdown } from 'rom-ui/chat/markdown';
  let { content, authority }: { content: string; authority: unknown } = $props();
</script>
<ChatMarkdown {content} {authority} allowedOrigins={['https://example.com']} />
```

The host owns message identity, model transport, cancellation, persistence, and recovery.
Update content and the authority token together when the session changes.
Do not retain another session's disclosed message text in host props.

Six installed-consumer Chromium and WebKit checks pass for SSR/hydration, updates, authority replacement, URL/image restrictions, and long-text fallback.
The comparison fixture also checks incremental fences, tables, replay, and longer responses against the pinned upstream renderer.
These checks do not establish a model transport or a complete redesigned ROM chat.

## Opt in to rich rendering

Import the qualified components separately. Pass them through `rich` to enable KaTeX equations and Mermaid diagrams.
Omit `rich`, or supply only one component, to retain literal rendering for the other token type.

```svelte
<script lang="ts">
  import { ChatMarkdown } from 'rom-ui/chat/markdown';
  import { chatMarkdownRich } from 'rom-ui/chat/markdown/rich';
  let { content, authority }: { content: string; authority: unknown } = $props();
</script>
<ChatMarkdown {content} {authority} rich={chatMarkdownRich} />
```

The adapter keeps KaTeX trust disabled and Mermaid in strict mode.
Raw Markdown HTML, images, and link origins retain the policies described above.
Incomplete diagram fences and diagram sources above 8192 code units remain literal text.
Each rendered diagram includes an expandable source, including when its syntax cannot render.
An authority change destroys the previous renderer before showing the replacement content.

The `rich` object can also supply trusted, bundled Svelte components for `math` and `mermaid`.
These components execute application code. The host owns their behavior and must not load component code from model output.
