Skip to content

fix(gateway): auto-enable skip_entity_detection for email-bearing rich messages - #68852

Open
webtecnica wants to merge 2 commits into
NousResearch:mainfrom
webtecnica:fix/68754-telegram-email-rich
Open

fix(gateway): auto-enable skip_entity_detection for email-bearing rich messages#68852
webtecnica wants to merge 2 commits into
NousResearch:mainfrom
webtecnica:fix/68754-telegram-email-rich

Conversation

@webtecnica

Copy link
Copy Markdown
Contributor

Description

Telegram rich messages can reject runtime text containing provider-prefixed email labels such as:

OAuth profile: openai:test.user@example.com (test.user@example.com)

Rich entity detection auto-links the provider-prefixed token into an invalid email entity, causing Telegram to return RICH_MESSAGE_EMAIL_INVALID.

Fix

  • _content_has_email_pattern() — new static helper that detects @ in content (signaling Telegram may auto-detect an email entity)
  • _rich_message_payload() — modified to auto-enable skip_entity_detection when email patterns are present, preventing the invalid entity from being created
  • All three rich-path callers (_try_send_rich, _edit_rich, _send_rich_draft_frame) benefit automatically since they all route through _rich_message_payload

Testing

New test class TestRichMessageEmailEntityProtection covers:

  • Provider-prefixed email (original reproducer)
  • Normal email address
  • Multiple email addresses
  • Content without @ (no skip_entity_detection set)
  • Explicit skip_entity_detection=True on non-email content
  • Email-like patterns in code blocks
  • The static _content_has_email_pattern helper directly

All 17 tests in test_telegram_rich_newlines.py pass (8 existing + 9 new).

Fixes #68754

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins platform/telegram Telegram bot adapter P3 Low — cosmetic, nice to have needs-decision Awaiting maintainer decision before any implementation labels Jul 21, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to #68757 and #68754. Both patches prevent RICH_MESSAGE_EMAIL_INVALID, but this one suppresses rich entity detection for every @ while #68757 uses a narrower email-token predicate. Maintainer decision needed on the intended entity-detection policy.

webtecnica and others added 2 commits July 21, 2026 20:35
Previously _count_skills() only counted SKILL.md files inside the
profile's own skills/ directory, making the WebUI profile card show
a misleading low count (e.g. 0 for 'default', 30 for 'webtecnica')
even though the profile loaded 150+ skills from global + external
dirs.

Now it scans three sources:
1. Profile-specific skills/ dir (as before)
2. Global ~/.hermes/skills/ dir (via get_default_hermes_root)
3. External dirs from skills.external_dirs config

Deduplication by skill name (from YAML frontmatter) prevents double-
counting when the same skill exists in both global and profile dirs,
matching how scan_skill_commands() loads skills at runtime.

The cache is updated to key on all scanned directories and track
their combined mtime signatures.
…h messages (NousResearch#68754)

Telegram rich messages are rejected with RICH_MESSAGE_EMAIL_INVALID
when automatic entity detection creates an invalid email entity from
provider-prefixed email addresses (e.g. "openai:test.user@example.com").

Hermes already supports the skip_entity_detection field in the
centralized _rich_message_payload builder, but no send/edit/draft
caller enables it for email-bearing content.

Fix:
- Add _content_has_email_pattern() static helper that detects '@' in
  content, indicating Telegram may auto-detect an email entity.
- Modify _rich_message_payload() to auto-enable skip_entity_detection
  when email patterns are detected, preventing the invalid entity
  from being created.
- All three rich-path callers (_try_send_rich, _edit_rich,
  _send_rich_draft_frame) benefit automatically since they all go
  through _rich_message_payload.

Testing:
- Existing tests for skip_entity_detection flag still pass.
- New test class TestRichMessageEmailEntityProtection covers:
  * Provider-prefixed email (the original reproducer)
  * Normal email address
  * Multiple email addresses
  * Content without @ (no skip_entity_detection)
  * Explicit skip_entity_detection=True on non-email content
  * Email-like patterns in code blocks
  * The static _content_has_email_pattern helper directly

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the shared rich-message builder; current main still has the reported gap: _rich_message_payload() only sets the flag when callers pass it (plugins/platforms/telegram/adapter.py:1683-1684), and send/edit/draft all use that builder (plugins/platforms/telegram/adapter.py:1791, 1900, 1994).

Problems

  • plugins/platforms/telegram/adapter.py:1650 classifies every @ as an email pattern. The added tests deliberately cover package==1.0@beta and a lone @ (tests/gateway/test_telegram_rich_newlines.py:157-169), so this disables entity detection for content outside the reported email case. Use an email-token predicate and add those inputs as negative controls.
  • The unrelated profile-count change is not safe as written: _collect_skills_dirs(profile_dir) calls get_external_skills_dirs() (hermes_cli/profiles.py:771-794), which reads the active HERMES_HOME config (agent/skill_utils.py:446-464), although list_profiles() invokes _count_skills() for every profile (hermes_cli/profiles.py:897, 937). Please split it out and scope its config lookup to the target profile.

Automated hermes-sweeper review.

Callers should combine this with ``skip_entity_detection`` when building
rich-message payloads for email-bearing content.
"""
return "@" in content

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This disables entity detection for every @, including non-email content such as the package-version form covered by the added tests. Please use a narrow email-token predicate and make lone @/package syntax negative controls.

Comment thread hermes_cli/profiles.py
if global_skills.is_dir() and global_skills not in dirs:
dirs.append(global_skills)

for ext_dir in get_external_skills_dirs():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_external_skills_dirs() reads the active HERMES_HOME config, not profile_dir; list_profiles() calls this for every profile. Read the target profile's config explicitly, otherwise inactive profiles inherit the active profile's external-dir count.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have platform/telegram Telegram bot adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Telegram rich messages can reject provider-prefixed email text

3 participants