Skip to content

fix(chat): add RTL support for message text via dir=auto#834

Open
jamesng16 wants to merge 2 commits into
fathah:mainfrom
jamesng16:fix/rtl-message-rendering
Open

fix(chat): add RTL support for message text via dir=auto#834
jamesng16 wants to merge 2 commits into
fathah:mainfrom
jamesng16:fix/rtl-message-rendering

Conversation

@jamesng16

Copy link
Copy Markdown
Contributor

Summary

Fixes #788 — RTL text (Arabic, Persian, Hebrew) renders with broken word ordering and misaligned punctuation in chat messages.

Root Cause

The chat message markdown renderer (AgentMarkdown) has no direction hint. Mixed RTL/LTR content relies entirely on Unicode bidirectional algorithm defaults, which fail when the container has no explicit dir attribute — the browser assumes LTR and renders RTL segments with incorrect ordering.

Fix

Wrap the Markdown component output in <div dir="auto">. This lets the browser auto-detect the text direction based on the first strong directional character:

  • RTL first character (Arabic \u0627, Persian \u067E, Hebrew \u05D0) → direction: rtl, right-aligned, correct bidi ordering
  • LTR first character (English, Vietnamese, Chinese, Cyrillic) → direction: ltr, no behavior change
  • Mixed content handled by Unicode bidirectional algorithm within an isolated context

One file changed: src/renderer/src/components/AgentMarkdown.tsx (+6/-2 lines).

The wrapper only affects text content direction — the chat bubble chrome (avatar, copy button, timestamp) remains LTR.

Testing

  • ✅ All 4 existing AgentMarkdown tests pass
  • No visual change for LTR languages (English, Vietnamese, Chinese)
  • dir="auto" is a standard HTML attribute with broad browser support (Chrome, Firefox, Safari, Edge)
  • No new dependencies, no API changes

jamesng16 added 2 commits July 8, 2026 16:31
Two changes to prevent GitHub API rate limiting on the Discover page:

1. Extend CACHE_TTL_MS from 5 min → 60 min (12× fewer API calls)
2. Use GITHUB_TOKEN/GH_TOKEN env var for authenticated GitHub API
   requests in listFolderFiles — anonymous requests hit the 60 req/h
   limit; authenticated requests get 5 000 req/h.

Fixes errors like 'Failed to load registry' and 'Tree fetch failed (403)'
that users behind shared IPs (VPNs, NAT, geographic regions) see
frequently.
AgentMarkdown now wraps rendered markdown in a <div dir="auto">
so the browser can auto-detect RTL content (Arabic, Persian,
Hebrew, etc.) and render text right-aligned with correct
bidirectional ordering. LTR languages (English, Vietnamese,
Chinese) are unaffected — dir="auto" falls back to LTR when
the first strong character is LTR.

No layout changes: the wrapper only affects text direction
within the message bubble; the bubble itself and its chrome
(avatar, copy button, timestamp) remain LTR.

Fixes fathah#788
@jamesng16 jamesng16 force-pushed the fix/rtl-message-rendering branch from 6387285 to a3da81d Compare July 8, 2026 10:06
@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes RTL text rendering in chat messages by wrapping the AgentMarkdown component's output in <div dir="auto">, and separately reduces GitHub API rate-limit pressure by increasing the registry cache TTL from 5 minutes to 1 hour and adding optional GITHUB_TOKEN/GH_TOKEN authentication for the git-tree fetch against api.github.com.

  • AgentMarkdown.tsx: Adds <div dir=\"auto\"> around the Markdown renderer so Arabic, Persian, and Hebrew messages are auto-detected as RTL; block-level children (paragraphs, headings) independently determine their own direction, so mixed LTR/RTL messages are handled correctly per block.
  • registry.ts: Cache TTL bumped to 1 hour (affects catalog, model, and tree caches); listFolderFiles now passes a Bearer token to api.github.com when the env var is present, raising the anonymous 60 req/h limit to 5,000 req/h.

Confidence Score: 4/5

Safe to merge; changes are small and well-scoped with no functional regressions for LTR languages.

