chatwoot-develop/.context/docs/custom-architecture.md

3.3 KiB

Custom Architecture: WuzAPI, Jasmine & Captain V2

This document outlines the specific customizations applied to this Chatwoot instance. It supersedes generic documentation for the modules listed below.

1. WuzAPI Integration Module (V1.5)

We do not use the standard WhatsApp Cloud API. We use a custom integration with WuzAPI (a Go-based WhatsApp gateway).

1.1 V1 Contract (Critical)

  • Token Storage: TOKENS ARE NEVER PLAIN TEXT. They are stored in encrypted_wuzapi_user_token and encrypted_wuzapi_admin_token in the channel_whatsapp table.
  • Deduplication: We use a Redis lock + Source ID check to prevent processing the same message twice (WuzAPI often sends retries).
  • Loop Protection: Messages with key.fromMe = true are OUTGOING messages synced from the phone. They must be created as message_type: :outgoing and MUST NOT trigger bots.

1.2 Webhook Flow

  1. Ingress: POST /webhooks/whatsapp/:phone_number
  2. Controller: Webhooks::WhatsappController delegates to WhatsappEventsJob.
  3. Job: Detects wuzapi provider -> delegates to IncomingMessageWuzapiService.
  4. Service:
    • Finds/Creates Contact (checking variations of DDI 55).
    • Creates Message.
    • Sync Logic: If IsFromMe: true -> Create Outgoing Message.

2. Jasmine Brain (The Intelligence Layer)

Jasmine is a specialized logical layer responsible for Intent Detection, Strategy Decision, and Sales Development (SDR) behavior.

2.1 Core Components

  • BrainService: The entry point. Receives a conversation context and decides "What to do".
  • IntentDetector: Analyzes user input (using Gemini/OpenAI) to classify intent (e.g., sales_inquiry, support_ticket, spam).
  • StrategyDecider: Based on intent, decides the workflow (e.g., "Handover to human", "Consult Knowledge Base", "Qualify Lead").
  • Playbooks: Structured scripts for SDR qualification (Ask Name -> Ask Budget -> Schedule Demo).

3. Captain V2 (The Unification)

We are unifying Jasmine (Brain) into Captain (Body).

3.1 Architecture Shift

  • Legacy Captain: Used OpenAI hardcoded logic to summarize/reply.
  • Captain V2: A flexible Agent Runner that executes the Jasmine Brain.

3.2 Key Classes

  • AgentRunnerService: The orchestrator. It manages the conversation loop, tool execution, and thinking process.
  • ProviderFactory: A factory that returns the configured LLM client (Gemini, OpenRouter, OpenAI) based on the Inbox settings.
  • JasmineBrain: A specialized Agent/Tool injected into the runner to perform high-level reasoning.

3.3 Configuration (Multi-LLM)

Configurations are stored in captain_inbox_configs (or chat_assistants):

  • llm_provider: gemini | openai | openrouter
  • llm_model: gemini-1.5-flash | gpt-4o
  • api_key: Encrypted credential for the specific inbox (optional, falls back to ENV).

4. Troubleshooting & Operational Rules

4.1 Database Connectivity

  • Development uses Docker Postgres on Port 5438.
  • export POSTGRES_PORT=5438 is REQUIRED before rails c or foreman start.

4.2 Ruby Environment

  • Project uses Ruby 3.4.4.
  • Always run eval "$(rbenv init -)" if bundle fails.

4.3 Webhooks

  • WuzAPI URL must include the FULL phone number with DDI (e.g., 5561...).
  • Database phone_number must match exactly.