wire/answer/thinking.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4// Copyright (c) 2026 2youg1 and the sprawling contributors
5
6//! Which thinking levels one (Endpoint, model) offers, and where that
7//! answer came from (`crates/wire/spec/Answer/Endpoints.lean` ยง8-92).
8
9use kernel::Effort;
10use serde::{Deserialize, Serialize};
11
12/// The thinking levels one (Endpoint, model) offers, as the gateway's
13/// thinking ladder resolved them.
14///
15/// Sourced rather than said: `from` names the rung of the ladder that
16/// answered, so a page never mistakes this for the upstream's own words,
17/// which are the other fields of the model row.
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
20pub struct ThinkingOffer {
21 /// In the city's fixed ascending order; never `none`, because turning
22 /// thinking off is not a level. Empty means no thinking control.
23 pub levels: Vec<Effort>,
24 /// Whether a model with a switch and no levels may be asked to think.
25 pub on: Switch,
26 /// The level the upstream says it uses when asked for none.
27 pub default: Option<Effort>,
28 /// Whether the upstream says it thinks when sent nothing.
29 pub default_on: Option<bool>,
30 /// The upstream's own word for a level, where it differs from the
31 /// city's spelling.
32 pub words: Vec<EffortWord>,
33 pub from: OfferSource,
34 /// Where a preset rung's statement is written.
35 pub source: Option<String>,
36}
37
38impl ThinkingOffer {
39 /// The offer nothing states: no levels, nothing known about the
40 /// switch or the default.
41 #[must_use]
42 pub fn unknown() -> Self {
43 Self {
44 levels: Vec::new(),
45 on: Switch::Unknown,
46 default: None,
47 default_on: None,
48 words: Vec::new(),
49 from: OfferSource::Unknown,
50 source: None,
51 }
52 }
53}
54
55/// Whether one setting is accepted.
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
57#[serde(rename_all = "snake_case")]
58#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
59pub enum Switch {
60 Allowed,
61 Refused,
62 Unknown,
63}
64
65/// The rung of the ladder an offer came from.
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
67#[serde(rename_all = "snake_case")]
68#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
69pub enum OfferSource {
70 /// The person stated the levels when attaching the endpoint.
71 Person,
72 /// The upstream's model listing stated them.
73 Upstream,
74 /// The vendor's documentation, as the preset table records it.
75 Preset,
76 /// Nothing states them.
77 Unknown,
78}
79
80/// The upstream's own word for one level.
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
82#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
83pub struct EffortWord {
84 pub effort: Effort,
85 pub word: String,
86}