The dir=auto wrapper is the standard HTML mechanism for unknown-direction content and is correct for the common case. The gap worth noting is that CodeBlock does not pin dir=ltr, so a code block whose first strong character is RTL would render right-to-left inside an RTL message. The registry changes are straightforward and the token is correctly guarded and scoped only to the api.github.com endpoint.

AgentMarkdown.tsx — the CodeBlock component root div does not set dir=ltr, so code blocks starting with RTL characters could render right-to-left in an RTL message context.

Important Files Changed

Filename Overview
src/renderer/src/components/AgentMarkdown.tsx Adds <div dir="auto"> wrapper around the Markdown renderer to enable automatic RTL text direction for Arabic, Persian, and Hebrew messages. The approach is correct and standard; a minor edge case exists for code blocks that contain RTL characters (e.g., Arabic comments in code), where direction could be detected as RTL, but PlainCodeView already applies unicodeBidi: isolate as a partial mitigation.
src/main/registry.ts Two changes: (1) cache TTL increased from 5 min to 1 hour—affects all three caches (catalog, model, and tree); (2) optional GITHUB_TOKEN/GH_TOKEN env-var support added to the listFolderFiles tree fetch (api.github.com) to raise the rate limit from 60 req/h to 5000 req/h. The token is correctly applied only to the api.github.com endpoint, not to raw.githubusercontent.com calls.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["AgentMarkdown receives children (string)"] --> B["div dir=auto wrapper"]
    B --> C["Markdown component (react-markdown)"]
    C --> D["Block-level descendants rendered"]
    D --> E{"First strong Unicode char in block element"}
    E -->|"Arabic / Hebrew / Persian"| F["direction: rtl, right-aligned"]
    E -->|"Latin / CJK / Cyrillic"| G["direction: ltr, left-aligned"]
    F --> H["Code blocks independently evaluate content"]
    G --> H
    H --> I{"Code first-char type"}
    I -->|"ASCII chars"| J["Code block: ltr"]
    I -->|"RTL chars in comment"| K["Code block: rtl edge case"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["AgentMarkdown receives children (string)"] --> B["div dir=auto wrapper"]
    B --> C["Markdown component (react-markdown)"]
    C --> D["Block-level descendants rendered"]
    D --> E{"First strong Unicode char in block element"}
    E -->|"Arabic / Hebrew / Persian"| F["direction: rtl, right-aligned"]
    E -->|"Latin / CJK / Cyrillic"| G["direction: ltr, left-aligned"]
    F --> H["Code blocks independently evaluate content"]
    G --> H
    H --> I{"Code first-char type"}
    I -->|"ASCII chars"| J["Code block: ltr"]
    I -->|"RTL chars in comment"| K["Code block: rtl edge case"]
Loading

Comments Outside Diff (2)

  1. src/renderer/src/components/AgentMarkdown.tsx, line 165-166 (link)

    P2 Code blocks inside an RTL message lack an explicit LTR override. When dir="auto" resolves to RTL (e.g., an Arabic message), block-level descendants independently determine their own direction based on their first strong Unicode character. Code that starts with an ASCII character will be fine, but a code block whose first strong character is RTL (e.g., an Arabic comment # تعليق at the top of a Python block) will inherit RTL layout, causing the Prism-rendered block to render right-to-left. Adding dir="ltr" to the chat-code-block root div ensures code is always rendered left-to-right regardless of the surrounding message direction.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

  2. src/main/registry.ts, line 126-128 (link)

    P2 The fetchRegistry call fetches index.json and fetchModelRegistry fetches models.json from raw.githubusercontent.com without an auth token. These endpoints have separate (more permissive) anonymous limits, but if the project ever migrates those resources to the GitHub API domain, or if users hit raw CDN throttling, the token won't help. Passing the token here is consistent with the pattern used in listFolderFiles and costs nothing when the env var is absent.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Reviews (1): Last reviewed commit: "fix(chat): add RTL support for message t..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RTL rendering issue in Persian or arabic responses (mixed Persian/English text becomes visually broken)

1 participant