Commit Graph

368 Commits

Author SHA1 Message Date
Christian Gick
dd904c6928 fix: monkey-patch nio to forward decrypted Olm encryption_keys events
nio's _handle_olm_event silently drops unknown Olm event types
with 'Received unsupported Olm event'. Element X sends E2EE call
keys as encrypted to-device io.element.call.encryption_keys events.
After Olm decryption they were dropped before reaching any callback.

Patch intercepts the drop and forwards to on_to_device_unknown handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:55:51 +02:00
Christian Gick
70b0b89290 fix: use actual nio device_id in call.member events, not hardcoded AIBOT
Element X sends E2EE keys via encrypted to-device messages targeting
the device_id from the call.member state event. Bot was advertising
device_id='AIBOT' but its actual Matrix session is on device
'PEYRKFEXFP'. Keys were sent to a non-existent device.

Now uses the real device_id from nio credentials so Element X's
encryptAndSendToDevice reaches the correct device.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:38:32 +02:00
Christian Gick
d11516f632 fix: mount Python source files as volumes for hot-reload deploys
git pull + docker compose restart bot now works without --build.
Patched FFI binary and proto bindings stay in the image; only
Python source files are mounted read-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:14:52 +02:00
Christian Gick
c604b5f644 fix: handle Element X to-device encryption key delivery
Element X (26.03.3+) sends io.element.call.encryption_keys as
to-device messages, not room timeline events. Added
UnknownToDeviceEvent callback to catch these and deliver keys
to active voice sessions.

Also added m.room.encrypted decryption attempt in timeline scan
as fallback for older Element versions that send encrypted timeline
events.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:08:09 +02:00
Christian Gick
c11dd73ce3 fix: handle Element X MSC4143 v2 encryption key format (memberships array)
Element X embeds E2EE keys inside memberships[].encryption_keys,
not at the top level of the call.member state event content.
Bot was only checking content.encryption_keys, so it never found
the caller's key — causing 'Warten auf Medien' (waiting for media)
because encrypted audio couldn't be decrypted.

- Added _extract_enc_keys_from_content() helper handling both formats
- Updated on_unknown handler, VoiceSession creation, and key fetch
- Bot now publishes keys in both formats for compatibility
- Updated voice.py state fetch to check memberships[] fallback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 08:57:24 +02:00
Christian Gick
3363b4238f chore: Trigger rebuild 2026-03-24 08:40:30 +02:00
Christian Gick
fafd440506 chore: Trigger rebuild 2026-03-24 08:30:51 +02:00
Christian Gick
0ae59c8ebe feat(CF-2411): Pipeline hardening — Sentry, retry, concurrent limits, audit log
- Sentry transactions wrapping pipeline execution with tags
- Retry with exponential backoff for transient failures (connect, timeout, 5xx)
- Concurrent execution limit (3/user) enforced in scheduler
- Audit log events fired at each pipeline lifecycle point
- Resume support: skip already-completed steps on restart

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 08:29:24 +02:00
Christian Gick
b3e6ae65de fix: URL-encode user_id in Synapse admin API paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:11:19 +02:00
Christian Gick
07d781d101 chore: Trigger rebuild 2026-03-23 19:06:36 +02:00
Christian Gick
7fd3aae176 feat(CF-2502): proper E2E encryption with cross-signing and device lifecycle
Replace insecure auto-trust-all-devices with cross-signed-only trust policy.
Extract cross-signing manager into reusable module with vault backup/recovery.
Add device cleanup script and automatic old device pruning on startup.

- device_trust.py: CrossSignedOnlyPolicy (only trust cross-signed devices)
- cross_signing.py: Extracted from bot.py, adds vault seed backup + recovery
- scripts/matrix_device_cleanup.py: Synapse Admin API bulk device cleanup CLI
- bot.py: Use new modules, add _cleanup_own_devices() on startup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:05:48 +02:00
Christian Gick
bfc717372c fix(voice): add MSC4143 call.member encryption key support
Element Call v0.17+ embeds encryption_keys in call.member state events
instead of separate timeline events. In E2EE rooms, timeline events are
encrypted and the bot HTTP fetch cannot decrypt them, causing DEC_FAILED.

- Extract caller keys from call.member state event on join
- Embed bot key in call.member state event
- Check call.member state in key fetch (before timeline fallback)
- Handle key updates in call.member during active calls
- Update voice.py key poller to check call.member state first
- Add debug logging for UnknownEvent types in call rooms

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 08:12:58 +02:00
Christian Gick
dcee2d30d5 fix: silently cache images in group rooms without mention
Same pattern as files: download and cache in _recent_images without
responding. When user next @mentions the bot, the cached image is
available as context. Applied to both plain and encrypted image handlers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:42:13 +00:00
Christian Gick
cb5f057006 fix: silently ingest files in group rooms without mention
Files uploaded to group rooms are now downloaded, parsed, and stored
in _room_document_context even without @mention. When the user later
mentions the bot, the document context is automatically included.

Previously files were silently dropped if the caption didn't contain
a mention, so the bot would say it can't access uploaded PDFs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:24:52 +00:00
Christian Gick
b69980d57f fix: match display name ('Claude') in group room mention check
Bot user is @ai:agiliton.eu but display name is 'Claude'.
Element renders mentions using display name, so the old check
for 'ai' in message body never matched '@Claude: ...' messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:05:22 +00:00
Christian Gick
0988f636d0 feat: add pitrader_script step type + image vision for pipeline triggers
Add pitrader_script executor for running PITrader scripts (pi-scan,
playbook, execute_trades) as pipeline steps with vault credential
injection and JSON output capture.

