pub struct ProviderTelemetry {Show 14 fields
pub source: String,
pub server_total_ms: Option<u64>,
pub server_load_ms: Option<u64>,
pub server_prompt_eval_ms: Option<u64>,
pub server_generation_ms: Option<u64>,
pub server_prompt_tokens: Option<i64>,
pub server_output_tokens: Option<i64>,
pub client_wall_ms: Option<u64>,
pub runtime_context_length: Option<u64>,
pub runtime_loaded_model: Option<String>,
pub runtime_memory_bytes: Option<u64>,
pub runtime_memory_vram_bytes: Option<u64>,
pub runtime_keep_alive_until: Option<String>,
pub request_id: Option<String>,
}Expand description
Provider-side timing and runtime accounting captured per LLM call.
All fields default to None / empty. Producers fill in what they can
extract and leave the rest absent; consumers must treat missing fields as
“not reported by this provider”, not “zero”.
Fields§
§source: StringWire format the values came from (ollama_chat, openai_usage, …).
See source for the canonical strings. Empty when no telemetry was
captured.
server_total_ms: Option<u64>Total server-side wall clock (Ollama total_duration).
server_load_ms: Option<u64>Time the server spent loading/warming the model (Ollama
load_duration). Useful for detecting cold-start latency.
server_prompt_eval_ms: Option<u64>Prompt-prefill time (Ollama prompt_eval_duration). Anything else
would be marketing — this is the field evals key on for prefill
regression detection.
server_generation_ms: Option<u64>Generation/decode time (Ollama eval_duration).
server_prompt_tokens: Option<i64>Tokens the server reports it prefilled (Ollama prompt_eval_count).
Distinct from LlmResult::input_tokens because hosted providers
frequently bill different token boundaries than the on-device
tokenizer reports.
server_output_tokens: Option<i64>Tokens the server reports it generated (Ollama eval_count).
client_wall_ms: Option<u64>Client-side wall clock around the HTTP request. Includes network and streaming latency the server-side counters omit. Recorded for every call regardless of provider.
runtime_context_length: Option<u64>Context window the model was loaded with (where the runtime
reports it; /api/ps for Ollama).
runtime_loaded_model: Option<String>Exact model id the server resolved. May differ from
LlmResult::model when an alias / digest is rewritten upstream.
runtime_memory_bytes: Option<u64>Total resident bytes for the loaded model (Ollama /api/ps.size).
runtime_memory_vram_bytes: Option<u64>VRAM bytes for the loaded model (Ollama /api/ps.size_vram).
runtime_keep_alive_until: Option<String>When the server will unload the model (Ollama /api/ps.expires_at).
request_id: Option<String>Provider-supplied request id (x-request-id / request_id).
Implementations§
Source§impl ProviderTelemetry
impl ProviderTelemetry
pub fn new(source: &str) -> Self
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true when no meaningful telemetry was captured. A bare
client_wall_ms is still “meaningful” — it lets evals reason about
per-call latency even for providers that report nothing else.
Sourcepub fn ns_to_ms(ns: u64) -> u64
pub fn ns_to_ms(ns: u64) -> u64
Convert nanoseconds (Ollama’s reporting unit) to milliseconds with integer rounding. Centralized so every Ollama timing field uses the same conversion and zero-vs-None semantics line up.
Sourcepub fn from_ollama_done(frame: &Value, source: &str) -> Self
pub fn from_ollama_done(frame: &Value, source: &str) -> Self
Extract Ollama-shape telemetry from a done=true chat or generate
frame. Returns a populated ProviderTelemetry whose source is
the caller-provided wire identifier.
Sourcepub fn from_openai_usage(usage: &Value, request_id: Option<&str>) -> Self
pub fn from_openai_usage(usage: &Value, request_id: Option<&str>) -> Self
Extract OpenAI-shape usage telemetry. Most OpenAI-compatible local
runtimes only report counts; llama.cpp’s usage.timings extension is
folded in here as well so a single envelope captures both shapes.
Sourcepub fn from_anthropic_usage(usage: &Value, request_id: Option<&str>) -> Self
pub fn from_anthropic_usage(usage: &Value, request_id: Option<&str>) -> Self
Extract Anthropic-shape usage telemetry. Anthropic only reports
input/output (and cache) counts — preserving the request id is the
most useful incremental signal beyond what LlmResult already
carries.
Sourcepub fn merge_ollama_ps(&mut self, ps: &OllamaPsModel)
pub fn merge_ollama_ps(&mut self, ps: &OllamaPsModel)
Merge a /api/ps snapshot of a loaded Ollama model into this
telemetry envelope. Only fills in fields that were not already
populated so a per-call extraction keeps precedence.
Sourcepub fn as_vm_dict(&self) -> Option<VmValue>
pub fn as_vm_dict(&self) -> Option<VmValue>
Render this envelope into the dictionary shape llm_call returns.
Returns None if the envelope is empty so callers can omit the key
entirely.
Trait Implementations§
Source§impl Clone for ProviderTelemetry
impl Clone for ProviderTelemetry
Source§fn clone(&self) -> ProviderTelemetry
fn clone(&self) -> ProviderTelemetry
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ProviderTelemetry
impl Debug for ProviderTelemetry
Source§impl Default for ProviderTelemetry
impl Default for ProviderTelemetry
Source§fn default() -> ProviderTelemetry
fn default() -> ProviderTelemetry
Source§impl<'de> Deserialize<'de> for ProviderTelemetry
impl<'de> Deserialize<'de> for ProviderTelemetry
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for ProviderTelemetry
impl PartialEq for ProviderTelemetry
Source§fn eq(&self, other: &ProviderTelemetry) -> bool
fn eq(&self, other: &ProviderTelemetry) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for ProviderTelemetry
impl Serialize for ProviderTelemetry
impl StructuralPartialEq for ProviderTelemetry
Auto Trait Implementations§
impl Freeze for ProviderTelemetry
impl RefUnwindSafe for ProviderTelemetry
impl Send for ProviderTelemetry
impl Sync for ProviderTelemetry
impl Unpin for ProviderTelemetry
impl UnsafeUnpin for ProviderTelemetry
impl UnwindSafe for ProviderTelemetry
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 moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);