[PR #5611] [CLOSED] feat(markdown): stream-aware pre-processor for partial links #5500

Closed
opened 2026-06-05 15:21:33 -04:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Mintplex-Labs/anything-llm/pull/5611
Author: @Alminc91
Created: 5/11/2026
Status: Closed

Base: masterHead: feat/stream-aware-markdown-preprocessor


📝 Commits (10+)

  • 7f1c57a Enhance temperature control and improve OpenAI API consistency
  • c785058 newest embed state
  • 83d4c8d feat: RBAC enhancements for SaaS billing model v2.2
  • 106433b Merge upstream/master with RBAC enhancements
  • 8114bda fix: RBAC refinements for SaaS billing model
  • afb524c docs: Fix directory path in BUILD.md (anythingllm not anything-llm)
  • ea249ca docs: Add DEV_SETUP.md with local development instructions
  • 8540ea0 feat: Add multilingual TTS normalizer and STT endpoint
  • d4b7281 fix: Pin n2words to 1.21.0 for Node 18 compatibility
  • 80cb027 feat: Auto-generate weekday/month abbreviations via Intl

📊 Changes

209 files changed (+44466 additions, -717 deletions)

View changed files

.claude/skills/review-code.md (+175 -0)
📝 .gitignore (+2 -0)
BROWSER-TEST-DATEPICKER.md (+226 -0)
BUILD.md (+67 -0)
CHANGELOG.md (+272 -0)
CLAUDE.md (+128 -0)
DEV.md (+61 -0)
DEV_SETUP.md (+119 -0)
ROADMAP.md (+341 -0)
ROLE_UPGRADE_PATH.md (+155 -0)
📝 collector/processLink/convert/generic.js (+108 -17)
📝 collector/processRawText/index.js (+5 -1)
📝 docker/Dockerfile (+5 -0)
📝 docker/docker-compose.yml (+18 -11)
📝 docker/docker-entrypoint.sh (+57 -3)
docker/get-docker.sh (+694 -0)
frontend/package-lock.json (+8282 -0)
📝 frontend/package.json (+1 -0)
📝 frontend/public/embed/anythingllm-chat-widget.min.css (+1 -1)
📝 frontend/public/embed/anythingllm-chat-widget.min.js (+5 -5)

...and 80 more files

📄 Description

Summary

  • Eliminate 400ms+ visual pauses during LLM streaming when partial markdown links arrive
  • Pre-process buffer with regex that converts unfinished [Text](url-streaming to **Text** (bold), making link text visible immediately
  • Once closing ) streams in, the regex no longer matches and markdown-it renders the full <a href> normally
  • Same approach ChatGPT/Claude.ai use in their frontends

Why

RAG course listings with [**Title**](URL) constructs created the dominant perceived "stutter" in chatbot output. Long URLs (~80 chars) stream as markdown tokens that are invisible until complete — user sees a pause for the entire URL duration. With this pre-processor, link text appears immediately as bold text, then upgrades to a real link once the URL is complete.

Measurements (praesentation chatbot, gemma-4-31b-mtp, RAG course list)

Metric Before After
Longest perceived pause 455 ms 69 ms
Pauses > 300 ms 1 0
Pauses > 200 ms 2 0
Pauses > 100 ms 3 0
Output token rate unchanged unchanged

Implementation

frontend/src/utils/chat/markdown.js — 11 lines added, 1 changed:

function streamSafePreprocess(text) {
  return text.replace(/\[([^\]]+)\]\([^)\s]*$/, "**$1**");
}

export default function renderMarkdown(text = "") {
  return markdown.render(streamSafePreprocess(text));
}

The regex only matches at the very end of the input buffer ($ anchor), so completed links elsewhere in the text are never touched.

