Skip to content

feat(signal): add reactions, native audio, and threading#4768

Open
ishaanrathodd wants to merge 5 commits intoNousResearch:mainfrom
ishaanrathodd:feat/signal-replies-reactions-voice
Open

feat(signal): add reactions, native audio, and threading#4768
ishaanrathodd wants to merge 5 commits intoNousResearch:mainfrom
ishaanrathodd:feat/signal-replies-reactions-voice

Conversation

@ishaanrathodd
Copy link
Copy Markdown

Summary

  • add Signal-native reply context parsing plus opt-in native replies instead of forcing replies on every message
  • expose react_message to Signal agents and route Signal reactions through sendReaction
  • send Signal voice replies through stock signal-cli using filename-less data URI audio so they render in native audio UI
  • fix Signal toolset expansion so react_message and text_to_speech are actually available at runtime
  • update Signal prompting/session context so the agent can see replied-to content and choose human-like reactions

Details

This PR keeps Signal on the stock signal-cli path and improves three core interaction patterns:

  1. Reactions
  • adds a model-facing react_message tool
  • defaults reactions to the current inbound message using session message metadata
  • passes arbitrary emoji through Signal sendReaction
  1. Replies / threading
  • preserves inbound Signal timestamps as stable message_ids
  • parses Signal quote metadata into reply context
  • stops auto-threading Signal responses by default
  • adds explicit opt-in native replies via [[reply_to_current]]
  1. Voice / native audio UI
  • sends Signal voice/audio replies as filename-less data URI attachments
  • preserves stock signal-cli compatibility while rendering in Signal's native audio UI

Validation

  • venv/bin/python -m pytest tests/hermes_cli/test_tools_config.py tests/gateway/test_base_topic_sessions.py tests/agent/test_prompt_builder.py tests/gateway/test_signal.py tests/test_toolsets.py -q
  • venv/bin/python -m pytest tests/tools/test_send_message_tool.py -q

Both passed locally.

@ishaanrathodd ishaanrathodd changed the title feat(signal): add reactions, native audio, and opt-in replies feat(signal): add reactions, native audio, and threading Apr 3, 2026
@britrik
Copy link
Copy Markdown

britrik commented Apr 3, 2026

Code Review: PR #4768

Summary

Great work on adding Signal reactions, native audio, and threading support! The feature is well-designed and tests pass.

Positive Aspects

  • Clean platform abstraction with get_default_reply_target() and requires_reply_context_metadata()
  • Good test coverage with dedicated test classes for the new features
  • Smart use of data URI encoding for native Signal audio UI rendering
  • Proper environment variable injection for session context (message_id, user_id)

Potential Issues to Address

  1. Memory Concern (signal.py): The _file_to_data_uri function reads entire files into memory with Path(file_path).read_bytes(). For large audio files, this could cause memory pressure. Consider streaming or adding file size limits.

  2. Silent Error Handling (signal.py): The _coerce_timestamp function silently returns None when timestamp conversion fails. Consider logging a warning for debugging purposes.

  3. Platform Limitation: The react_message tool only supports Signal currently - other platforms return an error. Consider documenting this limitation or implementing for other platforms (Telegram supports reactions via Bot API).

  4. Test Assertion (test_signal.py): The test expects "voice.m4a" not in call["params"]["attachments"][0] - this is a good defensive check, but verify the data URI format works reliably with signal-cli across different audio formats.

Suggestions

  • Add file size validation before _file_to_data_uri to prevent OOM
  • Consider adding rate limiting for reactions to prevent spam
  • Document the [[reply_to_current]] directive behavior in a user-facing format

Overall: LGTM with minor suggestions for improvement.

@ishaanrathodd
Copy link
Copy Markdown
Author

ishaanrathodd commented Apr 3, 2026

britrik

Thanks — addressed the suggestions.

I added a safe fallback for oversized inline Signal audio, warning logs for invalid quote timestamps, and restricted react_message to active Signal sessions so the tool availability matches implementation scope.

Re-tested:
/hermes-agent/venv/bin/python -m pytest tests/gateway/test_signal.py tests/tools/test_send_message_tool.py tests/agent/test_prompt_builder.py tests/test_toolsets.py tests/hermes_cli/test_tools_config.py -q`

222 passed, 1 skipped

@ishaanrathodd
Copy link
Copy Markdown
Author

Addressed a final Signal UX bug I found while testing:

  • Signal auto-TTS voice replies no longer send the same response as text afterward
  • implemented this as a platform hook so Signal gets voice-only behavior for auto voice replies, while other platforms keep their existing text+audio behavior
  • added a regression test covering the Signal voice-input case

Re-ran the focused suite:
/.hermes/hermes-agent/venv/bin/python -m pytest tests/gateway/test_base_topic_sessions.py tests/gateway/test_signal.py tests/tools/test_send_message_tool.py tests/agent/test_prompt_builder.py tests/test_toolsets.py tests/hermes_cli/test_tools_config.py -q

Result: 231 passed, 1 skipped

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.

2 participants