Self run: a refused reply holds back the replies behind it, so a long result reaches the mind in order
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8073a7c3bc
commit
59aca09c62
2 changed files with 19 additions and 5 deletions
|
|
@ -795,17 +795,19 @@ impl<'a> SelfInbox<'a> {
|
|||
Self { mind, start, plan: render_plan(plan_quota, now_ms), told, waiting: Vec::new(), heard, run: run.clone(), carried, echoed: Vec::new(), serving, last_answers, flush_written: false, flushing: false, replies: 0, unadmitted: Vec::new() }
|
||||
}
|
||||
|
||||
/// Admits each reply the mind has not taken, in order; one try each. A refusal or an unreachable mind keeps the reply and never ends the session.
|
||||
/// Admits each reply the mind has not taken, in order; one try each. A refusal or an unreachable mind keeps that reply and every one behind it
|
||||
/// (the admission ordinal is the order the Persona hears them in, so none may overtake a refused one) and never ends the session.
|
||||
fn admit_unadmitted(&mut self) {
|
||||
let label = self.run.id.0.rsplit(':').next().unwrap_or(&self.run.id.0).to_string();
|
||||
let mut kept = Vec::new();
|
||||
for reply in std::mem::take(&mut self.unadmitted) {
|
||||
let mut queue = std::mem::take(&mut self.unadmitted).into_iter();
|
||||
for reply in queue.by_ref() {
|
||||
let taken = matches!(self.mind.admit(AGENT, &label, vec![PipelineDocument::Reply(reply.clone())]), Ok(PipelineAdmissionOutcome::Committed { .. } | PipelineAdmissionOutcome::AlreadyAdmitted { .. }));
|
||||
if !taken {
|
||||
kept.push(reply);
|
||||
self.unadmitted.push(reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.unadmitted = kept;
|
||||
self.unadmitted.extend(queue);
|
||||
}
|
||||
|
||||
/// One result of the main thread: with words, one reply answering the briefs the CLI has taken since the last reply (the first 64, in tell
|
||||
|
|
|
|||
|
|
@ -106,3 +106,15 @@ fn a_reply_the_mind_did_not_take_is_tried_once_more_when_the_run_ends() {
|
|||
assert!(ran.outcome.is_ok());
|
||||
assert_eq!(text_of(&mind, 1), "last words");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_refused_piece_of_a_long_result_holds_back_the_pieces_behind_it() {
|
||||
let mind = live_mind();
|
||||
let seen = Seen::of(&mind);
|
||||
seen.fail_admits.set(1); // the first piece is refused
|
||||
let long = "w".repeat(REPLY_TEXT_LIMIT * 2 + 1);
|
||||
let ran = carry_with(&seen, vec![Out(echo()), Out(at("m1", 10)), Out(saying(&long))], Some(0), false);
|
||||
assert!(ran.outcome.is_ok());
|
||||
let ordinals: Vec<u64> = (1..=3).map(|n| mind.view(K::Reply, &format!("{INSTANCE}:reply:selfrun-a-r{n}")).unwrap_or_else(|| panic!("piece {n} lost")).admission.ordinal).collect();
|
||||
assert!(ordinals.windows(2).all(|w| w[0] < w[1]), "the pieces reached the mind out of order: {ordinals:?}");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue