OpenRouter Support, Insight Chat and User injection #56
@@ -1071,8 +1071,13 @@ fn is_rendered(m: &ChatMessage) -> bool {
|
|||||||
/// Given a rendered index to start discarding from, find the raw index at
|
/// Given a rendered index to start discarding from, find the raw index at
|
||||||
/// which to truncate. The cut position is the raw length after all prior
|
/// which to truncate. The cut position is the raw length after all prior
|
||||||
/// rendered messages — which also strips any tool-call scaffolding that
|
/// rendered messages — which also strips any tool-call scaffolding that
|
||||||
/// immediately precedes the discarded rendered message. Returns `None` if
|
/// immediately precedes the discarded rendered message.
|
||||||
/// `discard_from_rendered_index` is past the end of the rendered view.
|
///
|
||||||
|
/// Discarding *at* the end (`discard == rendered_count`) is a no-op success:
|
||||||
|
/// returns `Some(messages.len())`. The mobile client hits this when
|
||||||
|
/// regenerating after a failed turn — its optimistic user bubble lives at
|
||||||
|
/// the index just past the server's persisted history. Strictly past the end
|
||||||
|
/// (`discard > rendered_count`) returns `None`.
|
||||||
pub(crate) fn find_raw_cut(
|
pub(crate) fn find_raw_cut(
|
||||||
messages: &[ChatMessage],
|
messages: &[ChatMessage],
|
||||||
discard_from_rendered_index: usize,
|
discard_from_rendered_index: usize,
|
||||||
@@ -1089,10 +1094,8 @@ pub(crate) fn find_raw_cut(
|
|||||||
rendered_count += 1;
|
rendered_count += 1;
|
||||||
last_kept_raw_end = i + 1;
|
last_kept_raw_end = i + 1;
|
||||||
}
|
}
|
||||||
if rendered_count == discard_from_rendered_index {
|
if discard_from_rendered_index == rendered_count {
|
||||||
// Discarding past the last rendered message is a no-op, but we
|
return Some(messages.len());
|
||||||
// surface it as "nothing to cut" rather than silent success.
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -1361,4 +1364,18 @@ mod tests {
|
|||||||
let msgs = vec![ChatMessage::user("q1"), assistant_text("a1")];
|
let msgs = vec![ChatMessage::user("q1"), assistant_text("a1")];
|
||||||
assert!(find_raw_cut(&msgs, 5).is_none());
|
assert!(find_raw_cut(&msgs, 5).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rewind_at_end_is_noop_success() {
|
||||||
|
// Mobile client retries after a failed turn that never persisted —
|
||||||
|
// its optimistic user bubble's index equals the server's rendered
|
||||||
|
// count. Should resolve to "no cut" rather than an out-of-range error.
|
||||||
|
let msgs = vec![
|
||||||
|
ChatMessage::system("s"),
|
||||||
|
ChatMessage::user("q1"),
|
||||||
|
assistant_text("a1"),
|
||||||
|
];
|
||||||
|
let cut = find_raw_cut(&msgs, 2).expect("boundary cut should succeed");
|
||||||
|
assert_eq!(cut, msgs.len());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user