Skip to main content

gglib_core/request_pipeline/
explain.rs

1//! Resolving a model's *stored* sampling configuration, with provenance.
2//!
3//! The live pipeline answers "what did this request end up sampling with?".
4//! This answers the question the explain surfaces ask instead — "what would
5//! this model sample with, and which rung supplied each value?" — with no
6//! request in hand, so the top rung is empty by construction.
7//!
8//! # Why it is shared rather than written twice
9//!
10//! `gglib model explain` and the GUI's sampling panel had a copy each, and
11//! they had to agree: the same ladder, followed by the same stage-5b effort
12//! gate applied to the resolution rather than to a request. Two copies of a
13//! rule can only ever drift into two accounts of one resolution, and the whole
14//! value of an explain surface is that it describes the resolution that
15//! actually runs. So the rule lives here once, and the callers keep only what
16//! genuinely differs between them — one prints, the other builds a DTO.
17//!
18//! It sits beside [`effort_gate`](super::effort_gate) because
19//! [`suppress_stored_effort`] does, and applying that gate offline is half of
20//! what this function is.
21
22use crate::domain::{
23    FieldSources, InferenceConfig, InferenceProfile, ModelSamplingContext, TemplateCaps,
24};
25
26use super::effort_gate::{SuppressedEffort, suppress_stored_effort};
27
28/// Resolve stored sampling for one model, and report where each value came
29/// from and whether the template gate silently dropped an effort level.
30///
31/// The request rung is deliberately empty: this explains configuration, not a
32/// call, so there are no per-request parameters to occupy the top of the
33/// ladder.
34#[must_use]
35pub fn explain_stored(
36    profile: Option<&InferenceProfile>,
37    model_defaults: Option<&InferenceConfig>,
38    global_defaults: Option<&InferenceConfig>,
39    model_ctx: ModelSamplingContext,
40    caps: &Option<TemplateCaps>,
41) -> (InferenceConfig, FieldSources, Option<SuppressedEffort>) {
42    let (mut resolved, mut sources) = InferenceConfig::default().resolve_with_profile_explained(
43        profile.map(|selected| &selected.config),
44        model_defaults,
45        global_defaults,
46        model_ctx,
47    );
48    let suppressed = suppress_stored_effort(&mut resolved, &mut sources, caps);
49    (resolved, sources, suppressed)
50}