Module agents.metrics.metrics_schema
Classes
class BaseComponentMetrics (id: str = '', provider_class: str = '', model_name: str = '')-
Expand source code
@dataclass class BaseComponentMetrics: """Base for component-specific metrics with provider and model identity.""" id: str = "" provider_class: str = "" model_name: str = ""Base for component-specific metrics with provider and model identity.
Subclasses
Instance variables
var id : strvar model_name : strvar provider_class : str
class EouMetrics (id: str = '',
provider_class: str = '',
model_name: str = '',
eou_latency: float | None = None,
eou_start_time: float | None = None,
eou_end_time: float | None = None,
eou_probability: float | None = None,
min_speech_wait_timeout: float | None = None,
max_speech_wait_timeout: float | None = None,
eou_avg_delay: float | None = None,
waited_for_additional_speech: bool = False,
eou_wait_ms: float | None = None)-
Expand source code
@dataclass class EouMetrics(BaseComponentMetrics): """EOU (End of Utterance) metrics.""" eou_latency: Optional[float] = None eou_start_time: Optional[float] = None eou_end_time: Optional[float] = None eou_probability: Optional[float] = None min_speech_wait_timeout: Optional[float] = None max_speech_wait_timeout: Optional[float] = None eou_avg_delay: Optional[float] = None waited_for_additional_speech: bool = False eou_wait_ms: Optional[float] = NoneEOU (End of Utterance) metrics.
Ancestors
Instance variables
var eou_avg_delay : float | Nonevar eou_end_time : float | Nonevar eou_latency : float | Nonevar eou_probability : float | Nonevar eou_start_time : float | Nonevar eou_wait_ms : float | Nonevar max_speech_wait_timeout : float | Nonevar min_speech_wait_timeout : float | Nonevar waited_for_additional_speech : bool
class FallbackEvent (component_type: str = '',
temporary_disable_sec: float = 0.0,
permanent_disable_after_attempts: int = 0,
recovery_attempt: int = 0,
message: str = '',
start_time: float = <factory>,
end_time: float | None = None,
duration_ms: float | None = None,
original_provider_label: str | None = None,
original_connection_start: float | None = None,
original_connection_end: float | None = None,
original_connection_duration_ms: float | None = None,
new_provider_label: str | None = None,
new_connection_start: float | None = None,
new_connection_end: float | None = None,
new_connection_duration_ms: float | None = None,
is_recovery: bool = False)-
Expand source code
@dataclass class FallbackEvent: """Fallback event when a provider fails and switches to backup.""" component_type: str = "" temporary_disable_sec: float = 0.0 permanent_disable_after_attempts: int = 0 recovery_attempt: int = 0 message: str = "" start_time: float = field(default_factory=time.perf_counter) end_time: Optional[float] = None duration_ms: Optional[float] = None original_provider_label: Optional[str] = None original_connection_start: Optional[float] = None original_connection_end: Optional[float] = None original_connection_duration_ms: Optional[float] = None new_provider_label: Optional[str] = None new_connection_start: Optional[float] = None new_connection_end: Optional[float] = None new_connection_duration_ms: Optional[float] = None is_recovery: bool = FalseFallback event when a provider fails and switches to backup.
Instance variables
var component_type : strvar duration_ms : float | Nonevar end_time : float | Nonevar is_recovery : boolvar message : strvar new_connection_duration_ms : float | Nonevar new_connection_end : float | Nonevar new_connection_start : float | Nonevar new_provider_label : str | Nonevar original_connection_duration_ms : float | Nonevar original_connection_end : float | Nonevar original_connection_start : float | Nonevar original_provider_label : str | Nonevar permanent_disable_after_attempts : intvar recovery_attempt : intvar start_time : floatvar temporary_disable_sec : float
class FunctionToolMetrics (tool_name: str = '',
tool_params: Dict[str, Any] | List[Any] = <factory>,
tool_response: Dict[str, Any] = <factory>,
start_time: float | None = None,
end_time: float | None = None,
latency: float | None = None)-
Expand source code
@dataclass class FunctionToolMetrics: """Metrics for a single function (agent) tool call in a turn.""" tool_name: str = "" tool_params: Union[Dict[str, Any], List[Any]] = field(default_factory=dict) tool_response: Dict[str, Any] = field(default_factory=dict) start_time: Optional[float] = None end_time: Optional[float] = None latency: Optional[float] = NoneMetrics for a single function (agent) tool call in a turn.
Instance variables
var end_time : float | Nonevar latency : float | Nonevar start_time : float | Nonevar tool_name : strvar tool_params : Dict[str, Any] | List[Any]var tool_response : Dict[str, Any]
class InterruptionMetrics (false_interrupt_pause_duration: float | None = None,
resume_on_false_interrupt: bool | None = None,
interrupt_words: int | None = None,
interrupt_duration: float | None = None,
interrupt_reason: List[str] = <factory>,
interrupt_start_time: float | None = None,
interrupt_end_time: float | None = None,
is_false_interrupt: bool = False,
false_interrupt_duration: float | None = None,
false_interrupt_words: int | None = None,
false_interrupt_start_time: float | None = None,
false_interrupt_end_time: float | None = None,
resumed_after_false_interrupt: bool = False,
interrupt_mode: Literal['VAD_ONLY', 'STT_ONLY', 'HYBRID'] | None = None,
interrupt_min_duration: float | None = None,
interrupt_min_words: int | None = None)-
Expand source code
@dataclass class InterruptionMetrics: """Interruption and false-interrupt metrics for a turn.""" false_interrupt_pause_duration: Optional[float] = None resume_on_false_interrupt: Optional[bool] = None interrupt_words: Optional[int] = None interrupt_duration: Optional[float] = None interrupt_reason: List[str] = field(default_factory=list) interrupt_start_time: Optional[float] = None interrupt_end_time: Optional[float] = None is_false_interrupt: bool = False false_interrupt_duration: Optional[float] = None false_interrupt_words: Optional[int] = None false_interrupt_start_time: Optional[float] = None false_interrupt_end_time: Optional[float] = None resumed_after_false_interrupt: bool = False interrupt_mode: Optional[Literal["VAD_ONLY", "STT_ONLY", "HYBRID"]] = None interrupt_min_duration: Optional[float] = None interrupt_min_words: Optional[int] = NoneInterruption and false-interrupt metrics for a turn.
Instance variables
var false_interrupt_duration : float | Nonevar false_interrupt_end_time : float | Nonevar false_interrupt_pause_duration : float | Nonevar false_interrupt_start_time : float | Nonevar false_interrupt_words : int | Nonevar interrupt_duration : float | Nonevar interrupt_end_time : float | Nonevar interrupt_min_duration : float | Nonevar interrupt_min_words : int | Nonevar interrupt_mode : Literal['VAD_ONLY', 'STT_ONLY', 'HYBRID'] | Nonevar interrupt_reason : List[str]var interrupt_start_time : float | Nonevar interrupt_words : int | Nonevar is_false_interrupt : boolvar resume_on_false_interrupt : bool | Nonevar resumed_after_false_interrupt : bool
class KbMetrics (id: str = '',
provider_class: str = '',
model_name: str = '',
kb_id: str | None = None,
kb_documents: List[str] | None = None,
kb_scores: List[float] | None = None,
kb_retrieval_latency: float | None = None,
kb_start_time: float | None = None,
kb_end_time: float | None = None)-
Expand source code
@dataclass class KbMetrics(BaseComponentMetrics): """Knowledge base retrieval metrics.""" kb_id: Optional[str] = None kb_documents: Optional[List[str]] = None kb_scores: Optional[List[float]] = None kb_retrieval_latency: Optional[float] = None kb_start_time: Optional[float] = None kb_end_time: Optional[float] = NoneKnowledge base retrieval metrics.
Ancestors
Instance variables
var kb_documents : List[str] | Nonevar kb_end_time : float | Nonevar kb_id : str | Nonevar kb_retrieval_latency : float | Nonevar kb_scores : List[float] | Nonevar kb_start_time : float | None
class LlmMetrics (id: str = '',
provider_class: str = '',
model_name: str = '',
llm_config: Dict[str, Any] | None = None,
llm_input: str | None = None,
llm_latency: float | None = None,
llm_start_time: float | None = None,
llm_end_time: float | None = None,
llm_duration: float | None = None,
llm_first_token_time: float | None = None,
llm_ttft: float | None = None,
prompt_tokens: int | None = None,
completion_tokens: int | None = None,
total_tokens: int | None = None,
prompt_cached_tokens: int | None = None,
tokens_per_second: float | None = None)-
Expand source code
@dataclass class LlmMetrics(BaseComponentMetrics): """LLM metrics.""" llm_config: Optional[Dict[str, Any]] = None llm_input: Optional[str] = None llm_latency: Optional[float] = None llm_start_time: Optional[float] = None llm_end_time: Optional[float] = None llm_duration: Optional[float] = None llm_first_token_time: Optional[float] = None llm_ttft: Optional[float] = None prompt_tokens: Optional[int] = None completion_tokens: Optional[int] = None total_tokens: Optional[int] = None prompt_cached_tokens: Optional[int] = None tokens_per_second: Optional[float] = NoneLLM metrics.
Ancestors
Instance variables
var completion_tokens : int | Nonevar llm_config : Dict[str, Any] | Nonevar llm_duration : float | Nonevar llm_end_time : float | Nonevar llm_first_token_time : float | Nonevar llm_input : str | Nonevar llm_latency : float | Nonevar llm_start_time : float | Nonevar llm_ttft : float | Nonevar prompt_cached_tokens : int | Nonevar prompt_tokens : int | Nonevar tokens_per_second : float | Nonevar total_tokens : int | None
class McpToolMetrics (type: Literal['local', 'http'] = 'local',
tool_url: str | None = None,
tool_params: Dict[str, Any] | List[Any] = <factory>,
tool_response: Dict[str, Any] = <factory>,
start_time: float | None = None,
end_time: float | None = None,
latency: float | None = None)-
Expand source code
@dataclass class McpToolMetrics: """Metrics for a single MCP tool call in a turn.""" type: Literal["local", "http"] = "local" tool_url: Optional[str] = None # endpoint URL for http, or endpoint identifier tool_params: Union[Dict[str, Any], List[Any]] = field(default_factory=dict) tool_response: Dict[str, Any] = field(default_factory=dict) start_time: Optional[float] = None end_time: Optional[float] = None latency: Optional[float] = NoneMetrics for a single MCP tool call in a turn.
Instance variables
var end_time : float | Nonevar latency : float | Nonevar start_time : float | Nonevar tool_params : Dict[str, Any] | List[Any]var tool_response : Dict[str, Any]var tool_url : str | Nonevar type : Literal['local', 'http']
class ParticipantMetrics (participant_id: str | None = None,
kind: Literal['agent', 'user'] | None = None,
sip_user: bool | None = None,
join_time: float | None = None,
meta: Dict[str, Any] | None = None)-
Expand source code
@dataclass class ParticipantMetrics: """Participant/connection metrics at session level.""" participant_id: Optional[str] = None kind: Optional[Literal["agent", "user"]] = None sip_user: Optional[bool] = None join_time: Optional[float] = None meta: Optional[Dict[str, Any]] = NoneParticipant/connection metrics at session level.
Instance variables
var join_time : float | Nonevar kind : Literal['agent', 'user'] | Nonevar meta : Dict[str, Any] | Nonevar participant_id : str | Nonevar sip_user : bool | None
class RealtimeMetrics (id: str = '',
provider_class: str = '',
model_name: str = '',
realtime_config: Dict[str, Any] | None = None,
realtime_ttfb: float | None = None,
realtime_input_tokens: int | None = None,
realtime_total_tokens: int | None = None,
realtime_output_tokens: int | None = None,
realtime_input_text_tokens: int | None = None,
realtime_input_audio_tokens: int | None = None,
realtime_input_image_tokens: int | None = None,
realtime_input_cached_tokens: int | None = None,
realtime_thoughts_tokens: int | None = None,
realtime_cached_text_tokens: int | None = None,
realtime_cached_audio_tokens: int | None = None,
realtime_cached_image_tokens: int | None = None,
realtime_output_text_tokens: int | None = None,
realtime_output_audio_tokens: int | None = None,
realtime_output_image_tokens: int | None = None)-
Expand source code
@dataclass class RealtimeMetrics(BaseComponentMetrics): """Realtime model (full s2s) metrics.""" realtime_config: Optional[Dict[str, Any]] = None realtime_ttfb: Optional[float] = None realtime_input_tokens: Optional[int] = None realtime_total_tokens: Optional[int] = None realtime_output_tokens: Optional[int] = None realtime_input_text_tokens: Optional[int] = None realtime_input_audio_tokens: Optional[int] = None realtime_input_image_tokens: Optional[int] = None realtime_input_cached_tokens: Optional[int] = None realtime_thoughts_tokens: Optional[int] = None realtime_cached_text_tokens: Optional[int] = None realtime_cached_audio_tokens: Optional[int] = None realtime_cached_image_tokens: Optional[int] = None realtime_output_text_tokens: Optional[int] = None realtime_output_audio_tokens: Optional[int] = None realtime_output_image_tokens: Optional[int] = NoneRealtime model (full s2s) metrics.
Ancestors
Instance variables
var realtime_cached_audio_tokens : int | Nonevar realtime_cached_image_tokens : int | Nonevar realtime_cached_text_tokens : int | Nonevar realtime_config : Dict[str, Any] | Nonevar realtime_input_audio_tokens : int | Nonevar realtime_input_cached_tokens : int | Nonevar realtime_input_image_tokens : int | Nonevar realtime_input_text_tokens : int | Nonevar realtime_input_tokens : int | Nonevar realtime_output_audio_tokens : int | Nonevar realtime_output_image_tokens : int | Nonevar realtime_output_text_tokens : int | Nonevar realtime_output_tokens : int | Nonevar realtime_thoughts_tokens : int | Nonevar realtime_total_tokens : int | Nonevar realtime_ttfb : float | None
class SessionMetrics (session_id: str | None = None,
room_id: str | None = None,
system_instruction: str = '',
components: List[str] = <factory>,
pipeline_type: str | None = None,
pipeline_mode: str | None = None,
realtime_mode: str | None = None,
session_start_time: float = <factory>,
session_end_time: float | None = None,
participant_metrics: List[ParticipantMetrics] = <factory>,
errors: List[Dict[str, Any]] = <factory>,
provider_per_component: Dict[str, Dict[str, str]] = <factory>,
eou_config: Dict[str, Any] | None = None,
interrupt_config: Dict[str, Any] | None = None)-
Expand source code
@dataclass class SessionMetrics: """Session-level metrics.""" session_id: Optional[str] = None room_id: Optional[str] = None system_instruction: str = "" components: List[str] = field(default_factory=list) pipeline_type: Optional[str] = None pipeline_mode: Optional[str] = None realtime_mode: Optional[str] = None session_start_time: float = field(default_factory=time.time) session_end_time: Optional[float] = None participant_metrics: List[ParticipantMetrics] = field(default_factory=list) errors: List[Dict[str, Any]] = field(default_factory=list) provider_per_component: Dict[str, Dict[str, str]] = field(default_factory=dict) eou_config: Optional[Dict[str, Any]] = None interrupt_config: Optional[Dict[str, Any]] = NoneSession-level metrics.
Instance variables
var components : List[str]var eou_config : Dict[str, Any] | Nonevar errors : List[Dict[str, Any]]var interrupt_config : Dict[str, Any] | Nonevar participant_metrics : List[ParticipantMetrics]var pipeline_mode : str | Nonevar pipeline_type : str | Nonevar provider_per_component : Dict[str, Dict[str, str]]var realtime_mode : str | Nonevar room_id : str | Nonevar session_end_time : float | Nonevar session_id : str | Nonevar session_start_time : floatvar system_instruction : str
class SttMetrics (id: str = '',
provider_class: str = '',
model_name: str = '',
stt_config: Dict[str, Any] | None = None,
stt_confidence: float | None = None,
stt_input_tokens: int | None = None,
stt_output_tokens: int | None = None,
stt_total_tokens: int | None = None,
stt_latency: float | None = None,
stt_start_time: float | None = None,
stt_end_time: float | None = None,
stt_duration: float | None = None,
stt_preflight_end_time: float | None = None,
stt_preflight_latency: float | None = None,
stt_interim_end_time: float | None = None,
stt_interim_latency: float | None = None,
stt_ttfw: float | None = None,
stt_preemptive_generation_occurred: bool = False,
stt_preemptive_generation_enabled: bool = False,
stt_transcript: str | None = None,
stt_preflight_transcript: str | None = None)-
Expand source code
@dataclass class SttMetrics(BaseComponentMetrics): """STT (Speech-to-Text) metrics.""" stt_config: Optional[Dict[str, Any]] = None stt_confidence: Optional[float] = None stt_input_tokens: Optional[int] = None stt_output_tokens: Optional[int] = None stt_total_tokens: Optional[int] = None stt_latency: Optional[float] = None stt_start_time: Optional[float] = None stt_end_time: Optional[float] = None stt_duration: Optional[float] = None stt_preflight_end_time: Optional[float] = None stt_preflight_latency: Optional[float] = None stt_interim_end_time: Optional[float] = None stt_interim_latency: Optional[float] = None stt_ttfw: Optional[float] = None stt_preemptive_generation_occurred: bool = False stt_preemptive_generation_enabled: bool = False stt_transcript: Optional[str] = None stt_preflight_transcript: Optional[str] = NoneSTT (Speech-to-Text) metrics.
Ancestors
Instance variables
var stt_confidence : float | Nonevar stt_config : Dict[str, Any] | Nonevar stt_duration : float | Nonevar stt_end_time : float | Nonevar stt_input_tokens : int | Nonevar stt_interim_end_time : float | Nonevar stt_interim_latency : float | Nonevar stt_latency : float | Nonevar stt_output_tokens : int | Nonevar stt_preemptive_generation_enabled : boolvar stt_preemptive_generation_occurred : boolvar stt_preflight_end_time : float | Nonevar stt_preflight_latency : float | Nonevar stt_preflight_transcript : str | Nonevar stt_start_time : float | Nonevar stt_total_tokens : int | Nonevar stt_transcript : str | Nonevar stt_ttfw : float | None
class TimelineEvent (event_type: str = '',
start_time: float = 0.0,
end_time: float | None = None,
duration_ms: float | None = None,
text: str = '')-
Expand source code
@dataclass class TimelineEvent: """Data structure for a single timeline event.""" event_type: str = "" start_time: float = 0.0 end_time: Optional[float] = None duration_ms: Optional[float] = None text: str = ""Data structure for a single timeline event.
Instance variables
var duration_ms : float | Nonevar end_time : float | Nonevar event_type : strvar start_time : floatvar text : str
class TtsMetrics (id: str = '',
provider_class: str = '',
model_name: str = '',
tts_config: Dict[str, Any] | None = None,
tts_latency: float | None = None,
tts_start_time: float | None = None,
tts_end_time: float | None = None,
tts_duration: float | None = None,
tts_characters: int | None = 0,
tts_first_byte_time: float | None = None,
ttfb: float | None = None)-
Expand source code
@dataclass class TtsMetrics(BaseComponentMetrics): """TTS metrics.""" tts_config: Optional[Dict[str, Any]] = None tts_latency: Optional[float] = None tts_start_time: Optional[float] = None tts_end_time: Optional[float] = None tts_duration: Optional[float] = None tts_characters: Optional[int] = 0 tts_first_byte_time: Optional[float] = None ttfb: Optional[float] = NoneTTS metrics.
Ancestors
Instance variables
var ttfb : float | Nonevar tts_characters : int | Nonevar tts_config : Dict[str, Any] | Nonevar tts_duration : float | Nonevar tts_end_time : float | Nonevar tts_first_byte_time : float | Nonevar tts_latency : float | Nonevar tts_start_time : float | None
class TurnMetrics (turn_id: str = '',
is_interrupted: bool = False,
user_speech_start_time: float | None = None,
user_speech_end_time: float | None = None,
user_speech_duration: float | None = None,
user_speech: str | None = None,
agent_speech_start_time: float | None = None,
agent_speech_end_time: float | None = None,
agent_speech_duration: float | None = None,
agent_speech: str | None = None,
e2e_latency: float | None = None,
function_tools_called: List[str] = <factory>,
function_tool_timestamps: List[Dict[str, Any]] = <factory>,
is_a2a_enabled: bool = False,
handoff_occurred: bool = False,
errors: List[Dict[str, Any]] = <factory>,
timestamp: float = <factory>,
preemtive_generation_enabled: bool = False,
vad_metrics: List[VadMetrics] = <factory>,
stt_metrics: List[SttMetrics] = <factory>,
eou_metrics: List[EouMetrics] = <factory>,
kb_metrics: List[KbMetrics] = <factory>,
llm_metrics: List[LlmMetrics] = <factory>,
tts_metrics: List[TtsMetrics] = <factory>,
interruption_metrics: InterruptionMetrics | None = None,
realtime_metrics: List[RealtimeMetrics] = <factory>,
timeline_event_metrics: List[TimelineEvent] = <factory>,
fallback_events: List[FallbackEvent] = <factory>,
function_tool_metrics: List[FunctionToolMetrics] = <factory>,
mcp_tool_metrics: List[McpToolMetrics] = <factory>,
session_metrics: SessionMetrics | None = <factory>,
background_audio_file_path: str | None = None,
background_audio_looping: bool | None = None,
thinking_audio_file_path: str | None = None,
thinking_audio_looping: bool | None = None,
thinking_audio_override_thinking: bool | None = None)-
Expand source code
@dataclass class TurnMetrics: """Single turn with lists of per-component metrics.""" turn_id: str = "" is_interrupted: bool = False user_speech_start_time: Optional[float] = None user_speech_end_time: Optional[float] = None user_speech_duration: Optional[float] = None user_speech: Optional[str] = None agent_speech_start_time: Optional[float] = None agent_speech_end_time: Optional[float] = None agent_speech_duration: Optional[float] = None agent_speech: Optional[str] = None e2e_latency: Optional[float] = None function_tools_called: List[str] = field(default_factory=list) function_tool_timestamps: List[Dict[str, Any]] = field(default_factory=list) is_a2a_enabled: bool = False handoff_occurred: bool = False errors: List[Dict[str, Any]] = field(default_factory=list) timestamp: float = field(default_factory=time.time) preemtive_generation_enabled: bool = False vad_metrics: List[VadMetrics] = field(default_factory=list) stt_metrics: List[SttMetrics] = field(default_factory=list) eou_metrics: List[EouMetrics] = field(default_factory=list) kb_metrics: List[KbMetrics] = field(default_factory=list) llm_metrics: List[LlmMetrics] = field(default_factory=list) tts_metrics: List[TtsMetrics] = field(default_factory=list) interruption_metrics: Optional[InterruptionMetrics] = None realtime_metrics: List[RealtimeMetrics] = field(default_factory=list) timeline_event_metrics: List[TimelineEvent] = field(default_factory=list) fallback_events: List[FallbackEvent] = field(default_factory=list) function_tool_metrics: List[FunctionToolMetrics] = field(default_factory=list) mcp_tool_metrics: List[McpToolMetrics] = field(default_factory=list) session_metrics: Optional[SessionMetrics] = field(default_factory=SessionMetrics) # Background audio background_audio_file_path: Optional[str] = None background_audio_looping: Optional[bool] = None # Thinking audio thinking_audio_file_path: Optional[str] = None thinking_audio_looping: Optional[bool] = None thinking_audio_override_thinking: Optional[bool] = None def compute_e2e_latency(self) -> None: """Calculate E2E latency by summing component latencies (STT + EOU + LLM TTFT + TTS).""" e2e_components = [] if self.stt_metrics: stt = self.stt_metrics[-1] if stt.stt_latency is not None: e2e_components.append(stt.stt_latency) if self.eou_metrics: eou = self.eou_metrics[-1] if eou.eou_latency is not None: e2e_components.append(eou.eou_latency) if eou.eou_wait_ms is not None: e2e_components.append(eou.eou_wait_ms) if self.llm_metrics: llm = self.llm_metrics[-1] if llm.llm_ttft is not None: e2e_components.append(llm.llm_ttft) if self.tts_metrics: tts = self.tts_metrics[-1] if tts.tts_latency is not None: e2e_components.append(tts.tts_latency) if self.realtime_metrics: rt = self.realtime_metrics[-1] if rt.realtime_ttfb is not None: e2e_components.append(rt.realtime_ttfb) if e2e_components: self.e2e_latency = round(sum(e2e_components), 4) def to_dict(self) -> Dict[str, Any]: """Serialize turn metrics to a dictionary.""" self.compute_e2e_latency() return asdict(self)Single turn with lists of per-component metrics.
Instance variables
var agent_speech : str | Nonevar agent_speech_duration : float | Nonevar agent_speech_end_time : float | Nonevar agent_speech_start_time : float | Nonevar background_audio_file_path : str | Nonevar background_audio_looping : bool | Nonevar e2e_latency : float | Nonevar eou_metrics : List[EouMetrics]var errors : List[Dict[str, Any]]var fallback_events : List[FallbackEvent]var function_tool_metrics : List[FunctionToolMetrics]var function_tool_timestamps : List[Dict[str, Any]]var function_tools_called : List[str]var handoff_occurred : boolvar interruption_metrics : InterruptionMetrics | Nonevar is_a2a_enabled : boolvar is_interrupted : boolvar kb_metrics : List[KbMetrics]var llm_metrics : List[LlmMetrics]var mcp_tool_metrics : List[McpToolMetrics]var preemtive_generation_enabled : boolvar realtime_metrics : List[RealtimeMetrics]var session_metrics : SessionMetrics | Nonevar stt_metrics : List[SttMetrics]var thinking_audio_file_path : str | Nonevar thinking_audio_looping : bool | Nonevar thinking_audio_override_thinking : bool | Nonevar timeline_event_metrics : List[TimelineEvent]var timestamp : floatvar tts_metrics : List[TtsMetrics]var turn_id : strvar user_speech : str | Nonevar user_speech_duration : float | Nonevar user_speech_end_time : float | Nonevar user_speech_start_time : float | Nonevar vad_metrics : List[VadMetrics]
Methods
def compute_e2e_latency(self) ‑> None-
Expand source code
def compute_e2e_latency(self) -> None: """Calculate E2E latency by summing component latencies (STT + EOU + LLM TTFT + TTS).""" e2e_components = [] if self.stt_metrics: stt = self.stt_metrics[-1] if stt.stt_latency is not None: e2e_components.append(stt.stt_latency) if self.eou_metrics: eou = self.eou_metrics[-1] if eou.eou_latency is not None: e2e_components.append(eou.eou_latency) if eou.eou_wait_ms is not None: e2e_components.append(eou.eou_wait_ms) if self.llm_metrics: llm = self.llm_metrics[-1] if llm.llm_ttft is not None: e2e_components.append(llm.llm_ttft) if self.tts_metrics: tts = self.tts_metrics[-1] if tts.tts_latency is not None: e2e_components.append(tts.tts_latency) if self.realtime_metrics: rt = self.realtime_metrics[-1] if rt.realtime_ttfb is not None: e2e_components.append(rt.realtime_ttfb) if e2e_components: self.e2e_latency = round(sum(e2e_components), 4)Calculate E2E latency by summing component latencies (STT + EOU + LLM TTFT + TTS).
def to_dict(self) ‑> Dict[str, Any]-
Expand source code
def to_dict(self) -> Dict[str, Any]: """Serialize turn metrics to a dictionary.""" self.compute_e2e_latency() return asdict(self)Serialize turn metrics to a dictionary.
class VadMetrics (id: str = '',
provider_class: str = '',
model_name: str = '',
vad_config: Dict[str, Any] | None = None,
user_speech_start_time: float | None = None,
user_speech_end_time: float | None = None,
vad_min_silence_duration: float | None = None,
vad_min_speech_duration: float | None = None,
vad_threshold: float | None = None,
vad_end_of_speech_time: float | None = None)-
Expand source code
@dataclass class VadMetrics(BaseComponentMetrics): """VAD (Voice Activity Detection) metrics.""" vad_config: Optional[Dict[str, Any]] = None user_speech_start_time: Optional[float] = None user_speech_end_time: Optional[float] = None vad_min_silence_duration: Optional[float] = None vad_min_speech_duration: Optional[float] = None vad_threshold: Optional[float] = None vad_end_of_speech_time: Optional[float] = NoneVAD (Voice Activity Detection) metrics.
Ancestors
Instance variables
var user_speech_end_time : float | Nonevar user_speech_start_time : float | Nonevar vad_config : Dict[str, Any] | Nonevar vad_end_of_speech_time : float | Nonevar vad_min_silence_duration : float | Nonevar vad_min_speech_duration : float | Nonevar vad_threshold : float | None