pub struct Excluded {
pub uri: String,
pub kind: Option<String>,
pub tier: Tier,
pub reason: ExclusionReason,
pub detail: String,
pub cost_tokens: u64,
pub relevance: f64,
}Expand description
One thing the compiler reached and did not give. Excluded is not the same as absent: an under-filled context is debugged from this list, not by guessing.
cost_tokens is why this type exists in the shape it does. A budget that reported only
that it dropped things would leave a caller guessing at a new ceiling; one that reports
what each omission would have cost turns “raise the budget” into arithmetic. detail
carries the same in words, so the row is legible without the reader doing that
arithmetic themselves.
The ordering puts the tier first as an explicit rank, because the tier is the precedence the budget spent in; inside a tier a reader is looking for a reason, and the identifier ends the key so the list is total and the same tree always prints it the same way.
use majordomus_cli::devcontext::{Excluded, ExclusionReason, Tier};
use majordomus_cli::order::canonical;
use serde_json::json;
let row = |uri: &str, tier: &str, reason: &str, cost: u64| -> Excluded {
serde_json::from_value(json!({
"uri": uri, "tier": tier, "reason": reason,
"detail": "as measured", "cost_tokens": cost, "relevance": 0.4,
})).unwrap()
};
let mut excluded = vec![
row("majordomus://knowledge/b", "history", "budget", 900),
row("majordomus://adr/0001", "decision", "superseded", 300),
row("majordomus://knowledge/a", "history", "budget", 1_200),
];
canonical(&mut excluded);
// the tier ranks first, so the decision tier precedes history whatever the reason says
assert_eq!(excluded[0].tier, Tier::Decision);
assert_eq!(excluded[0].reason, ExclusionReason::Superseded);
// then the reason, then the identifier — which makes the order total
let rest: Vec<&str> = excluded[1..].iter().map(|e| e.uri.as_str()).collect();
assert_eq!(rest, ["majordomus://knowledge/a", "majordomus://knowledge/b"]);
// and the row a caller acts on says what it would have cost to keep
let biggest = excluded.iter().max_by_key(|e| e.cost_tokens).unwrap();
assert_eq!(biggest.cost_tokens, 1_200);Fields§
§uri: StringThe canonical identifier, or the name the layer used when nothing resolves.
kind: Option<String>Its kind, when it resolved to something.
tier: TierThe tier it would have been spent from.
reason: ExclusionReasonWhy it is not in the answer.
detail: StringThe same, in words.
cost_tokens: u64What it would have cost, so that a reader can decide whether to raise the budget.
relevance: f64What its relevance was.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Excluded
impl<'de> Deserialize<'de> for Excluded
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 JsonSchema for Excluded
impl JsonSchema for Excluded
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreSource§impl Ordered for Excluded
The tier is the precedence the budget spends in, so it is the explicit rank; inside a
tier a reader looks for a reason, and the identifier ends the key so the list is total.
impl Ordered for Excluded
The tier is the precedence the budget spends in, so it is the explicit rank; inside a tier a reader looks for a reason, and the identifier ends the key so the list is total.