Add AssemblyAI as a third transcription provider option alongside
OpenAI and Groq. AssemblyAI offers better accuracy for certain
audio types (distant voices, noisy environments) and serves as a
reliable fallback when other providers struggle.
Changes:
- Add AssemblyAITranscriptionProvider class in providers/transcription.py
- Add 'assemblyai' option in base channel's transcribe_audio()
- Per-channel configuration via transcriptionProvider in config
Usage:
Set transcriptionProvider: 'assemblyai' and provide an AssemblyAI
API key via transcriptionApiKey in the channel config.
Three improvements to the WhatsApp Baileys bridge:
1. Forwarded message detection: Extracts contextInfo.isForwarded from
all message types (text, image, video, audio, document) and passes
it as isForwarded in the InboundMessage. Allows the agent to
distinguish forwarded content from direct messages — useful for
different handling (e.g., transcribe-only vs execute as instruction).
2. Startup timestamp guard: Records the timestamp when the bridge
starts and drops any messages with messageTimestamp older than
startup time. Prevents replaying message history on reconnect,
which caused duplicate processing and stale command execution.
3. Contact message handling: Adds support for contactMessage and
contactsArrayMessage types, extracting displayName and vcard
data instead of silently dropping shared contacts.
Changes:
- Add isForwarded field to InboundMessage interface
- Add startupTimestamp guard in message processing loop
- Add contactMessage/contactsArrayMessage extraction
- Extract contextInfo.isForwarded from all media message types
- Wrap both token estimation calls in try/except to prevent silent failures
from crashing the consolidation cycle
- Add _MAX_CHUNK_MESSAGES = 60 to cap messages per consolidation round,
avoiding oversized chunks being sent to the consolidation LLM
- Improve idle log to include unconsolidated message count for easier debugging
These are purely defensive improvements with no behaviour change for
normal sessions.
The bridge's pn/sender fields don't consistently map to phone/LID
across different versions. Classify by JID suffix instead:
@s.whatsapp.net → phone number
@lid.whatsapp.net → LID (internal WhatsApp identifier)
This ensures allowFrom works reliably with phone numbers regardless
of which field the bridge populates.