Struct SupervisorApi

Source
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

Source

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);
Source

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!");
}
Source

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");
    }
}
Source

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");
}
Source

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);
}
Source

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");
}
Source

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");
}
Source

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!");
    }
}
Source

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!");
        }
    }
}
Source

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");
}
Source

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 assign
  • agent_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");
    }
}
Source

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 period
  • end_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);
}
Source

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);
            }
        }
    }
}
Source

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 coach
  • message - 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

Source§

fn clone(&self) -> SupervisorApi

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for SupervisorApi

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,