feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
use crate ::shared ::models ::UserSession ;
use crate ::shared ::state ::AppState ;
use chrono ::Utc ;
use diesel ::prelude ::* ;
use log ::{ debug , error , info , warn } ;
use rhai ::{ Dynamic , Engine , Map } ;
use serde ::{ Deserialize , Serialize } ;
use std ::path ::PathBuf ;
use std ::sync ::Arc ;
use uuid ::Uuid ;
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct TransferToHumanRequest {
pub name : Option < String > ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
pub department : Option < String > ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
pub priority : Option < String > ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
pub reason : Option < String > ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
pub context : Option < String > ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct TransferResult {
pub success : bool ,
pub status : TransferStatus ,
pub queue_position : Option < i32 > ,
pub assigned_to : Option < String > ,
pub assigned_to_name : Option < String > ,
pub estimated_wait_seconds : Option < i32 > ,
pub message : String ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
#[ serde(rename_all = " snake_case " ) ]
pub enum TransferStatus {
Queued ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
Assigned ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
Connected ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
NoAttendants ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
CrmDisabled ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
AttendantNotFound ,
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
Error ,
}
#[ derive(Debug, Clone, Serialize, Deserialize) ]
pub struct Attendant {
pub id : String ,
pub name : String ,
pub channel : String ,
pub preferences : String ,
pub department : Option < String > ,
pub aliases : Vec < String > ,
pub status : AttendantStatus ,
}
2025-12-26 08:59:25 -03:00
#[ derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq) ]
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
#[ serde(rename_all = " snake_case " ) ]
pub enum AttendantStatus {
Online ,
Busy ,
Away ,
Offline ,
}
impl Default for AttendantStatus {
fn default ( ) -> Self {
2025-12-26 08:59:25 -03:00
Self ::Offline
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
}
}
pub fn is_crm_enabled ( bot_id : Uuid , work_path : & str ) -> bool {
let config_path = PathBuf ::from ( work_path )
. join ( format! ( " {} .gbai " , bot_id ) )
. join ( " config.csv " ) ;
if ! config_path . exists ( ) {
let alt_path = PathBuf ::from ( work_path ) . join ( " config.csv " ) ;
if alt_path . exists ( ) {
return check_config_for_crm ( & alt_path ) ;
}
2025-12-26 08:59:25 -03:00
warn! ( " Config file not found: {} " , config_path . display ( ) ) ;
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
return false ;
}
check_config_for_crm ( & config_path )
}
fn check_config_for_crm ( config_path : & PathBuf ) -> bool {
match std ::fs ::read_to_string ( config_path ) {
Ok ( content ) = > {
for line in content . lines ( ) {
let line_lower = line . to_lowercase ( ) ;
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
if ( line_lower . contains ( " crm-enabled " ) | | line_lower . contains ( " crm_enabled " ) )
& & line_lower . contains ( " true " )
{
return true ;
}
2025-12-23 18:40:58 -03:00
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
if line_lower . contains ( " transfer " ) & & line_lower . contains ( " true " ) {
return true ;
}
}
false
}
Err ( e ) = > {
error! ( " Failed to read config file: {} " , e ) ;
false
}
}
}
pub fn read_attendants ( bot_id : Uuid , work_path : & str ) -> Vec < Attendant > {
let attendant_path = PathBuf ::from ( work_path )
. join ( format! ( " {} .gbai " , bot_id ) )
. join ( " attendant.csv " ) ;
if ! attendant_path . exists ( ) {
let alt_path = PathBuf ::from ( work_path ) . join ( " attendant.csv " ) ;
if alt_path . exists ( ) {
return parse_attendants_csv ( & alt_path ) ;
}
2025-12-26 08:59:25 -03:00
warn! ( " Attendants file not found: {} " , attendant_path . display ( ) ) ;
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
return Vec ::new ( ) ;
}
parse_attendants_csv ( & attendant_path )
}
fn parse_attendants_csv ( path : & PathBuf ) -> Vec < Attendant > {
match std ::fs ::read_to_string ( path ) {
Ok ( content ) = > {
let mut attendants = Vec ::new ( ) ;
let mut lines = content . lines ( ) ;
let header = lines . next ( ) . unwrap_or ( " " ) ;
let headers : Vec < String > = header . split ( ',' ) . map ( | s | s . trim ( ) . to_lowercase ( ) ) . collect ( ) ;
let id_idx = headers . iter ( ) . position ( | h | h = = " id " ) . unwrap_or ( 0 ) ;
let name_idx = headers . iter ( ) . position ( | h | h = = " name " ) . unwrap_or ( 1 ) ;
let channel_idx = headers . iter ( ) . position ( | h | h = = " channel " ) . unwrap_or ( 2 ) ;
let pref_idx = headers . iter ( ) . position ( | h | h = = " preferences " ) . unwrap_or ( 3 ) ;
let dept_idx = headers . iter ( ) . position ( | h | h = = " department " ) ;
let alias_idx = headers . iter ( ) . position ( | h | h = = " aliases " | | h = = " alias " ) ;
for line in lines {
if line . trim ( ) . is_empty ( ) {
continue ;
}
let parts : Vec < & str > = line . split ( ',' ) . map ( | s | s . trim ( ) ) . collect ( ) ;
if parts . len ( ) > = 4 {
2025-12-26 08:59:25 -03:00
let department = dept_idx . and_then ( | i | parts . get ( i ) . map ( | s | ( * s ) . to_string ( ) ) ) ;
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
let aliases = alias_idx
. and_then ( | i | parts . get ( i ) )
. map ( | s | s . split ( ';' ) . map ( | a | a . trim ( ) . to_lowercase ( ) ) . collect ( ) )
. unwrap_or_default ( ) ;
attendants . push ( Attendant {
2025-12-26 08:59:25 -03:00
id : ( * parts . get ( id_idx ) . unwrap_or ( & " " ) ) . to_string ( ) ,
name : ( * parts . get ( name_idx ) . unwrap_or ( & " " ) ) . to_string ( ) ,
channel : ( * parts . get ( channel_idx ) . unwrap_or ( & " all " ) ) . to_string ( ) ,
preferences : ( * parts . get ( pref_idx ) . unwrap_or ( & " " ) ) . to_string ( ) ,
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
department ,
aliases ,
2025-12-23 18:40:58 -03:00
status : AttendantStatus ::Online ,
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
} ) ;
}
}
info! ( " Loaded {} attendants from CSV " , attendants . len ( ) ) ;
attendants
}
Err ( e ) = > {
error! ( " Failed to read attendant file: {} " , e ) ;
Vec ::new ( )
}
}
}
pub fn find_attendant < ' a > (
attendants : & ' a [ Attendant ] ,
name : Option < & str > ,
department : Option < & str > ,
) -> Option < & ' a Attendant > {
if let Some ( search_name ) = name {
let search_lower = search_name . to_lowercase ( ) ;
if let Some ( att ) = attendants
. iter ( )
. find ( | a | a . name . to_lowercase ( ) = = search_lower )
{
return Some ( att ) ;
}
if let Some ( att ) = attendants
. iter ( )
. find ( | a | a . name . to_lowercase ( ) . contains ( & search_lower ) )
{
return Some ( att ) ;
}
if let Some ( att ) = attendants
. iter ( )
. find ( | a | a . aliases . contains ( & search_lower ) )
{
return Some ( att ) ;
}
if let Some ( att ) = attendants
. iter ( )
. find ( | a | a . id . to_lowercase ( ) = = search_lower )
{
return Some ( att ) ;
}
}
if let Some ( dept ) = department {
let dept_lower = dept . to_lowercase ( ) ;
if let Some ( att ) = attendants . iter ( ) . find ( | a | {
a . department
. as_ref ( )
. map ( | d | d . to_lowercase ( ) = = dept_lower )
. unwrap_or ( false )
& & a . status = = AttendantStatus ::Online
} ) {
return Some ( att ) ;
}
if let Some ( att ) = attendants . iter ( ) . find ( | a | {
a . preferences . to_lowercase ( ) . contains ( & dept_lower )
& & a . status = = AttendantStatus ::Online
} ) {
return Some ( att ) ;
}
}
attendants
. iter ( )
. find ( | a | a . status = = AttendantStatus ::Online )
}
fn priority_to_int ( priority : Option < & str > ) -> i32 {
match priority . map ( | p | p . to_lowercase ( ) ) . as_deref ( ) {
Some ( " urgent " ) = > 3 ,
Some ( " high " ) = > 2 ,
Some ( " low " ) = > 0 ,
2025-12-26 08:59:25 -03:00
Some ( " normal " ) | None = > 1 ,
Some ( _ ) = > 1 ,
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
}
}
pub async fn execute_transfer (
state : Arc < AppState > ,
session : & UserSession ,
request : TransferToHumanRequest ,
) -> TransferResult {
let work_path = " ./work " ;
let bot_id = session . bot_id ;
if ! is_crm_enabled ( bot_id , work_path ) {
return TransferResult {
success : false ,
status : TransferStatus ::CrmDisabled ,
queue_position : None ,
assigned_to : None ,
assigned_to_name : None ,
estimated_wait_seconds : None ,
message : " CRM features are not enabled. Add 'crm-enabled,true' to config.csv "
. to_string ( ) ,
} ;
}
let attendants = read_attendants ( bot_id , work_path ) ;
if attendants . is_empty ( ) {
return TransferResult {
success : false ,
status : TransferStatus ::NoAttendants ,
queue_position : None ,
assigned_to : None ,
assigned_to_name : None ,
estimated_wait_seconds : None ,
message : " No attendants configured. Create attendant.csv in your .gbai folder "
. to_string ( ) ,
} ;
}
let attendant = find_attendant (
& attendants ,
request . name . as_deref ( ) ,
request . department . as_deref ( ) ,
) ;
if request . name . is_some ( ) & & attendant . is_none ( ) {
return TransferResult {
success : false ,
status : TransferStatus ::AttendantNotFound ,
queue_position : None ,
assigned_to : None ,
assigned_to_name : None ,
estimated_wait_seconds : None ,
message : format ! (
" Attendant '{}' not found. Available attendants: {} " ,
request . name . as_ref ( ) . unwrap ( ) ,
attendants
. iter ( )
. map ( | a | a . name . as_str ( ) )
. collect ::< Vec < _ > > ( )
. join ( " , " )
) ,
} ;
}
let priority = priority_to_int ( request . priority . as_deref ( ) ) ;
let transfer_context = serde_json ::json! ( {
" transfer_requested_at " : Utc ::now ( ) . to_rfc3339 ( ) ,
" transfer_priority " : priority ,
" transfer_reason " : request . reason . clone ( ) . unwrap_or_default ( ) ,
" transfer_context " : request . context . clone ( ) . unwrap_or_default ( ) ,
" transfer_to_name " : request . name . clone ( ) ,
" transfer_to_department " : request . department . clone ( ) ,
" needs_human " : true ,
" assigned_to " : attendant . as_ref ( ) . map ( | a | a . id . clone ( ) ) ,
" assigned_to_name " : attendant . as_ref ( ) . map ( | a | a . name . clone ( ) ) ,
" status " : if attendant . is_some ( ) { " assigned " } else { " queued " } ,
} ) ;
let session_id = session . id ;
let conn = state . conn . clone ( ) ;
let ctx_data = transfer_context . clone ( ) ;
let update_result = tokio ::task ::spawn_blocking ( move | | {
let mut db_conn = conn
. get ( )
. map_err ( | e | format! ( " DB connection error: {} " , e ) ) ? ;
use crate ::shared ::models ::schema ::user_sessions ;
diesel ::update ( user_sessions ::table . filter ( user_sessions ::id . eq ( session_id ) ) )
. set ( user_sessions ::context_data . eq ( ctx_data ) )
. execute ( & mut db_conn )
. map_err ( | e | format! ( " Failed to update session: {} " , e ) )
} )
. await ;
match update_result {
Ok ( Ok ( _ ) ) = > {
if let Some ( att ) = attendant {
info! (
" Transfer: Session {} assigned to {} ({}) " ,
session . id , att . name , att . id
) ;
TransferResult {
success : true ,
status : TransferStatus ::Assigned ,
queue_position : Some ( 1 ) ,
assigned_to : Some ( att . id . clone ( ) ) ,
assigned_to_name : Some ( att . name . clone ( ) ) ,
estimated_wait_seconds : Some ( 30 ) ,
message : format ! (
" You have been connected to {}. They will be with you shortly. " ,
att . name
) ,
}
} else {
info! (
" Transfer: Session {} queued for next available attendant " ,
session . id
) ;
Fix truncated files, implement TODOs, remove all compilation errors and warnings
- Complete truncated auto_task.rs, autotask_api.rs, intent_compiler.rs, mcp_client.rs, safety_layer.rs
- Add missing structs: RiskFactor, ResourceUsage, TaskError, RollbackState, TaskSchedule, HealthStatus
- Add missing IntentCompiler methods: call_llm, assess_risks, estimate_resources, check_ambiguity, store_compiled_intent
- Implement SET ATTENDANT STATUS database storage
- Implement queue position calculation in transfer_to_human
- Add llm_tokens to ResourceEstimate
- Fix all unused imports and variables
- Add proper derives (Copy, PartialOrd) where needed
2025-12-12 17:33:11 -03:00
let queue_position = calculate_queue_position ( & state , session_id ) . await ;
let estimated_wait = queue_position * 60 ;
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
TransferResult {
success : true ,
status : TransferStatus ::Queued ,
Fix truncated files, implement TODOs, remove all compilation errors and warnings
- Complete truncated auto_task.rs, autotask_api.rs, intent_compiler.rs, mcp_client.rs, safety_layer.rs
- Add missing structs: RiskFactor, ResourceUsage, TaskError, RollbackState, TaskSchedule, HealthStatus
- Add missing IntentCompiler methods: call_llm, assess_risks, estimate_resources, check_ambiguity, store_compiled_intent
- Implement SET ATTENDANT STATUS database storage
- Implement queue position calculation in transfer_to_human
- Add llm_tokens to ResourceEstimate
- Fix all unused imports and variables
- Add proper derives (Copy, PartialOrd) where needed
2025-12-12 17:33:11 -03:00
queue_position : Some ( queue_position ) ,
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
assigned_to : None ,
assigned_to_name : None ,
Fix truncated files, implement TODOs, remove all compilation errors and warnings
- Complete truncated auto_task.rs, autotask_api.rs, intent_compiler.rs, mcp_client.rs, safety_layer.rs
- Add missing structs: RiskFactor, ResourceUsage, TaskError, RollbackState, TaskSchedule, HealthStatus
- Add missing IntentCompiler methods: call_llm, assess_risks, estimate_resources, check_ambiguity, store_compiled_intent
- Implement SET ATTENDANT STATUS database storage
- Implement queue position calculation in transfer_to_human
- Add llm_tokens to ResourceEstimate
- Fix all unused imports and variables
- Add proper derives (Copy, PartialOrd) where needed
2025-12-12 17:33:11 -03:00
estimated_wait_seconds : Some ( estimated_wait ) ,
message : format ! (
" You have been added to the queue at position {}. Estimated wait time: {} minutes. " ,
queue_position ,
estimated_wait / 60
) ,
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
}
}
}
Ok ( Err ( e ) ) = > {
error! ( " Transfer failed: {} " , e ) ;
TransferResult {
success : false ,
status : TransferStatus ::Error ,
queue_position : None ,
assigned_to : None ,
assigned_to_name : None ,
estimated_wait_seconds : None ,
message : format ! ( " Transfer failed: {} " , e ) ,
}
}
Err ( e ) = > {
error! ( " Transfer task failed: {:?} " , e ) ;
TransferResult {
success : false ,
status : TransferStatus ::Error ,
queue_position : None ,
assigned_to : None ,
assigned_to_name : None ,
estimated_wait_seconds : None ,
message : format ! ( " Transfer task failed: {:?} " , e ) ,
}
}
}
}
impl TransferResult {
pub fn to_dynamic ( & self ) -> Dynamic {
let mut map = Map ::new ( ) ;
map . insert ( " success " . into ( ) , Dynamic ::from ( self . success ) ) ;
map . insert (
" status " . into ( ) ,
Dynamic ::from ( format! ( " {:?} " , self . status ) . to_lowercase ( ) ) ,
) ;
map . insert ( " message " . into ( ) , Dynamic ::from ( self . message . clone ( ) ) ) ;
if let Some ( pos ) = self . queue_position {
map . insert ( " queue_position " . into ( ) , Dynamic ::from ( pos ) ) ;
}
if let Some ( ref id ) = self . assigned_to {
map . insert ( " assigned_to " . into ( ) , Dynamic ::from ( id . clone ( ) ) ) ;
}
if let Some ( ref name ) = self . assigned_to_name {
map . insert ( " assigned_to_name " . into ( ) , Dynamic ::from ( name . clone ( ) ) ) ;
}
if let Some ( wait ) = self . estimated_wait_seconds {
map . insert ( " estimated_wait_seconds " . into ( ) , Dynamic ::from ( wait ) ) ;
}
Dynamic ::from ( map )
}
}
Fix truncated files, implement TODOs, remove all compilation errors and warnings
- Complete truncated auto_task.rs, autotask_api.rs, intent_compiler.rs, mcp_client.rs, safety_layer.rs
- Add missing structs: RiskFactor, ResourceUsage, TaskError, RollbackState, TaskSchedule, HealthStatus
- Add missing IntentCompiler methods: call_llm, assess_risks, estimate_resources, check_ambiguity, store_compiled_intent
- Implement SET ATTENDANT STATUS database storage
- Implement queue position calculation in transfer_to_human
- Add llm_tokens to ResourceEstimate
- Fix all unused imports and variables
- Add proper derives (Copy, PartialOrd) where needed
2025-12-12 17:33:11 -03:00
async fn calculate_queue_position ( state : & Arc < AppState > , current_session_id : Uuid ) -> i32 {
let conn = state . conn . clone ( ) ;
let result = tokio ::task ::spawn_blocking ( move | | {
let mut db_conn = match conn . get ( ) {
Ok ( c ) = > c ,
Err ( e ) = > {
error! ( " DB connection error calculating queue position: {} " , e ) ;
return 1 ;
}
} ;
let query = diesel ::sql_query (
Update attendance, keywords, calendar, compliance, console, core, drive, email, llm, msteams, security, and tasks modules
2025-12-24 09:29:27 -03:00
r " SELECT COUNT(*) as position FROM user_sessions
Fix truncated files, implement TODOs, remove all compilation errors and warnings
- Complete truncated auto_task.rs, autotask_api.rs, intent_compiler.rs, mcp_client.rs, safety_layer.rs
- Add missing structs: RiskFactor, ResourceUsage, TaskError, RollbackState, TaskSchedule, HealthStatus
- Add missing IntentCompiler methods: call_llm, assess_risks, estimate_resources, check_ambiguity, store_compiled_intent
- Implement SET ATTENDANT STATUS database storage
- Implement queue position calculation in transfer_to_human
- Add llm_tokens to ResourceEstimate
- Fix all unused imports and variables
- Add proper derives (Copy, PartialOrd) where needed
2025-12-12 17:33:11 -03:00
WHERE context_data ->> ' needs_human ' = ' true '
AND context_data ->> ' status ' = ' queued '
AND created_at < = ( SELECT created_at FROM user_sessions WHERE id = $ 1 )
Update attendance, keywords, calendar, compliance, console, core, drive, email, llm, msteams, security, and tasks modules
2025-12-24 09:29:27 -03:00
AND id ! = $ 2 " ,
Fix truncated files, implement TODOs, remove all compilation errors and warnings
- Complete truncated auto_task.rs, autotask_api.rs, intent_compiler.rs, mcp_client.rs, safety_layer.rs
- Add missing structs: RiskFactor, ResourceUsage, TaskError, RollbackState, TaskSchedule, HealthStatus
- Add missing IntentCompiler methods: call_llm, assess_risks, estimate_resources, check_ambiguity, store_compiled_intent
- Implement SET ATTENDANT STATUS database storage
- Implement queue position calculation in transfer_to_human
- Add llm_tokens to ResourceEstimate
- Fix all unused imports and variables
- Add proper derives (Copy, PartialOrd) where needed
2025-12-12 17:33:11 -03:00
)
. bind ::< diesel ::sql_types ::Uuid , _ > ( current_session_id )
. bind ::< diesel ::sql_types ::Uuid , _ > ( current_session_id ) ;
#[ derive(QueryableByName) ]
struct QueueCount {
#[ diesel(sql_type = diesel::sql_types::BigInt) ]
position : i64 ,
}
match query . get_result ::< QueueCount > ( & mut * db_conn ) {
Ok ( count ) = > ( count . position + 1 ) as i32 ,
Err ( e ) = > {
debug! ( " Could not calculate queue position: {} " , e ) ;
1
}
}
} )
. await ;
2025-12-26 08:59:25 -03:00
result . unwrap_or ( 1 )
Fix truncated files, implement TODOs, remove all compilation errors and warnings
- Complete truncated auto_task.rs, autotask_api.rs, intent_compiler.rs, mcp_client.rs, safety_layer.rs
- Add missing structs: RiskFactor, ResourceUsage, TaskError, RollbackState, TaskSchedule, HealthStatus
- Add missing IntentCompiler methods: call_llm, assess_risks, estimate_resources, check_ambiguity, store_compiled_intent
- Implement SET ATTENDANT STATUS database storage
- Implement queue position calculation in transfer_to_human
- Add llm_tokens to ResourceEstimate
- Fix all unused imports and variables
- Add proper derives (Copy, PartialOrd) where needed
2025-12-12 17:33:11 -03:00
}
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
pub fn register_transfer_to_human_keyword (
state : Arc < AppState > ,
user : UserSession ,
engine : & mut Engine ,
) {
let state_clone = state . clone ( ) ;
let user_clone = user . clone ( ) ;
engine . register_fn ( " transfer_to_human " , move | | -> Dynamic {
let state = state_clone . clone ( ) ;
let session = user_clone . clone ( ) ;
let rt = tokio ::runtime ::Handle ::current ( ) ;
let result = rt . block_on ( async {
execute_transfer (
state ,
& session ,
TransferToHumanRequest {
name : None ,
department : None ,
priority : None ,
reason : None ,
context : None ,
} ,
)
. await
} ) ;
result . to_dynamic ( )
} ) ;
let state_clone = state . clone ( ) ;
let user_clone = user . clone ( ) ;
engine . register_fn ( " transfer_to_human " , move | name : & str | -> Dynamic {
let state = state_clone . clone ( ) ;
let session = user_clone . clone ( ) ;
let name_str = name . to_string ( ) ;
let rt = tokio ::runtime ::Handle ::current ( ) ;
let result = rt . block_on ( async {
execute_transfer (
state ,
& session ,
TransferToHumanRequest {
name : Some ( name_str ) ,
department : None ,
priority : None ,
reason : None ,
context : None ,
} ,
)
. await
} ) ;
result . to_dynamic ( )
} ) ;
let state_clone = state . clone ( ) ;
let user_clone = user . clone ( ) ;
engine . register_fn (
" transfer_to_human " ,
move | department : & str , priority : & str | -> Dynamic {
let state = state_clone . clone ( ) ;
let session = user_clone . clone ( ) ;
let dept = department . to_string ( ) ;
let prio = priority . to_string ( ) ;
let rt = tokio ::runtime ::Handle ::current ( ) ;
let result = rt . block_on ( async {
execute_transfer (
state ,
& session ,
TransferToHumanRequest {
name : None ,
department : Some ( dept ) ,
priority : Some ( prio ) ,
reason : None ,
context : None ,
} ,
)
. await
} ) ;
result . to_dynamic ( )
} ,
) ;
let state_clone = state . clone ( ) ;
let user_clone = user . clone ( ) ;
engine . register_fn (
" transfer_to_human " ,
move | department : & str , priority : & str , reason : & str | -> Dynamic {
let state = state_clone . clone ( ) ;
let session = user_clone . clone ( ) ;
let dept = department . to_string ( ) ;
let prio = priority . to_string ( ) ;
let rsn = reason . to_string ( ) ;
let rt = tokio ::runtime ::Handle ::current ( ) ;
let result = rt . block_on ( async {
execute_transfer (
state ,
& session ,
TransferToHumanRequest {
name : None ,
department : Some ( dept ) ,
priority : Some ( prio ) ,
reason : Some ( rsn ) ,
context : None ,
} ,
)
. await
} ) ;
result . to_dynamic ( )
} ,
) ;
2025-12-26 08:59:25 -03:00
let state_clone = state ;
let user_clone = user ;
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
engine . register_fn ( " transfer_to_human_ex " , move | params : Map | -> Dynamic {
let state = state_clone . clone ( ) ;
let session = user_clone . clone ( ) ;
let name = params
. get ( " name " )
. and_then ( | v | v . clone ( ) . try_cast ::< String > ( ) ) ;
let department = params
. get ( " department " )
. and_then ( | v | v . clone ( ) . try_cast ::< String > ( ) ) ;
let priority = params
. get ( " priority " )
. and_then ( | v | v . clone ( ) . try_cast ::< String > ( ) ) ;
let reason = params
. get ( " reason " )
. and_then ( | v | v . clone ( ) . try_cast ::< String > ( ) ) ;
let context = params
. get ( " context " )
. and_then ( | v | v . clone ( ) . try_cast ::< String > ( ) ) ;
let rt = tokio ::runtime ::Handle ::current ( ) ;
let result = rt . block_on ( async {
execute_transfer (
state ,
& session ,
TransferToHumanRequest {
name ,
department ,
priority ,
reason ,
context ,
} ,
)
. await
} ) ;
result . to_dynamic ( )
} ) ;
debug! ( " Registered TRANSFER TO HUMAN keywords " ) ;
}
pub const TRANSFER_TO_HUMAN_TOOL_SCHEMA : & str = r #" {
" name " : " transfer_to_human " ,
" description " : " Transfer the conversation to a human attendant. Use this when the customer explicitly asks to speak with a person, when the issue is too complex for automated handling, or when emotional support is needed. " ,
" parameters " : {
" type " : " object " ,
" properties " : {
" name " : {
" type " : " string " ,
" description " : " If someone wants to talk to somebody specific, provide their name or alias. Leave empty for any available attendant. "
} ,
" department " : {
" type " : " string " ,
" description " : " Department to transfer to: sales, support, technical, billing, etc. " ,
" enum " : [ " sales " , " support " , " technical " , " billing " , " general " ]
} ,
" priority " : {
" type " : " string " ,
" description " : " Priority level for the transfer " ,
" enum " : [ " normal " , " high " , " urgent " ] ,
" default " : " normal "
} ,
" reason " : {
" type " : " string " ,
" description " : " Brief reason for the transfer to help the attendant understand the context "
}
} ,
" required " : [ ]
}
} " #;
pub fn get_tool_definition ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " function " ,
" function " : {
" name " : " transfer_to_human " ,
" description " : " Transfer the conversation to a human attendant. Use this when the customer explicitly asks to speak with a person, when the issue is too complex for automated handling, or when emotional support is needed. " ,
" parameters " : {
" type " : " object " ,
" properties " : {
" name " : {
" type " : " string " ,
" description " : " If someone wants to talk to somebody specific, provide their name or alias. Leave empty for any available attendant. "
} ,
" department " : {
" type " : " string " ,
" description " : " Department to transfer to: sales, support, technical, billing, etc. "
} ,
" priority " : {
" type " : " string " ,
" description " : " Priority level for the transfer: normal, high, or urgent " ,
" default " : " normal "
} ,
" reason " : {
" type " : " string " ,
" description " : " Brief reason for the transfer to help the attendant understand the context "
}
} ,
" required " : [ ]
}
}
} )
}