#[non_exhaustive]pub struct Warning {
pub kind: WarningKind,
pub subject: Subject,
pub provider: Option<Cow<'static, str>>,
pub code: Option<Cow<'static, str>>,
pub message: String,
pub cause: Option<WarningCause>,
/* private fields */
}Expand description
A non-fatal issue reported alongside a successful response.
§Emission
A warning remembers whether it was already emitted as a warning event
(emit), so a wrapper that passes it on emits it no second time. The
mark is not serialized and is ignored by ==. A clone keeps it: a
warning copied into another response and passed through
Prepared::finish again is not logged
again. A deserialized warning is unmarked, so it is emitted again by the
next layer that finishes a call with it (see the
module docs on response caches).
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.kind: WarningKindWhat kind of degradation happened.
subject: SubjectWhat the warning is about.
provider: Option<Cow<'static, str>>Provider that produced the warning, when known.
code: Option<Cow<'static, str>>A stable code for the condition (unsupported.seed), when the
producer gives one.
A code says the warning describes the shape of a request or of the
configuration, so it recurs on every call that has that shape: its
warning event goes out at WARN once per provider, model, kind and
code, then at DEBUG (see the module docs).
A warning without a code is about this call alone (a failover,
content the application sent) and its event is WARN every time.
A limitation about content that history repeats on every turn is
coded all the same (approximated.tool_result_error, see
Degradations::coded_approximated).
Degradations gives a warning about a request field or a system
prompt the code <kind>.<field> (unsupported.seed,
dropped.system) when it has none.
message: StringHuman-readable explanation.
cause: Option<WarningCause>The failure behind the warning, for a warning a failure caused: the
error a FallbackProvider
failed over on. Structured, so failovers can be counted by cause.
Implementations§
Source§impl Warning
impl Warning
Sourcepub fn new(
kind: WarningKind,
subject: Subject,
message: impl Into<String>,
) -> Self
pub fn new( kind: WarningKind, subject: Subject, message: impl Into<String>, ) -> Self
Create a warning.
Sourcepub fn unsupported(field: RequestField, message: impl Into<String>) -> Self
pub fn unsupported(field: RequestField, message: impl Into<String>) -> Self
An unsupported-field warning.
Sourcepub fn with_provider(self, provider: impl Into<Cow<'static, str>>) -> Self
pub fn with_provider(self, provider: impl Into<Cow<'static, str>>) -> Self
Set the provider identity.
Sourcepub fn with_code(self, code: &'static str) -> Self
pub fn with_code(self, code: &'static str) -> Self
Set a stable code for the condition (see code).
Give one to a warning that recurs on every call with the same request shape or configuration, such as a hint the model never takes; leave it out for a warning about this call alone.
Sourcepub fn recurs(&self) -> bool
pub fn recurs(&self) -> bool
Whether the warning recurs on every call with the same request shape or configuration: whether it has a code.
A recurring warning says the same thing on the next call, so an
application shows it once, with SeenWarnings. A warning that does
not recur is about this call alone (a failover, content the
application sent) and is worth showing every time.
use allama::{RequestField, Subject, Warning, WarningKind};
let seed = Warning::unsupported(RequestField::Seed, "demo has no seed; `seed` was not sent")
.with_code("unsupported.seed");
assert!(seed.recurs());
let failover = Warning::new(
WarningKind::Fallback,
Subject::Response,
"failed with `overloaded`; served by `b`",
);
assert!(!failover.recurs());Sourcepub fn replay_state(&self) -> Option<ReplayState>
pub fn replay_state(&self) -> Option<ReplayState>
The replay state the warning reports as dropped: a
Dropped warning coded with a
ReplayState::code, as Degradations::dropped_replay_state
records it.
Match on it, rather than on the message, to tell the user about replay state in your own words:
use allama::adapter::Degradations;
use allama::{ReplayState, Subject, UnsupportedPolicy};
let mut d = Degradations::new("demo", UnsupportedPolicy::Warn);
d.dropped_replay_state(
ReplayState::ForeignReasoning,
Subject::Content { message: 1, block: Some(0) },
"reasoning from `openai` can be replayed only to its origin; it was dropped",
);
let state = d.warnings()[0].replay_state();
assert_eq!(state, Some(ReplayState::ForeignReasoning));
assert!(state.is_some_and(ReplayState::is_foreign));Sourcepub fn with_cause(self, cause: WarningCause) -> Self
pub fn with_cause(self, cause: WarningCause) -> Self
Set the failure behind the warning (see cause).
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Warning
impl<'de> Deserialize<'de> for Warning
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 Display for Warning
The provider in brackets, then where the warning applies for a warning
about content, then the message: [ollama] message 3, block 0: ….
impl Display for Warning
The provider in brackets, then where the warning applies for a warning
about content, then the message: [ollama] message 3, block 0: ….
The location is shown for Subject::Content (message 3, block 0)
and Subject::EmbeddingInput (embedding input 2, part 1), whose
message cannot say which block it is about. Indices are zero-based and
those of the caller’s request: message indexes
ChatRequest::messages, so system prompts, which are
ChatRequest::system, do not count. Other subjects are named by the
message itself ( `seed` was not sent), so nothing is added.
use allama::{Subject, Warning, WarningKind};
let content = Subject::Content { message: 3, block: Some(0) };
let warning = Warning::new(WarningKind::Dropped, content, "`ollama` takes no reasoning back; it was dropped")
.with_provider("ollama");
assert_eq!(
warning.to_string(),
"[ollama] message 3, block 0: `ollama` takes no reasoning back; it was dropped"
);impl Eq for Warning
Source§impl Extend<Warning> for Degradations
impl Extend<Warning> for Degradations
Source§fn extend<I: IntoIterator<Item = Warning>>(&mut self, warnings: I)
fn extend<I: IntoIterator<Item = Warning>>(&mut self, warnings: I)
Record warnings collected elsewhere, such as an encoder’s, as
warn does.
Source§fn extend_one(&mut self, item: T)
fn extend_one(&mut self, item: T)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)