feat: add _sanitize_mentions helper and apply to comment/reply truncation
Introduce a new `_sanitize_mentions` method in `BotHelpersMixin` that deduplicates and removes self-mentions from text, using a compiled regex for `@handle` patterns. Apply this sanitizer before the 2000-character truncation in both `engage.py` comment posting and `social.py` reply posting to prevent duplicate or self-referential mentions from being cut off mid-handle. Additionally, fix profile URL parsing in `social.py` to strip trailing path segments, and refine `LLMClient.clean` to handle asterisks and underscores more precisely without breaking adjacent alphanumeric characters.
This commit is contained in:
parent
0f872336b1
commit
f1bdefd834
@ -305,7 +305,7 @@ class BotEngageMixin:
|
||||
else:
|
||||
comment = f"@{mention_target} {comment}"
|
||||
|
||||
comment = comment[:2000]
|
||||
comment = self._sanitize_mentions(comment)[:2000]
|
||||
mention_log = f" @{mention_target}" if mention_target else ""
|
||||
|
||||
textarea_sels = [
|
||||
@ -437,7 +437,7 @@ class BotEngageMixin:
|
||||
return False
|
||||
if mentioner and f"@{mentioner.lower()}" not in reply.lower():
|
||||
reply = f"@{mentioner} {reply}"
|
||||
reply = reply[:2000]
|
||||
reply = self._sanitize_mentions(reply)[:2000]
|
||||
textarea_sels = [
|
||||
".reply-form textarea[name='content']",
|
||||
".comment-form textarea[name='content']",
|
||||
|
||||
@ -11,6 +11,8 @@ from devplacepy.services.bot.config import persona_article_score, pick_category
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_MENTION_RE = re.compile(r"@([A-Za-z0-9_-]+)")
|
||||
|
||||
|
||||
class BotHelpersMixin:
|
||||
def _identity(self) -> str:
|
||||
@ -31,6 +33,21 @@ class BotHelpersMixin:
|
||||
m = re.search(r"/(?:posts|gists|news|projects)/([^/?#]+)", url)
|
||||
return m.group(1) if m else ""
|
||||
|
||||
def _sanitize_mentions(self, text: str) -> str:
|
||||
own = (self.state.username or "").lower()
|
||||
seen: set[str] = set()
|
||||
|
||||
def keep(match: "re.Match[str]") -> str:
|
||||
handle = match.group(1)
|
||||
lowered = handle.lower()
|
||||
if lowered == own or lowered in seen:
|
||||
return ""
|
||||
seen.add(lowered)
|
||||
return match.group(0)
|
||||
|
||||
cleaned = _MENTION_RE.sub(keep, text)
|
||||
return re.sub(r"\s{2,}", " ", cleaned).strip()
|
||||
|
||||
def _sync_cost(self) -> None:
|
||||
self.state.total_cost = self.llm.total_cost
|
||||
self.state.total_calls = self.llm.total_calls
|
||||
|
||||
@ -115,7 +115,10 @@ class LLMClient:
|
||||
@staticmethod
|
||||
def clean(text: str, preserve_md: bool = False) -> str:
|
||||
if not preserve_md:
|
||||
text = re.sub(r"\*\*|__|\*|_", "", text)
|
||||
text = re.sub(r"\*+", "", text)
|
||||
text = re.sub(r"(?<![A-Za-z0-9])__(?=\S)(.*?)(?<=\S)__(?![A-Za-z0-9])", r"\1", text)
|
||||
text = re.sub(r"(?<![A-Za-z0-9])_(?=\S)(.*?)(?<=\S)_(?![A-Za-z0-9])", r"\1", text)
|
||||
text = re.sub(r"(?<![A-Za-z0-9])_+(?![A-Za-z0-9])", "", text)
|
||||
text = text.replace("—", "-").replace("–", "-")
|
||||
text = text.replace("‘", "'").replace("’", "'")
|
||||
text = text.replace("“", '"').replace("”", '"')
|
||||
|
||||
@ -28,7 +28,7 @@ class BotSocialMixin:
|
||||
try:
|
||||
await links.nth(i).click(timeout=5000)
|
||||
await b._idle(1.0, 2.0)
|
||||
uname = h.split("/profile/")[-1].split("?")[0]
|
||||
uname = h.split("/profile/")[-1].split("?")[0].split("/")[0]
|
||||
if uname not in self.state.known_users:
|
||||
self.state.known_users.append(uname)
|
||||
self.state.profiles_viewed += 1
|
||||
@ -446,6 +446,9 @@ class BotSocialMixin:
|
||||
)
|
||||
except Exception:
|
||||
mentioner = ""
|
||||
if mentioner and mentioner.lower() == self.state.username.lower():
|
||||
self._log("Mention target resolves to self, skipping")
|
||||
return False
|
||||
try:
|
||||
await comment_loc.scroll_into_view_if_needed(timeout=2000)
|
||||
await b._idle(0.3, 0.9)
|
||||
@ -485,7 +488,7 @@ class BotSocialMixin:
|
||||
return False
|
||||
if mentioner and f"@{mentioner.lower()}" not in reply.lower():
|
||||
reply = f"@{mentioner} {reply}"
|
||||
reply = reply[:2000]
|
||||
reply = self._sanitize_mentions(reply)[:2000]
|
||||
textarea_sels = [
|
||||
".comment .reply-form textarea[name='content']",
|
||||
".reply-form textarea[name='content']",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user