refactor(gateway): share markdown link formatting
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""Shared helper classes for gateway platform adapters.
|
||||
|
||||
Extracts common patterns that were duplicated across 5-7 adapters:
|
||||
message deduplication, text batch aggregation, markdown stripping,
|
||||
message deduplication, text batch aggregation, markdown formatting/stripping,
|
||||
and thread participation tracking.
|
||||
"""
|
||||
|
||||
@@ -12,6 +12,7 @@ import re
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Dict
|
||||
from urllib.parse import quote
|
||||
|
||||
from utils import atomic_json_write
|
||||
|
||||
@@ -181,7 +182,20 @@ class TextBatchAggregator:
|
||||
|
||||
# ─── Markdown Stripping ──────────────────────────────────────────────────────
|
||||
|
||||
# Pre-compiled regexes for performance
|
||||
# Standard Markdown links are supported by several rich-text adapters. Keep
|
||||
# delimiter escaping here; platform-specific dialect conversion stays in each
|
||||
# adapter.
|
||||
_MARKDOWN_LINK_LABEL_RE = re.compile(r"([\\\[\]])")
|
||||
|
||||
|
||||
def format_markdown_link(label: str, url: str) -> str:
|
||||
"""Return a standard Markdown link with safe label and destination text."""
|
||||
escaped_label = _MARKDOWN_LINK_LABEL_RE.sub(r"\\\1", label)
|
||||
escaped_url = quote(url, safe=":/?#[]@!$&'*+,;=%")
|
||||
return f"[{escaped_label}]({escaped_url})"
|
||||
|
||||
|
||||
# Pre-compiled regexes for Markdown stripping
|
||||
_RE_BOLD = re.compile(r"\*\*(.+?)\*\*", re.DOTALL)
|
||||
_RE_ITALIC_STAR = re.compile(r"\*(.+?)\*", re.DOTALL)
|
||||
_RE_BOLD_UNDER = re.compile(r"\b__(?![\s_])(.+?)(?<![\s_])__\b", re.DOTALL)
|
||||
|
||||
@@ -26,7 +26,7 @@ import time
|
||||
from collections import defaultdict
|
||||
from contextlib import suppress
|
||||
from typing import Callable, Dict, List, Optional, Any, Tuple
|
||||
from urllib.parse import quote, urljoin
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from agent.async_utils import (
|
||||
consume_detached_task_result as _consume_background_task_result,
|
||||
@@ -121,7 +121,12 @@ except ImportError:
|
||||
|
||||
from gateway.config import Platform, PlatformConfig
|
||||
|
||||
from gateway.platforms.helpers import MessageDeduplicator, ThreadParticipationTracker, convert_table_to_bullets
|
||||
from gateway.platforms.helpers import (
|
||||
MessageDeduplicator,
|
||||
ThreadParticipationTracker,
|
||||
convert_table_to_bullets,
|
||||
format_markdown_link,
|
||||
)
|
||||
from utils import atomic_json_write, env_float, env_int
|
||||
from gateway.platforms.base import (
|
||||
BasePlatformAdapter,
|
||||
@@ -982,9 +987,7 @@ class DiscordAdapter(BasePlatformAdapter):
|
||||
if not preview.url:
|
||||
return preview.text
|
||||
|
||||
label = re.sub(r"([\\\[\]])", r"\\\1", preview.text)
|
||||
href = quote(preview.url, safe=":/?#[]@!$&'*+,;=%")
|
||||
return f"[{label}]({href})"
|
||||
return format_markdown_link(preview.text, preview.url)
|
||||
|
||||
def __init__(self, config: PlatformConfig):
|
||||
super().__init__(config, Platform.DISCORD)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
"""Tests for shared platform Markdown formatting helpers."""
|
||||
|
||||
from gateway.platforms.helpers import format_markdown_link
|
||||
|
||||
|
||||
def test_format_markdown_link_escapes_label_and_destination_delimiters():
|
||||
assert format_markdown_link(
|
||||
r"docs [beta]", "https://example.com/a_(draft)"
|
||||
) == r"[docs \[beta\]](https://example.com/a_%28draft%29)"
|
||||
Reference in New Issue
Block a user