Skip to main content

ai_lib_rust/telemetry/
mod.rs

1//! Telemetry and feedback (optional, application-controlled).
2//!
3//! The runtime MUST NOT force telemetry collection. Instead it provides:
4//! - a stable `client_request_id` for linkage
5//! - typed feedback events
6//! - an injectable `FeedbackSink` hook (default: no-op)
7
8use crate::Result;
9use async_trait::async_trait;
10use std::sync::Arc;
11
12/// Minimal user feedback for multi-candidate selection.
13#[derive(Debug, Clone)]
14pub struct ChoiceSelectionFeedback {
15    /// Request identifier emitted by the runtime (`client_request_id`).
16    pub request_id: String,
17    /// The chosen candidate index (0-based).
18    pub chosen_index: u32,
19    /// Optional rejected indices (0-based).
20    pub rejected_indices: Option<Vec<u32>>,
21    /// Time from render to selection (ms), if the UI can measure it.
22    pub latency_to_select_ms: Option<u64>,
23    /// Optional UI context (component name / experiment id / etc.)
24    pub ui_context: Option<serde_json::Value>,
25    /// Optional content hashes to link choice to rendered candidates without uploading text.
26    pub candidate_hashes: Option<Vec<String>>,
27}
28
29/// Typed feedback events (extensible).
30#[derive(Debug, Clone)]
31pub enum FeedbackEvent {
32    ChoiceSelection(ChoiceSelectionFeedback),
33}
34
35/// Feedback sink hook. Applications decide whether and where to store/report feedback.
36#[async_trait]
37pub trait FeedbackSink: Send + Sync {
38    async fn report(&self, event: FeedbackEvent) -> Result<()>;
39}
40
41/// Default sink: do nothing.
42pub struct NoopFeedbackSink;
43
44#[async_trait]
45impl FeedbackSink for NoopFeedbackSink {
46    async fn report(&self, _event: FeedbackEvent) -> Result<()> {
47        Ok(())
48    }
49}
50
51pub fn noop_sink() -> Arc<dyn FeedbackSink> {
52    Arc::new(NoopFeedbackSink)
53}