272 lines
9.2 KiB
Markdown
272 lines
9.2 KiB
Markdown
# Integrated Suite — Conversational Interface Plan
|
|
|
|
> **Pattern:** Every suite app exposes its own `PROMPT.md` + internal tools.
|
|
> The shared chat bar activates app-specific context when the user is inside that app.
|
|
> WhatsApp campaigns is the first full example.
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
```
|
|
User (WhatsApp / Suite chat bar)
|
|
↓
|
|
BotOrchestrator (core/bot/mod.rs)
|
|
↓
|
|
detect active app context
|
|
↓
|
|
load app PROMPT.md + app InternalTools
|
|
↓
|
|
LLM with tools → tool_executor.rs
|
|
↓
|
|
app data / actions
|
|
```
|
|
|
|
### Key existing pieces
|
|
| File | Role |
|
|
|---|---|
|
|
| `core/bot/mod.rs` | `get_session_tools()` + `ToolExecutor::execute_tool_call()` |
|
|
| `tasks/PROMPT.md` | Pattern for app-level LLM prompt |
|
|
| `marketing/whatsapp.rs` | WhatsApp campaign send/metrics |
|
|
| `marketing/campaigns.rs` | Campaign CRUD |
|
|
| `marketing/lists.rs` | Recipient lists |
|
|
| `botui/ui/suite/campaigns/` | Campaigns UI |
|
|
|
|
---
|
|
|
|
## Standard: Every Suite App
|
|
|
|
### 1. `PROMPT.md` per app folder
|
|
Location: `botserver/src/<app>/PROMPT.md`
|
|
|
|
```markdown
|
|
# <App> — Internal Tools Guide
|
|
|
|
You are the <App> assistant. When the user is in <App>, you have access to:
|
|
- tool: list_<entities>
|
|
- tool: create_<entity>
|
|
- tool: search_<entity>
|
|
- tool: <app_specific_action>
|
|
|
|
Rules:
|
|
- Always confirm destructive actions before executing
|
|
- Show results as structured summaries, not raw JSON
|
|
- If user uploads a file, parse it and confirm before acting
|
|
```
|
|
|
|
### 2. `tools.rs` per app
|
|
Location: `botserver/src/<app>/tools.rs`
|
|
|
|
Registers `Vec<Tool>` (LLM function-calling schema) + handler mapping.
|
|
Loaded by `get_session_tools()` when session's active app = this app.
|
|
|
|
### 3. App context detection
|
|
`core/bot/mod.rs` reads `session.active_app` (set by UI via `POST /api/session/context`).
|
|
Loads `<app>/PROMPT.md` as system prompt prefix + `<app>/tools.rs` tools.
|
|
|
|
---
|
|
|
|
## WhatsApp Campaigns — Full Conversational Flow
|
|
|
|
### Meta Rules (enforced in tools)
|
|
- Only approved Message Templates for marketing (non-session-initiated)
|
|
- 24h session window for free-form after user replies
|
|
- Media: image/video/document via Media Upload API before send
|
|
- Opt-out: always honor STOP, add to suppression list immediately
|
|
- Rate: respect per-phone-number rate limits (1000 msg/s business tier)
|
|
- Template category: MARKETING requires explicit opt-in from recipient
|
|
|
|
### Conversation Flow (WhatsApp → campaign creation)
|
|
|
|
```
|
|
User sends to bot number:
|
|
"I want to send a campaign"
|
|
↓
|
|
Bot: "Great! Send me:
|
|
1. Your contact list (.xlsx or .csv)
|
|
2. The message text
|
|
3. An image (optional)
|
|
4. When to send (or 'now')"
|
|
↓
|
|
User uploads contacts.xlsx
|
|
↓
|
|
[tool: parse_contact_file]
|
|
→ extract phone numbers, names
|
|
→ validate E.164 format
|
|
→ show preview: "Found 342 contacts. First 3: +55..."
|
|
↓
|
|
User sends message text
|
|
↓
|
|
[tool: check_template_compliance]
|
|
→ check if free-form or needs approved template
|
|
→ if template needed: list available approved templates
|
|
→ suggest closest match
|
|
↓
|
|
User sends image (optional)
|
|
↓
|
|
[tool: upload_media]
|
|
→ upload to Meta Media API
|
|
→ return media_id
|
|
↓
|
|
Bot: "Ready to send to 342 contacts at 14:00 today.
|
|
Preview: [image] Hello {name}, ...
|
|
Estimated cost: $X
|
|
Confirm? (yes/no)"
|
|
↓
|
|
User: "yes"
|
|
↓
|
|
[tool: create_and_schedule_campaign]
|
|
→ create campaign record
|
|
→ apply warmup limit if IP warming
|
|
→ schedule via TaskScheduler
|
|
```
|
|
|
|
### WhatsApp Campaign Tools (`marketing/whatsapp_tools.rs`)
|
|
|
|
```rust
|
|
// Tool definitions for LLM function calling
|
|
pub fn whatsapp_campaign_tools() -> Vec<Tool> {
|
|
vec![
|
|
Tool::new("parse_contact_file", "Parse uploaded xlsx/csv into contact list"),
|
|
Tool::new("list_templates", "List approved WhatsApp message templates"),
|
|
Tool::new("check_template_compliance", "Check if message needs approved template"),
|
|
Tool::new("upload_media", "Upload image/video to Meta Media API"),
|
|
Tool::new("preview_campaign", "Show campaign preview with cost estimate"),
|
|
Tool::new("create_and_schedule_campaign", "Create campaign and schedule send"),
|
|
Tool::new("get_campaign_status", "Get delivery/read metrics for a campaign"),
|
|
Tool::new("pause_campaign", "Pause an in-progress campaign"),
|
|
Tool::new("list_campaigns", "List recent campaigns with metrics"),
|
|
Tool::new("add_to_suppression", "Add number to opt-out list"),
|
|
]
|
|
}
|
|
```
|
|
|
|
### WhatsApp PROMPT.md (`marketing/WHATSAPP_PROMPT.md`)
|
|
|
|
```markdown
|
|
# WhatsApp Campaign Assistant
|
|
|
|
You help users create and manage WhatsApp marketing campaigns.
|
|
|
|
## Meta Platform Rules (MANDATORY)
|
|
- Marketing messages MUST use pre-approved templates outside 24h session window
|
|
- Always check opt-in status before adding to campaign
|
|
- Honor STOP/unsubscribe immediately via add_to_suppression tool
|
|
- Never send more than warmup daily limit if IP is warming up
|
|
- Image must be uploaded via upload_media before referencing in campaign
|
|
|
|
## Conversation Style
|
|
- Guide step by step: contacts → message → media → schedule → confirm
|
|
- Show cost estimate before confirming
|
|
- After send: proactively share open/read rates when available
|
|
|
|
## File Handling
|
|
- .xlsx/.csv → use parse_contact_file tool
|
|
- Images → use upload_media tool
|
|
- Always confirm parsed data before proceeding
|
|
```
|
|
|
|
---
|
|
|
|
## Integrated Suite Chat Bar — Standard
|
|
|
|
### How it works
|
|
1. User opens any suite app (CRM, Campaigns, Drive, etc.)
|
|
2. Chat bar at bottom activates with app context
|
|
3. `POST /api/session/context { app: "campaigns" }` sets `session.active_app`
|
|
4. BotOrchestrator loads `campaigns/PROMPT.md` + `campaigns/tools.rs`
|
|
5. User can ask natural language questions or trigger actions
|
|
|
|
### Examples per app
|
|
|
|
| App | Example query | Tool activated |
|
|
|---|---|---|
|
|
| **Campaigns** | "How did last week's campaign perform?" | `get_campaign_metrics` |
|
|
| **CRM** | "Show deals closing this month" | `list_deals` with filter |
|
|
| **Drive** | "Find the Q1 report" | `search_files` |
|
|
| **Tasks** | "Create a task to follow up with Acme" | `create_task` |
|
|
| **People** | "Who hasn't been contacted in 30 days?" | `list_contacts` with filter |
|
|
| **Mail** | "Summarize unread emails from clients" | `list_emails` + LLM summary |
|
|
| **Sheet** | "What's the total revenue in column D?" | `query_sheet` |
|
|
| **Learn** | "What does our refund policy say?" | `search_kb` |
|
|
|
|
---
|
|
|
|
## Implementation Plan
|
|
|
|
### Phase 1 — Infrastructure (1 sprint)
|
|
- [ ] `core/bot/mod.rs` — read `session.active_app`, load app PROMPT + tools
|
|
- [ ] `core/tool_context.rs` — app tool registry: `register_app_tools(app_name) -> Vec<Tool>`
|
|
- [ ] `POST /api/session/context` — set active app from UI
|
|
- [ ] Suite chat bar UI component (`botui/ui/suite/partials/chatbar.html`)
|
|
|
|
### Phase 2 — WhatsApp Campaigns (1 sprint)
|
|
- [ ] `marketing/whatsapp_tools.rs` — 10 tools above
|
|
- [ ] `marketing/WHATSAPP_PROMPT.md`
|
|
- [ ] `marketing/file_parser.rs` — xlsx/csv → contact list
|
|
- [ ] Meta warmup enforcement in send path
|
|
- [ ] Conversational campaign creation flow (state machine in session)
|
|
|
|
### Phase 3 — App-by-app rollout (1 app/sprint)
|
|
Priority order based on value:
|
|
1. CRM (deals, contacts, pipeline queries)
|
|
2. Campaigns (email + WhatsApp)
|
|
3. Tasks (create, assign, status)
|
|
4. Drive (search, summarize docs)
|
|
5. Mail (summarize, draft reply)
|
|
6. People (segment, find contacts)
|
|
7. Sheet (query, calculate)
|
|
8. Learn (KB search)
|
|
|
|
### Phase 4 — Cross-app intelligence
|
|
- [ ] Global search across all apps via single query
|
|
- [ ] "What happened today?" — aggregates activity across CRM + Mail + Tasks
|
|
- [ ] Proactive suggestions: "You have 3 deals closing this week and no follow-up tasks"
|
|
|
|
---
|
|
|
|
## File Structure to Create
|
|
|
|
```
|
|
botserver/src/
|
|
├── marketing/
|
|
│ ├── whatsapp_tools.rs ← NEW: LLM tool definitions + handlers
|
|
│ ├── WHATSAPP_PROMPT.md ← NEW: WhatsApp assistant system prompt
|
|
│ ├── file_parser.rs ← NEW: xlsx/csv → contacts
|
|
│ └── warmup.rs ← NEW: (from campaigns.md plan)
|
|
├── core/
|
|
│ ├── tool_registry.rs ← NEW: app → tools mapping
|
|
│ └── bot/
|
|
│ └── app_context.rs ← NEW: load app prompt + tools per session
|
|
├── crm/
|
|
│ ├── tools.rs ← NEW
|
|
│ └── PROMPT.md ← NEW
|
|
├── tasks/
|
|
│ └── tools.rs ← NEW (PROMPT.md exists)
|
|
└── <each app>/
|
|
├── tools.rs ← NEW per app
|
|
└── PROMPT.md ← NEW per app
|
|
|
|
botui/ui/suite/
|
|
└── partials/
|
|
└── chatbar.html ← NEW: shared chat bar component
|
|
```
|
|
|
|
---
|
|
|
|
## Chat Bar UI (`partials/chatbar.html`)
|
|
|
|
```html
|
|
<div id="suite-chatbar" class="chatbar">
|
|
<div id="chatbar-messages" hx-ext="ws" ws-connect="/ws/suite-chat"></div>
|
|
<form ws-send>
|
|
<input type="hidden" name="app_context" value="{{ active_app }}">
|
|
<input type="file" id="chatbar-file" name="file" accept=".xlsx,.csv,.png,.jpg,.pdf" style="display:none">
|
|
<button type="button" onclick="document.getElementById('chatbar-file').click()">📎</button>
|
|
<input type="text" name="message" placeholder="Ask anything about {{ active_app }}...">
|
|
<button type="submit">→</button>
|
|
</form>
|
|
</div>
|
|
```
|
|
|
|
File uploads go to `POST /api/suite/upload` → stored in Drive → media_id passed to tool.
|