From eff5c4a2d99732e0c0ade49b51cc164bef7f4aa7 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Tue, 11 Aug 2026 03:44:06 +0200 Subject: [PATCH] feat: parse :::writing block metadata and use the subject as the block title (#28280) Newer OpenAI chat models put metadata on the opening line of a colon fence block, like :::writing{variant="email" id="48173" subject="Short question" recipient="mail@example.com"}. The tokenizer matched that line and discarded it, so every block rendered under the same generic "Writing" heading no matter what it contained. The opening line is now parsed into an attributes map on the token and the header uses it: the subject becomes the title, the recipient follows it and the full string is reachable on hover when the row is too narrow for it. Blocks without metadata render exactly as before, and the other fence types get the parsed attributes for free. Attributes are read only from inside the {...} braces, not from the whole opening line. Scanning the whole line turned ordinary prose containing key="value" into metadata, and it backtracked quadratically: a 40k character opening line took 586ms to parse, and that runs again on every re-lex while the message streams. Anchored to the braces it is 0.0ms. Nothing here turns the recipient into a link or a send action. That metadata is model output and can be steered by whatever is in the context, so a prefilled mail action is a separate decision rather than a side effect of parsing. --- .../Messages/Markdown/ColonFenceBlock.svelte | 20 ++++-- .../marked/colon-fence-extension.test.ts | 69 +++++++++++++++++++ src/lib/utils/marked/colon-fence-extension.ts | 16 ++++- 3 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 src/lib/utils/marked/colon-fence-extension.test.ts diff --git a/src/lib/components/chat/Messages/Markdown/ColonFenceBlock.svelte b/src/lib/components/chat/Messages/Markdown/ColonFenceBlock.svelte index 2206a8735d..71f9d4f2d3 100644 --- a/src/lib/components/chat/Messages/Markdown/ColonFenceBlock.svelte +++ b/src/lib/components/chat/Messages/Markdown/ColonFenceBlock.svelte @@ -18,9 +18,12 @@ export let onTaskClick: Function = () => {}; export let onSourceClick: Function = () => {}; - const fenceType: string = token.fenceType ?? 'default'; + $: fenceType = token.fenceType ?? 'default'; + $: attributes = token.attributes ?? {}; - const label = fenceType.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()); + $: label = + attributes.subject || fenceType.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()); + $: header = attributes.recipient ? `${label} · ${attributes.recipient}` : label; let copied = false; @@ -34,13 +37,16 @@
- -
- - {label} +
+ + {header} -