- Fix root cause: Message.from_json was parsing status/capabilities
payloads (plain JSON dicts) as Message objects with empty payload,
causing _on_status_update to silently fail. Now plain JSON payloads
(no 'type'/'sender' keys) are passed as raw strings to callbacks.
- _on_status_update: ignore own status, call on_agent_status_change
hook only when status actually changes (was_online != is_online)
- Add on_agent_status_change(agent_id, status) hook in BaseAgent
- Add on_xmpp_connected() hook in BaseAgent
- XMPPClient.connect_async() accepts on_ready callback
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace process(forever=True) with asyncio event loop in _SlixClient.start()
- Make send_xmpp_message() thread-safe via loop.call_soon_threadsafe()
- Remove wait=True from join_muc() (no longer supported in slixmpp 1.13)
- Silence empty retained MQTT capability messages in CapabilitiesRegistry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>