refactor(discord): keep link formatting adapter-local
This commit is contained in:
parent
56941eb329
commit
7af104b37b
|
|
@ -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 formatting/stripping,
|
||||
message deduplication, text batch aggregation, markdown stripping,
|
||||
and thread participation tracking.
|
||||
"""
|
||||
|
||||
|
|
@ -12,7 +12,6 @@ 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
|
||||
|
||||
|
|
@ -182,20 +181,7 @@ class TextBatchAggregator:
|
|||
|
||||
# ─── Markdown Stripping ──────────────────────────────────────────────────────
|
||||
|
||||
# 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
|
||||
# Pre-compiled regexes for performance
|
||||
_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 urljoin
|
||||
from urllib.parse import quote, urljoin
|
||||
|
||||
from agent.async_utils import (
|
||||
consume_detached_task_result as _consume_background_task_result,
|
||||
|
|
@ -35,6 +35,15 @@ from agent.display import ToolPreview
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_DISCORD_MARKDOWN_LINK_LABEL_RE = re.compile(r"([\\\[\]])")
|
||||
|
||||
|
||||
def _format_discord_markdown_link(label: str, url: str) -> str:
|
||||
"""Return a Discord Markdown link with escaped delimiters."""
|
||||
escaped_label = _DISCORD_MARKDOWN_LINK_LABEL_RE.sub(r"\\\1", label)
|
||||
escaped_url = quote(url, safe=":/?#[]@!$&'*+,;=%")
|
||||
return f"[{escaped_label}]({escaped_url})"
|
||||
|
||||
|
||||
class _Snowflake:
|
||||
"""Minimal object exposing ``.id`` — satisfies discord.py's Snowflake
|
||||
|
|
@ -125,7 +134,6 @@ 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 (
|
||||
|
|
@ -987,7 +995,7 @@ class DiscordAdapter(BasePlatformAdapter):
|
|||
if not preview.url:
|
||||
return preview.text
|
||||
|
||||
return format_markdown_link(preview.text, preview.url)
|
||||
return _format_discord_markdown_link(preview.text, preview.url)
|
||||
|
||||
def __init__(self, config: PlatformConfig):
|
||||
super().__init__(config, Platform.DISCORD)
|
||||
|
|
|
|||
|
|
@ -56,6 +56,21 @@ class TestDiscordToolPreviewFormatting:
|
|||
|
||||
assert out == f"[{visible}]({url})"
|
||||
|
||||
def test_link_escapes_discord_markdown_delimiters(self):
|
||||
from agent.display import ToolPreview
|
||||
|
||||
adapter = _make_discord_adapter()
|
||||
preview = ToolPreview(
|
||||
r"https://example.com/docs/[beta]...",
|
||||
truncated=True,
|
||||
url="https://example.com/docs/_(beta)",
|
||||
)
|
||||
|
||||
assert adapter.format_tool_preview(preview) == (
|
||||
r"[https://example.com/docs/\[beta\]...]"
|
||||
r"(https://example.com/docs/_%28beta%29)"
|
||||
)
|
||||
|
||||
def test_structured_tool_event_uses_clickable_truncated_url(self):
|
||||
from gateway.stream_events import ToolCallChunk
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
"""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)"
|
||||
Loading…
Reference in New Issue