From f5e08257ebea8986fdd1f4e0bb07065712e9006c Mon Sep 17 00:00:00 2001 From: Christian Gick Date: Mon, 9 Mar 2026 16:06:52 +0200 Subject: [PATCH] fix(MAT-140): Set E2EE decryption keys for video tracks, not just audio Video tracks (camera + screen share) were never getting E2EE keys set via set_key() because the condition on track_subscribed only matched audio tracks (kind==1). This caused DEC_FAILED for all video frames, making look_at_screen return encrypted garbage or fail entirely. Also added track source logging to distinguish camera vs screen share. Co-Authored-By: Claude Opus 4.6 --- voice.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/voice.py b/voice.py index e248c7c..cb726a2 100644 --- a/voice.py +++ b/voice.py @@ -672,10 +672,12 @@ class VoiceSession: # skips HKDF derivation → raw key stored → DEC_FAILED. # Solution: set caller key HERE, after frame cryptor is initialized. # Store video track for on-demand vision (look_at_screen tool) + # Screen share = source "screen_share" or "screenshare"; camera = "camera" or default if int(t.kind) == 2: # video track (LiveKit: 1=audio, 2=video) + track_source = getattr(pub, 'source', None) or "unknown" self._video_track = t - logger.info("Video track stored from %s for on-demand vision", p.identity) - if int(t.kind) == 1 and e2ee_opts is not None: # audio track only + logger.info("Video track stored from %s source=%s for on-demand vision", p.identity, track_source) + if int(t.kind) in (1, 2) and e2ee_opts is not None: # audio + video tracks caller_id = p.identity logger.info("E2EE_DIAG: track_subscribed for %s, have %d caller keys", caller_id, len(self._caller_all_keys))