Panics · P23 Chat: a branch past its total shows none; parameters peg into range; matches outside a passage stay out

This commit is contained in:
ZacharyZhang-NY committed 2026-10-07 00:29:39 -04:00
1 parent 30fea9ecec
commit 0b8b74b968
4 files changed
+83 -17

No files matched your search

+25 -6
View File
@@ -308,7 +308,7 @@ impl RenderOnce for MessageEditor {
#[derive(IntoElement)]
pub struct BranchNavigator {
id: ElementId,
current: usize,
current: Option<usize>,
total: usize,
on_change: Pick,
}
@@ -320,10 +320,12 @@ impl BranchNavigator {
total: usize,
on_change: impl Fn(usize, &mut Window, &mut App) + 'static,
) -> Self {
assert!(current < total, "version {current} of {total}");
if current >= total {
log::error!("branch navigator: version {current} of {total}; none shown");
}
Self {
id: id.into(),
current,
current: (current < total).then_some(current),
total,
on_change: Rc::new(on_change),
}
@@ -355,7 +357,7 @@ impl RenderOnce for BranchNavigator {
"back",
IconName::ChevronLeft,
"Previous version",
current.checked_sub(1),
current.and_then(|current| current.checked_sub(1)),
))
.child(
tabular(
@@ -363,13 +365,30 @@ impl RenderOnce for BranchNavigator {
.text_size(theme.text_size(TextSize::Xs))
.text_color(theme.colors.fg_muted),
)
.child(format!("{} / {total}", current + 1)),
.child(match current {
Some(current) => format!("{} / {total}", current + 1),
None => format!("– / {total}"),
}),
)
.child(step(
"forward",
IconName::ChevronRight,
"Next version",
(current + 1 < total).then_some(current + 1),
current.and_then(|current| (current + 1 < total).then_some(current + 1)),
))
}
}
#[cfg(test)]
mod tests {
use super::BranchNavigator;
#[test]
fn a_version_past_the_branches_shows_none() {
let navigator =
|current, total| BranchNavigator::new("branch", current, total, |_, _, _| {});
assert_eq!(navigator(1, 3).current, Some(1));
assert_eq!(navigator(3, 3).current, None);
assert_eq!(navigator(0, 0).current, None);
}
}
+31 -4
View File
@@ -58,15 +58,25 @@ impl ParameterPanel {
parameters: impl IntoIterator<Item = Parameter>,
on_change: impl Fn(&SharedString, f64, &mut Window, &mut App) + 'static,
) -> Self {
let parameters: Vec<Parameter> = parameters.into_iter().collect();
for parameter in &parameters {
let mut parameters: Vec<Parameter> = parameters.into_iter().collect();
for parameter in &mut parameters {
assert!(
parameter.min < parameter.max
&& parameter.step > 0.0
&& (parameter.min..=parameter.max).contains(&parameter.value),
&& parameter.value.is_finite(),
"parameter {} has a bad range",
parameter.key
);
if !(parameter.min..=parameter.max).contains(&parameter.value) {
log::error!(
"parameters: {} at {} lies outside {}..={}; pegged",
parameter.key,
parameter.value,
parameter.min,
parameter.max
);
parameter.value = parameter.value.clamp(parameter.min, parameter.max);
}
}
Self {
id: id.into(),
@@ -309,7 +319,7 @@ impl RenderOnce for SystemPromptEditor {
#[cfg(test)]
mod tests {
use super::{Parameter, cost, places};
use super::{Parameter, ParameterPanel, cost, places};
#[test]
fn cost_counts_tokens_at_their_prices() {
@@ -351,4 +361,21 @@ mod tests {
"float noise adds no places"
);
}
#[test]
fn a_value_outside_its_range_pegs() {
let knob = |value| Parameter {
key: "temperature".into(),
label: "Temperature".into(),
value,
min: 0.0,
max: 2.0,
step: 0.1,
hint: None,
};
let panel =
ParameterPanel::new("knobs", [knob(3.5), knob(-1.0), knob(0.7)], |_, _, _, _| {});
let values: Vec<f64> = panel.parameters.iter().map(|knob| knob.value).collect();
assert_eq!(values, [2.0, 0.0, 0.7]);
}
}
+26 -7
View File
@@ -232,13 +232,19 @@ impl DocumentChunkPreview {
text: impl Into<SharedString>,
matched: Vec<Range<usize>>,
) -> Self {
let text = text.into();
assert!(
matched.iter().all(|range| range.end <= text.len()
&& text.is_char_boundary(range.start)
&& text.is_char_boundary(range.end)),
"a match lies outside the passage"
);
let text: SharedString = text.into();
let matched: Vec<Range<usize>> = matched
.into_iter()
.filter(|range| {
let inside = text.get(range.clone()).is_some();
if !inside {
log::error!(
"document chunk: match {range:?} lies outside the passage; left out"
);
}
inside
})
.collect();
assert!(
matched.windows(2).all(|pair| pair[0].end <= pair[1].start),
"matches come in order without overlapping"
@@ -315,3 +321,16 @@ impl RenderOnce for DocumentChunkPreview {
)
}
}
#[cfg(test)]
mod tests {
use super::DocumentChunkPreview;
#[test]
fn a_match_outside_the_passage_is_left_out() {
let ranges = vec![1..2, 2..3, 3..9];
let preview = DocumentChunkPreview::new("guide.md", "p. 2", "éabc", ranges);
let kept = 2..3;
assert_eq!(preview.matched, [kept]);
}
}
+1
View File
@@ -88,3 +88,4 @@ One line per item: what changed, what stayed and why, review rounds.
- P20: a hex selection off the bytes and a stack frame past the stack select none; a flame focus keeps what the profile holds; the timeline's wheel reports only finite, positive ranges from finite factors; a dump's last byte must have an address; flame paints log. Kept: disassembly patterns, `zoomed`'s contract. Review: 3 rounds.
- P21: block editor listeners painted for a block, field, cell or kind since gone log and change nothing, a dropped picture drag leaves undo alone; a visual block press or edit over text the owner replaced is dropped; nested images parse; a version or find hit past its list selects none. Review: 4 rounds.
- P22: annotations and suggestions outside their text log and stay out, picks and decisions keeping the owner's index; `accept` returns `Option`; a gone pick, active thread or followed peer logs; yours at no count comes off; a masked field clamps a stale offset, so remote cursors and selections draw. Kept: a thread's comments, presence max, one list's order, empty marks, constant role and mode tables. Review: 3 rounds.
- P23: a branch version past its total logs and shows a dash, its arrows off; a parameter outside its range logs and pegs; a passage's matches outside it log and stay out. Kept: one-value contracts (progress, scores, shapes, peaks, levels, limits, prices, capacity, format, hour), the composer's trigger rows and stream reveal by construction; `places` skips zero, so `decimals` meets no zero step. Review: 2 rounds.