bitrouter_core/observe.rs
1//! Handler-level observation callback for request lifecycle events.
2//!
3//! [`ObserveCallback`] fires from the API handler layer with full request
4//! context (route, provider, model, account, latency, usage/error).
5//! This is complementary to [`GenerationHook`](crate::hooks::GenerationHook)
6//! which fires at the model layer with no request context.
7
8use std::future::Future;
9use std::pin::Pin;
10
11use crate::errors::BitrouterError;
12use crate::models::language::usage::LanguageModelUsage;
13
14/// Context about the request available to observation callbacks.
15#[derive(Debug, Clone)]
16pub struct RequestContext {
17 /// The incoming model name (route key).
18 pub route: String,
19 /// The resolved provider name.
20 pub provider: String,
21 /// The resolved model ID sent to the provider.
22 pub model: String,
23 /// The account that made the request, if authentication is enabled.
24 pub account_id: Option<String>,
25 /// End-to-end request latency in milliseconds.
26 pub latency_ms: u64,
27}
28
29/// Event emitted when a request completes successfully.
30#[derive(Debug, Clone)]
31pub struct RequestSuccessEvent {
32 /// Request context.
33 pub ctx: RequestContext,
34 /// Token usage reported by the model.
35 pub usage: LanguageModelUsage,
36}
37
38/// Event emitted when a request fails.
39#[derive(Debug, Clone)]
40pub struct RequestFailureEvent {
41 /// Request context.
42 pub ctx: RequestContext,
43 /// The error that caused the failure.
44 pub error: BitrouterError,
45}
46
47/// Callback trait for observing completed API requests.
48///
49/// Implementations receive rich, typed events with full request context
50/// and can perform side effects such as spend logging, metrics aggregation,
51/// or alerting. Errors in callbacks are expected to be handled internally
52/// (e.g. logged and swallowed) — they must never break request serving.
53///
54/// Methods return boxed futures for dyn-compatibility, allowing multiple
55/// observers to be composed via [`CompositeObserver`](see bitrouter-observe).
56pub trait ObserveCallback: Send + Sync {
57 /// Called after a request completes successfully.
58 fn on_request_success(
59 &self,
60 event: RequestSuccessEvent,
61 ) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
62
63 /// Called after a request fails.
64 fn on_request_failure(
65 &self,
66 event: RequestFailureEvent,
67 ) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
68}