pub struct SupervisorApi { /* private fields */ }
Expand description
§Supervisor API for Call Center Oversight
The SupervisorApi
provides comprehensive monitoring and management capabilities
for call center supervisors. It enables real-time oversight of agents, calls,
queues, and system performance with advanced features for coaching and manual
call routing.
§Core Capabilities
§Monitoring
- Agent Monitoring: Real-time agent status and performance tracking
- Call Monitoring: Active call tracking with detailed information
- Queue Monitoring: Queue statistics and wait time analysis
- Performance Analytics: Comprehensive metrics and reporting
§Management
- Manual Routing: Force assignment of calls to specific agents
- Call Listening: Monitor live calls for quality assurance
- Agent Coaching: Send coaching messages during active calls
- Bridge Management: Track and manage call connections
§Thread Safety
The SupervisorApi
is thread-safe and can be cloned for use across multiple
tasks or components. It maintains a reference to the underlying call center
engine which handles all coordination and state management.
§Examples
§Basic Usage
use rvoip_call_engine::api::SupervisorApi;
use rvoip_call_engine::CallCenterEngine;
use std::sync::Arc;
let supervisor = SupervisorApi::new(engine);
// Get real-time statistics
let stats = supervisor.get_stats().await;
println!("Active calls: {}", stats.active_calls);
// List all agents
let agents = supervisor.list_agents().await;
println!("Total agents: {}", agents.len());
Implementations§
Source§impl SupervisorApi
impl SupervisorApi
Sourcepub fn new(engine: Arc<CallCenterEngine>) -> Self
pub fn new(engine: Arc<CallCenterEngine>) -> Self
Create a new supervisor API instance
Initializes a new supervisor API connected to the specified call center engine. The API provides access to all monitoring and management capabilities.
§Arguments
engine
- Shared reference to the call center engine
§Examples
use rvoip_call_engine::api::SupervisorApi;
use rvoip_call_engine::CallCenterEngine;
use std::sync::Arc;
let engine = CallCenterEngine::new(Default::default(), None).await?;
let supervisor = SupervisorApi::new(engine);
Sourcepub async fn get_stats(&self) -> OrchestratorStats
pub async fn get_stats(&self) -> OrchestratorStats
Get real-time orchestrator statistics
Returns comprehensive real-time statistics about the call center including active calls, agent availability, queue depths, and routing performance. This is the primary method for getting an overview of system status.
§Returns
OrchestratorStats
containing:
- Active calls count
- Available/busy agents count
- Queue depths across all queues
- Routing performance metrics
§Examples
use rvoip_call_engine::api::SupervisorApi;
let supervisor = SupervisorApi::new(engine);
let stats = supervisor.get_stats().await;
println!("📊 Call Center Status:");
println!(" Active calls: {}", stats.active_calls);
println!(" Available agents: {}", stats.available_agents);
println!(" Busy agents: {}", stats.busy_agents);
println!(" Queued calls: {}", stats.queued_calls);
// Check for capacity issues
if stats.queued_calls > stats.available_agents * 2 {
println!("⚠️ High queue to agent ratio detected!");
}
Sourcepub async fn list_agents(&self) -> Vec<AgentInfo>
pub async fn list_agents(&self) -> Vec<AgentInfo>
List all agents with their current status
Returns detailed information for each registered agent including their current status, active calls, skills, and performance metrics. This provides a comprehensive view of agent availability and activity.
§Returns
Vector of AgentInfo
containing:
- Agent identification and contact information
- Current status (available, busy, offline)
- Active calls count and details
- Skills and capabilities
- Performance score and metrics
- Last activity timestamp
§Examples
use rvoip_call_engine::api::SupervisorApi;
let supervisor = SupervisorApi::new(engine);
let agents = supervisor.list_agents().await;
println!("👥 Agent Overview:");
for agent in agents {
let status_icon = match agent.status {
_ if agent.current_calls > 0 => "📞",
_ => "🟢",
};
println!(" {} {} ({}): {} active calls, skills: {:?}",
status_icon, agent.agent_id.0, agent.agent_id.0,
agent.current_calls, agent.skills);
// Highlight performance issues
if agent.performance_score < 0.7 {
println!(" ⚠️ Performance below threshold");
}
}
Sourcepub async fn get_agent_details(&self, agent_id: &AgentId) -> Option<AgentInfo>
pub async fn get_agent_details(&self, agent_id: &AgentId) -> Option<AgentInfo>
Get detailed information about a specific agent
Retrieves comprehensive information for a single agent including their current status, active calls, and performance metrics.
§Arguments
agent_id
- Identifier of the agent to retrieve
§Returns
Some(AgentInfo)
if agent found, None
if agent doesn’t exist.
§Examples
use rvoip_call_engine::api::SupervisorApi;
use rvoip_call_engine::agent::AgentId;
let supervisor = SupervisorApi::new(engine);
let agent_id = AgentId::from("agent-001");
if let Some(agent) = supervisor.get_agent_details(&agent_id).await {
println!("🔍 Agent Details:");
println!(" Agent ID: {}", agent.agent_id.0);
println!(" Status: {:?}", agent.status);
println!(" Active calls: {}", agent.current_calls);
println!(" Performance: {:.1}%", agent.performance_score * 100.0);
println!(" Skills: {:?}", agent.skills);
} else {
println!("❌ Agent not found");
}
Sourcepub async fn list_active_calls(&self) -> Vec<CallInfo>
pub async fn list_active_calls(&self) -> Vec<CallInfo>
List all active calls
Returns comprehensive information about all calls currently active in the system, including both connected calls and calls waiting in queues. This provides a system-wide view of call activity.
§Returns
Vector of CallInfo
containing:
- Session identification and routing information
- Call status (active, queued, ringing)
- Agent assignment details
- Queue assignment and wait times
- Call duration and timestamps
- Caller identification information
§Examples
use rvoip_call_engine::api::SupervisorApi;
let supervisor = SupervisorApi::new(engine);
let active_calls = supervisor.list_active_calls().await;
println!("📞 Active Calls Overview:");
for call in active_calls {
println!(" Call {}: {:?}", call.session_id, call.status);
if let Some(agent_id) = &call.agent_id {
println!(" Agent: {}", agent_id);
}
if let Some(queue_id) = &call.queue_id {
let wait_time = call.queue_time_seconds;
println!(" Queue: {} (waiting {}s)", queue_id, wait_time);
}
let duration = call.duration_seconds;
println!(" Duration: {}s", duration);
}
Sourcepub async fn get_call_details(&self, session_id: &SessionId) -> Option<CallInfo>
pub async fn get_call_details(&self, session_id: &SessionId) -> Option<CallInfo>
Get detailed information about a specific call
Retrieves comprehensive information for a single call by its session ID. This is useful for detailed call analysis and troubleshooting.
§Arguments
session_id
- Session identifier of the call to retrieve
§Returns
Some(CallInfo)
if call found, None
if call doesn’t exist or has ended.
§Examples
use rvoip_call_engine::api::SupervisorApi;
use rvoip_session_core::SessionId;
let supervisor = SupervisorApi::new(engine);
let session_id = SessionId::new(); // In practice, get from active calls
if let Some(call) = supervisor.get_call_details(&session_id).await {
println!("📞 Call Details:");
println!(" Session: {}", call.session_id);
println!(" Status: {:?}", call.status);
println!(" Caller ID: {:?}", call.caller_id);
if let Some(agent) = &call.agent_id {
println!(" Assigned Agent: {}", agent);
}
let duration = call.duration_seconds;
println!(" Duration: {}m {}s", duration / 60, duration % 60);
} else {
println!("❌ Call not found or has ended");
}
Sourcepub async fn monitor_agent_calls(&self, agent_id: &AgentId) -> Vec<CallInfo>
pub async fn monitor_agent_calls(&self, agent_id: &AgentId) -> Vec<CallInfo>
Monitor calls assigned to a specific agent
Returns information about all calls currently assigned to the specified agent. This is useful for agent-specific monitoring and coaching.
§Arguments
agent_id
- Identifier of the agent to monitor
§Returns
Vector of CallInfo
for all calls assigned to the agent.
§Examples
use rvoip_call_engine::api::SupervisorApi;
use rvoip_call_engine::agent::AgentId;
let supervisor = SupervisorApi::new(engine);
let agent_id = AgentId::from("agent-001");
let agent_calls = supervisor.monitor_agent_calls(&agent_id).await;
println!("📞 Agent {} Calls:", agent_id);
for call in &agent_calls {
let duration = call.duration_seconds;
println!(" Call {}: {}m {}s",
call.session_id, duration / 60, duration % 60);
println!(" From: {}", call.caller_id);
// Alert on long calls
if duration > 600 { // 10 minutes
println!(" ⚠️ Long call duration");
}
}
if agent_calls.is_empty() {
println!(" No active calls");
}
Sourcepub async fn get_all_queue_stats(
&self,
) -> CallCenterResult<Vec<(String, QueueStats)>>
pub async fn get_all_queue_stats( &self, ) -> CallCenterResult<Vec<(String, QueueStats)>>
Get queue statistics for all queues
Returns comprehensive statistics for all configured queues including call counts, wait times, and performance metrics.
§Returns
Ok(Vec<(String, QueueStats)>)
with queue name and statistics pairs,
or error if statistics retrieval fails.
§Examples
use rvoip_call_engine::api::SupervisorApi;
let supervisor = SupervisorApi::new(engine);
let queue_stats = supervisor.get_all_queue_stats().await?;
println!("📋 Queue Statistics:");
for (queue_id, stats) in queue_stats {
println!(" Queue: {}", queue_id);
println!(" Total calls: {}", stats.total_calls);
println!(" Avg wait: {}s", stats.average_wait_time_seconds);
println!(" Max wait: {}s", stats.longest_wait_time_seconds);
// Alert on high wait times
if stats.average_wait_time_seconds > 120 {
println!(" 🚨 High average wait time!");
}
// Alert on queue depth
if stats.total_calls > 15 {
println!(" ⚠️ High queue depth!");
}
}
Sourcepub async fn get_queued_calls(&self, queue_id: &str) -> Vec<CallInfo>
pub async fn get_queued_calls(&self, queue_id: &str) -> Vec<CallInfo>
Get calls in a specific queue
Returns information about all calls currently waiting in the specified queue. This provides detailed queue analysis and wait time monitoring.
§Arguments
queue_id
- Identifier of the queue to examine
§Returns
Vector of CallInfo
for all calls in the specified queue.
§Examples
use rvoip_call_engine::api::SupervisorApi;
let supervisor = SupervisorApi::new(engine);
let vip_queue_calls = supervisor.get_queued_calls("vip").await;
print!("🌟 VIP Queue Status:");
if vip_queue_calls.is_empty() {
println!(" No calls waiting");
} else {
for (index, call) in vip_queue_calls.iter().enumerate() {
let wait_time = call.queue_time_seconds;
println!(" {}. Call {} - waiting {}s",
index + 1, call.session_id, wait_time);
println!(" From: {}", call.caller_id);
// VIP calls should be prioritized
if wait_time > 60 {
println!(" 🚨 VIP customer waiting too long!");
}
}
}
Sourcepub async fn list_active_bridges(&self) -> Vec<BridgeInfo>
pub async fn list_active_bridges(&self) -> Vec<BridgeInfo>
List all active bridges (connected calls)
Returns information about all active call bridges in the system. Bridges represent connected calls between parties and are used for call monitoring and management purposes.
§Returns
Vector of BridgeInfo
containing bridge identification and connection details.
§Examples
use rvoip_call_engine::api::SupervisorApi;
let supervisor = SupervisorApi::new(engine);
let bridges = supervisor.list_active_bridges().await;
println!("🌉 Active Bridges:");
for bridge in &bridges {
println!(" Bridge {}: {} participants", bridge.id, bridge.participant_count);
for session in &bridge.sessions {
println!(" Session: {}", session);
}
}
if bridges.is_empty() {
println!(" No active bridges");
}
Sourcepub async fn force_assign_call(
&self,
session_id: SessionId,
agent_id: AgentId,
) -> CallCenterResult<()>
pub async fn force_assign_call( &self, session_id: SessionId, agent_id: AgentId, ) -> CallCenterResult<()>
Force assign a queued call to a specific agent
Allows supervisors to manually route calls when automatic routing is insufficient or when special handling is required. This bypasses normal routing rules and assigns the call directly to the specified agent.
§Arguments
session_id
- Session identifier of the call to assignagent_id
- Identifier of the agent to receive the call
§Returns
Ok(())
if assignment successful, or error if assignment fails.
§Examples
use rvoip_call_engine::api::SupervisorApi;
use rvoip_call_engine::agent::AgentId;
use rvoip_session_core::SessionId;
let supervisor = SupervisorApi::new(engine);
// Find a high-priority call that needs immediate attention
let queued_calls = supervisor.get_queued_calls("vip").await;
if let Some(urgent_call) = queued_calls.first() {
// Find an available specialist agent
let agents = supervisor.list_agents().await;
let specialist = agents.iter()
.find(|agent| agent.skills.contains(&"vip".to_string()) &&
agent.current_calls == 0);
if let Some(agent) = specialist {
// Force assign the urgent call
supervisor.force_assign_call(
urgent_call.session_id.clone(),
agent.agent_id.clone()
).await?;
println!("✅ Urgent call assigned to specialist: {}", agent.agent_id.0);
} else {
println!("⚠️ No specialist agents available");
}
}
Sourcepub async fn get_performance_metrics(
&self,
start_time: DateTime<Utc>,
end_time: DateTime<Utc>,
) -> PerformanceMetrics
pub async fn get_performance_metrics( &self, start_time: DateTime<Utc>, end_time: DateTime<Utc>, ) -> PerformanceMetrics
Get performance metrics for a specific time period
Returns comprehensive performance analytics for the specified time range, including call volumes, service levels, and timing metrics. This data is essential for performance monitoring and reporting.
§Arguments
start_time
- Beginning of the analysis periodend_time
- End of the analysis period
§Returns
PerformanceMetrics
containing comprehensive call center performance data.
§Examples
use rvoip_call_engine::api::SupervisorApi;
use chrono::{Utc, Duration};
let supervisor = SupervisorApi::new(engine);
// Get metrics for the last 4 hours
let end_time = Utc::now();
let start_time = end_time - Duration::hours(4);
let metrics = supervisor.get_performance_metrics(start_time, end_time).await;
println!("📊 Performance Report ({} to {})",
start_time.format("%H:%M"), end_time.format("%H:%M"));
println!("┌─────────────────────────────────────────┐");
println!("│ Total Calls: {:>6} | Answered: {:>6} │",
metrics.total_calls, metrics.calls_answered);
println!("│ Queued: {:>6} | Abandoned: {:>6} │",
metrics.calls_queued, metrics.calls_abandoned);
println!("│ Avg Wait: {:>4}s | Avg Handle: {:>4}s │",
metrics.average_wait_time_ms / 1000,
metrics.average_handle_time_ms / 1000);
println!("│ Service Level: {:>6.1}% │",
metrics.service_level_percentage);
println!("└─────────────────────────────────────────┘");
// Performance alerts
if metrics.service_level_percentage < 80.0 {
println!("🚨 Service level below target!");
}
if metrics.average_wait_time_ms > 120000 { // 2 minutes
println!("⏰ Average wait time exceeds target!");
}
let answer_rate = metrics.calls_answered as f32 / metrics.total_calls as f32 * 100.0;
if answer_rate < 90.0 {
println!("📞 Answer rate below target: {:.1}%", answer_rate);
}
Sourcepub async fn listen_to_call(
&self,
session_id: &SessionId,
) -> CallCenterResult<Option<BridgeId>>
pub async fn listen_to_call( &self, session_id: &SessionId, ) -> CallCenterResult<Option<BridgeId>>
Listen to a live call (supervisor monitoring)
Enables supervisors to monitor live calls for quality assurance and coaching purposes. Returns the bridge ID that can be used to join the call in listen-only mode.
§Arguments
session_id
- Session identifier of the call to monitor
§Returns
Ok(Some(BridgeId))
if call can be monitored, Ok(None)
if call
not found or not bridged, or error if monitoring fails.
§Note
Actual implementation requires additional session-core support for listen-only mode participation in bridges.
§Examples
use rvoip_call_engine::api::SupervisorApi;
use rvoip_session_core::SessionId;
let supervisor = SupervisorApi::new(engine);
// Monitor a specific call for quality assurance
let active_calls = supervisor.list_active_calls().await;
for call in active_calls {
// Focus on longer calls for quality monitoring
if call.duration_seconds > 300 { // 5+ minutes
match supervisor.listen_to_call(&call.session_id).await? {
Some(bridge_id) => {
println!("🎧 Monitoring call {} on bridge {}",
call.session_id, bridge_id);
if let Some(agent_id) = &call.agent_id {
println!(" Agent: {}", agent_id);
}
// In practice, would establish listen-only connection
break;
}
None => {
println!("❌ Cannot monitor call {} - not bridged", call.session_id);
}
}
}
}
Sourcepub async fn coach_agent(
&self,
agent_id: &AgentId,
message: &str,
) -> CallCenterResult<()>
pub async fn coach_agent( &self, agent_id: &AgentId, message: &str, ) -> CallCenterResult<()>
Send a message to an agent during a call (coaching)
Enables supervisors to send coaching messages to agents during active calls. This supports real-time coaching and guidance for improved call handling.
§Arguments
agent_id
- Identifier of the agent to coachmessage
- Coaching message to send to the agent
§Returns
Ok(())
if message sent successfully, or error if coaching fails.
§Note
This is a placeholder implementation. Actual coaching functionality requires whisper/coaching support in the media layer.
§Examples
use rvoip_call_engine::api::SupervisorApi;
use rvoip_call_engine::agent::AgentId;
let supervisor = SupervisorApi::new(engine);
let agent_id = AgentId::from("agent-001");
// Monitor agent performance and provide coaching
let agent_calls = supervisor.monitor_agent_calls(&agent_id).await;
for call in agent_calls {
let duration = call.duration_seconds;
// Provide coaching based on call duration
if duration > 480 { // 8+ minutes
supervisor.coach_agent(
&agent_id,
"Call is running long - consider summarizing and wrapping up"
).await?;
println!("💬 Coaching sent: Call wrap-up guidance");
} else if duration > 240 { // 4+ minutes
supervisor.coach_agent(
&agent_id,
"Midpoint check - ensure you're addressing the customer's main concern"
).await?;
println!("💬 Coaching sent: Midpoint guidance");
}
}
// Proactive coaching for new agents
if let Some(agent) = supervisor.get_agent_details(&agent_id).await {
if agent.performance_score < 0.7 {
supervisor.coach_agent(
&agent_id,
"Remember to use active listening and confirm customer understanding"
).await?;
println!("💬 Coaching sent: Performance improvement guidance");
}
}
Trait Implementations§
Source§impl Clone for SupervisorApi
impl Clone for SupervisorApi
Source§fn clone(&self) -> SupervisorApi
fn clone(&self) -> SupervisorApi
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreAuto Trait Implementations§
impl Freeze for SupervisorApi
impl !RefUnwindSafe for SupervisorApi
impl Send for SupervisorApi
impl Sync for SupervisorApi
impl Unpin for SupervisorApi
impl !UnwindSafe for SupervisorApi
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more