Test plan

  • Live-tested in praesentation container
  • Visual confirmation: course list streams smoothly with **Title** appearing first, link activating when URL completes
  • Other markdown (bold mid-text, lists, code blocks) unaffected
  • Roll out to all customer containers after merge

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Mintplex-Labs/anything-llm/pull/5611 **Author:** [@Alminc91](https://github.com/Alminc91) **Created:** 5/11/2026 **Status:** ❌ Closed **Base:** `master` ← **Head:** `feat/stream-aware-markdown-preprocessor` --- ### 📝 Commits (10+) - [`7f1c57a`](https://github.com/Mintplex-Labs/anything-llm/commit/7f1c57a202497bc3c4aaee44d13984ce8ada2e1d) Enhance temperature control and improve OpenAI API consistency - [`c785058`](https://github.com/Mintplex-Labs/anything-llm/commit/c785058384a2e38f9bfd2b2fb15735e9979fee6f) newest embed state - [`83d4c8d`](https://github.com/Mintplex-Labs/anything-llm/commit/83d4c8d047c764c63566870f810a3b175184a536) feat: RBAC enhancements for SaaS billing model v2.2 - [`106433b`](https://github.com/Mintplex-Labs/anything-llm/commit/106433bbd2f91fa6ab8de470d8a66832322a0dc0) Merge upstream/master with RBAC enhancements - [`8114bda`](https://github.com/Mintplex-Labs/anything-llm/commit/8114bda72956d448fb1e747f1dee4e56ce722875) fix: RBAC refinements for SaaS billing model - [`afb524c`](https://github.com/Mintplex-Labs/anything-llm/commit/afb524cfb66d308a66c002eb497865082c43b134) docs: Fix directory path in BUILD.md (anythingllm not anything-llm) - [`ea249ca`](https://github.com/Mintplex-Labs/anything-llm/commit/ea249ca84372c8a3366ba866e81b254304690616) docs: Add DEV_SETUP.md with local development instructions - [`8540ea0`](https://github.com/Mintplex-Labs/anything-llm/commit/8540ea076f7102dd72c6b254b03b615e81c08a8b) feat: Add multilingual TTS normalizer and STT endpoint - [`d4b7281`](https://github.com/Mintplex-Labs/anything-llm/commit/d4b72813169ba2b2b592b20f628356c71d3a52a5) fix: Pin n2words to 1.21.0 for Node 18 compatibility - [`80cb027`](https://github.com/Mintplex-Labs/anything-llm/commit/80cb0277988639122ca54641ff04b755cb007aba) feat: Auto-generate weekday/month abbreviations via Intl ### 📊 Changes **209 files changed** (+44466 additions, -717 deletions) <details> <summary>View changed files</summary> ➕ `.claude/skills/review-code.md` (+175 -0) 📝 `.gitignore` (+2 -0) ➕ `BROWSER-TEST-DATEPICKER.md` (+226 -0) ➕ `BUILD.md` (+67 -0) ➕ `CHANGELOG.md` (+272 -0) ➕ `CLAUDE.md` (+128 -0) ➕ `DEV.md` (+61 -0) ➕ `DEV_SETUP.md` (+119 -0) ➕ `ROADMAP.md` (+341 -0) ➕ `ROLE_UPGRADE_PATH.md` (+155 -0) 📝 `collector/processLink/convert/generic.js` (+108 -17) 📝 `collector/processRawText/index.js` (+5 -1) 📝 `docker/Dockerfile` (+5 -0) 📝 `docker/docker-compose.yml` (+18 -11) 📝 `docker/docker-entrypoint.sh` (+57 -3) ➕ `docker/get-docker.sh` (+694 -0) ➕ `frontend/package-lock.json` (+8282 -0) 📝 `frontend/package.json` (+1 -0) 📝 `frontend/public/embed/anythingllm-chat-widget.min.css` (+1 -1) 📝 `frontend/public/embed/anythingllm-chat-widget.min.js` (+5 -5) _...and 80 more files_ </details> ### 📄 Description ## Summary - Eliminate 400ms+ visual pauses during LLM streaming when partial markdown links arrive - Pre-process buffer with regex that converts unfinished `[Text](url-streaming` to `**Text**` (bold), making link text visible immediately - Once closing `)` streams in, the regex no longer matches and markdown-it renders the full `<a href>` normally - Same approach ChatGPT/Claude.ai use in their frontends ## Why RAG course listings with `[**Title**](URL)` constructs created the dominant perceived "stutter" in chatbot output. Long URLs (~80 chars) stream as markdown tokens that are invisible until complete — user sees a pause for the entire URL duration. With this pre-processor, link text appears immediately as bold text, then upgrades to a real link once the URL is complete. ## Measurements (praesentation chatbot, gemma-4-31b-mtp, RAG course list) | Metric | Before | After | |---|---:|---:| | Longest perceived pause | 455 ms | **69 ms** | | Pauses > 300 ms | 1 | **0** | | Pauses > 200 ms | 2 | **0** | | Pauses > 100 ms | 3 | **0** | | Output token rate | unchanged | unchanged | ## Implementation `frontend/src/utils/chat/markdown.js` — 11 lines added, 1 changed: ```js function streamSafePreprocess(text) { return text.replace(/\[([^\]]+)\]\([^)\s]*$/, "**$1**"); } export default function renderMarkdown(text = "") { return markdown.render(streamSafePreprocess(text)); } ``` The regex only matches at the very end of the input buffer (`$` anchor), so completed links elsewhere in the text are never touched. ## Test plan - [x] Live-tested in praesentation container - [x] Visual confirmation: course list streams smoothly with `**Title**` appearing first, link activating when URL completes - [x] Other markdown (bold mid-text, lists, code blocks) unaffected - [ ] Roll out to all customer containers after merge --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-06-05 15:21:33 -04:00
yindo closed this issue 2026-06-05 15:21:33 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Mintplex-Labs/anything-llm#5500