Architecture: How should Vitto's rich messaging work across WhatsApp, Web ...
Documentation for Sessions
🏗️ Architecture: How should Vitto's rich messaging work across WhatsApp, Web ...
Date: 2026-03-13
Time: 01:05:43 UTC
Session: gspace1-210.5
Agent: angular
Confidence: 95%
Status: ✅ Documented
📋 Decision Context
Question:
How should Vitto's rich messaging work across WhatsApp, Web Chat, Slack, and Discord with consistent interactive experiences?
Task: S210.5: Design unified rich messaging across all channels
🎯 Decision Made
Chosen:
Build a channel-agnostic RichMessage type system (TextMessage, QuickReplyMessage, ListPickerMessage, CardMessage, CarouselMessage, CTAMessage, etc.) with a ChannelAdapter interface. Each channel gets its own adapter that converts RichMessage to channel-native format (Twilio Content API for WhatsApp, Angular components for Web, Block Kit for Slack, Embeds for Discord). The agent loop produces RichMessage output; adapters render it per-channel. Three phases: (1) architecture + structured interactions, (2) personality/expression, (3) WhatsApp Flows.
Options Considered:
- Option A: Keep extending WhatsApp-specific services (whatsapp-response-composer, channel-response-enricher) and build separate logic per channel
- Option B: Build channel-agnostic RichMessage type system with ChannelAdapter pattern — single source, multiple renderers
- Option C: Use Twilio Content API as the universal abstraction (it already supports multi-channel)
💭 Reasoning
Option B was chosen because: (1) The user explicitly requires cross-channel parity — WhatsApp, Web, Slack should feel similar. Option A (channel-specific) makes parity impossible to maintain. (2) Twilio Content API (Option C) only covers Twilio-managed channels — it can't render Angular components for the web chat. We need an abstraction above Twilio. (3) The current architecture is WhatsApp-siloed: WhatsAppResponseComposerService, whatsapp-formatter, whatsapp-chunker all make WhatsApp decisions with no equivalent for other channels. This leads to feature divergence where adding carousels means building it 4 times independently. (4) The RichMessage abstraction follows the Global Engineering Standard: small focused types, clear interfaces, plugin-style adapters. Each message type is its own file, each adapter is its own file. (5) TwilioContentApiService already supports list pickers, cards, carousels — the WhatsApp adapter just delegates to it, so we're not rebuilding delivery. Root cause of the decision: The user's Jarvis vision requires every channel to feel equally rich and interactive. Without a shared abstraction, each new feature multiplies development effort by the number of channels.
📁 Files Involved
APIs/backend-vitto-api/src/app/engine/whatsapp-response-composer.service.tsAPIs/backend-vitto-api/src/app/engine/channel-response-enricher.service.tslibs/libs-api/messaging-core/src/lib/services/twilio-content-api.service.tsAPIs/backend-vitto-api/src/app/engine/channel-processing.service.ts
🔗 Related
- Decision ID:
dev_1773363943606_teem5h7 - Session: 210
- Workspace: gspace1
Auto-generated by MCP Smart Consolidation