Extend claude_prompt step with vision support (image_b64 in trigger
context). Add image pipeline trigger to on_image_message handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:45:36 +02:00
Christian Gick
18b88d490f chore: Trigger rebuild 2026-03-19 12:36:23 +02:00
Christian Gick
c29c2170f3 fix(e2ee): fix screen share key rotation failures (MAT-164)
- Route HTTP-fetched keys through on_encryption_key() for proper rotation detection
- Replace boolean refetch gate with 500ms timestamp throttle for faster recovery
- Reduce DEC_FAILED cooldown from 2s to 0.5s
- Extend proactive key poll from 3s to 10s window
- Add continuous background key poller (3s interval) during active calls

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:35:50 +02:00
Christian Gick
183c41a72b chore: Trigger rebuild 2026-03-19 11:01:40 +02:00
Christian Gick
6ee3e74b1d feat: format Agent results as readable markdown list
Renders extracted items as markdown links with details instead of
raw JSON. Handles common patterns: list of dicts with title/link.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 11:01:18 +02:00
Christian Gick
b4425fc9e9 chore: Trigger rebuild 2026-03-19 10:41:27 +02:00
Christian Gick
006ed48cbe fix: prevent re-triggering pending jobs while already running
Track running job IDs to avoid creating duplicate Skyvern tasks
when the pending check runs faster than the task completes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:41:07 +02:00
Christian Gick
909c128a65 chore: Trigger rebuild 2026-03-19 10:18:45 +02:00
Christian Gick
a0b410337a chore: Trigger rebuild 2026-03-19 10:13:29 +02:00
Christian Gick
ad2caa90e7 chore: Trigger rebuild 2026-03-19 10:11:06 +02:00
Christian Gick
9f6132654c chore: Trigger rebuild 2026-03-19 10:10:09 +02:00
Christian Gick
6b226acb13 chore: Trigger rebuild 2026-03-19 10:09:22 +02:00
Christian Gick
9a223cd305 chore: Trigger rebuild 2026-03-19 10:08:30 +02:00
Christian Gick
21b6e78e83 chore: Trigger rebuild 2026-03-19 10:07:39 +02:00
Christian Gick
1d7730fbf7 fix: increase httpx timeout to 60s for Skyvern API calls
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:07:20 +02:00
Christian Gick
3aac724627 chore: Trigger rebuild 2026-03-19 10:01:16 +02:00
Christian Gick
ac0aefcfeb fix: use navigation_goal/data_extraction_goal for self-hosted Skyvern API
Cloud API uses 'prompt', self-hosted uses 'navigation_goal' and
'data_extraction_goal'. Pass them separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:00:56 +02:00
Christian Gick
8862ed2596 chore: Trigger rebuild 2026-03-19 09:23:26 +02:00
Christian Gick
8970179493 fix: remove /v1 suffix from OPENAI_COMPATIBLE_API_BASE
litellm client appends /v1/chat/completions itself.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:23:07 +02:00
Christian Gick
6084cd7d45 chore: Trigger rebuild 2026-03-19 09:20:37 +02:00
Christian Gick
ae8e6d7658 fix: use OPENAI_COMPATIBLE provider for Skyvern LLM via LiteLLM proxy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:20:19 +02:00
Christian Gick
5f3b8ef1d8 chore: Trigger rebuild 2026-03-19 08:48:38 +02:00
Christian Gick
d86401fe93 feat: support extractionGoal from portal in browser executor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 08:48:11 +02:00
Christian Gick
ea0df8c223 chore: Trigger rebuild 2026-03-19 08:41:30 +02:00
Christian Gick
b6acfca59d fix: use self-hosted Skyvern API paths and LiteLLM key
Self-hosted API uses /api/v1/tasks (not /v1/run/tasks), returns
task_id (not run_id). Pass LITELLM_API_KEY as OPENAI_API_KEY.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 08:41:10 +02:00
Christian Gick
4463cdfee9 chore: Trigger rebuild 2026-03-19 08:36:16 +02:00
Christian Gick
5724195fe0 fix: skyvern DB driver (postgresql+psycopg), add volumes, chromium-headful
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 08:35:55 +02:00
Christian Gick
0f251ddc37 chore: Trigger rebuild 2026-03-19 08:25:43 +02:00
Christian Gick
f3c7f994a2 feat: integrate Skyvern for browser automation
Add Skyvern container (public.ecr.aws) with dedicated PostgreSQL,
connected to LiteLLM proxy for LLM calls. Replace browser_executor
stub with full Skyvern API integration (create task, poll, extract).
Implement skyvern pipeline step for workflow chaining.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 08:25:07 +02:00
Christian Gick
e44e89aa00 chore: Trigger rebuild 2026-03-19 08:22:55 +02:00
Christian Gick
a22a922b43 Add Skyvern integration and browser executor enhancements
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 08:19:32 +02:00
Christian Gick
e94a5cfee4 chore: Trigger rebuild 2026-03-19 07:45:13 +02:00
Christian Gick
f27d545012 fix(MAT-164): proactive key poll on screen share + faster DEC_FAILED recovery
When a video track is subscribed (screen share starts), Element Call
rotates the E2EE key. Instead of waiting for DEC_FAILED, proactively
poll the timeline for the new key (6x @ 500ms = 3s window).

Also reduce DEC_FAILED threshold from 3→1 and cooldown from 5s→2s
for faster recovery when the proactive poll misses the rotation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:44:51 +02:00
Christian Gick
de3d67f756 chore: remove Claude Code artifacts from repository
- Delete tracked CLAUDE.md.migrated.20260308
- Update confluence-collab submodule (removed Claude Code docstring ref)
- .claude-session/ already gitignored, removed local copy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 07:04:56 +02:00
Christian Gick
4e92b8c053 chore: Trigger rebuild 2026-03-18 18:30:57 +02:00