Skip to content

fix(matrix): handle encrypted media in E2EE rooms - #4196

Closed
elkimek wants to merge 1 commit into
NousResearch:mainfrom
elkimek:fix/matrix-encrypted-media
Closed

fix(matrix): handle encrypted media in E2EE rooms#4196
elkimek wants to merge 1 commit into
NousResearch:mainfrom
elkimek:fix/matrix-encrypted-media

Conversation

@elkimek

@elkimek elkimek commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Encrypted media (images, audio, video, files) in E2EE Matrix rooms were silently dropped
  • matrix-nio emits RoomEncryptedImage/Audio/Video/File for these — distinct from MegolmEvent (encrypted text) and RoomMessageImage (unencrypted media)
  • No callbacks were registered for these event types, so the gateway never processed them

Changes

  • Register event callbacks for all four RoomEncrypted* media types
  • Extend isinstance checks in _on_room_message_media to match both encrypted and unencrypted variants
  • Decrypt attachment data after download using nio.crypto.decrypt_attachment before caching

Test plan

  • Send an image in an E2EE Matrix room — bot receives and processes it
  • Vision analysis works on decrypted image (valid JPEG/PNG, not encrypted bytes)
  • Unencrypted rooms still work as before
  • Existing test suite: 6887 passed, 0 new failures
  • Audio/video/file attachments in E2EE rooms (same code path, not yet tested)

Platforms tested

  • Linux (Ubuntu 24.04, Python 3.12)

🤖 Generated with Claude Code

In E2EE rooms, matrix-nio emits RoomEncryptedImage/Audio/Video/File
events for media messages. These are distinct from MegolmEvent (used
for encrypted text) and RoomMessageImage (used for unencrypted media).

Previously, no callbacks were registered for these event types, so
encrypted images, audio, video, and files were silently dropped.

This commit:
- Registers event callbacks for all four RoomEncrypted* media types
- Extends isinstance checks in _on_room_message_media to match both
  encrypted and unencrypted variants
- Decrypts attachment data after download using nio.crypto.decrypt_attachment
  before caching, so vision tools and other consumers receive valid files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@teknium1

teknium1 commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

Merged via PR #5271 using #3140's implementation which is more comprehensive — handles all media types (not just images), prevents ciphertext URL fallback, includes 355 lines of tests. Your approach was correct for the image case. Thanks!

@teknium1 teknium1 closed this Apr 5, 2026
kshitijk4poor pushed a commit that referenced this pull request Aug 25, 2026
Upstream OpenViking removed the uid-less viking://user/<segment>
shorthand (#4196, merged 2026-08-21): reserved segments like memories
and peers no longer expand to the caller's space and the server
rejects them with HTTP 400 (NamespaceShapeError). First-party clients
were migrated to viking://~ in the same change; the Hermes plugin was
not (#91995).

Migrate every URI the plugin constructs — the profile/preferences/
entities session-start reads, the _build_memory_uri memory-mirroring
write path, and the tool-schema example — to viking://~/... README
uid-less references updated to match; canonical user-scoped forms
(viking://user/default/...) are unchanged. The ~ alias requires
OpenViking server >= 0.4.16 (#4167).
prmartinow pushed a commit to prmartinow/hermes-agent that referenced this pull request Aug 26, 2026
Upstream OpenViking removed the uid-less viking://user/<segment>
shorthand (NousResearch#4196, merged 2026-08-21): reserved segments like memories
and peers no longer expand to the caller's space and the server
rejects them with HTTP 400 (NamespaceShapeError). First-party clients
were migrated to viking://~ in the same change; the Hermes plugin was
not (NousResearch#91995).

Migrate every URI the plugin constructs — the profile/preferences/
entities session-start reads, the _build_memory_uri memory-mirroring
write path, and the tool-schema example — to viking://~/... README
uid-less references updated to match; canonical user-scoped forms
(viking://user/default/...) are unchanged. The ~ alias requires
OpenViking server >= 0.4.16 (NousResearch#4167).
and7777 pushed a commit to and7777/hermes-agent that referenced this pull request Aug 27, 2026
Upstream OpenViking removed the uid-less viking://user/<segment>
shorthand (NousResearch#4196, merged 2026-08-21): reserved segments like memories
and peers no longer expand to the caller's space and the server
rejects them with HTTP 400 (NamespaceShapeError). First-party clients
were migrated to viking://~ in the same change; the Hermes plugin was
not (NousResearch#91995).

Migrate every URI the plugin constructs — the profile/preferences/
entities session-start reads, the _build_memory_uri memory-mirroring
write path, and the tool-schema example — to viking://~/... README
uid-less references updated to match; canonical user-scoped forms
(viking://user/default/...) are unchanged. The ~ alias requires
OpenViking server >= 0.4.16 (NousResearch#4167).
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