bxcore: a turn's speaker, SessionUpdated's turn, the session-state messages

Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
2026-09-28 10:27:28 -07:00
co-authored by ornith-1.5-35b-a3b
parent 027146f359
commit c798714af1
31 changed files with 238 additions and 13 deletions
+31
View File
@@ -46,16 +46,46 @@ fn usage() -> Usage {
}
}
/// A turn without a speaker has the bytes it had before M5c, and a frame without `speaker` reads
/// as `None`: a turn with no speaker is never synced (M5c spec, section 4).
#[test]
fn turn() {
let body = Turn {
session: SessionId::new("chat-1789700000-42").unwrap(),
content: "What time is it?".to_string(),
resume: false,
speaker: None,
};
check("turn.json", env(3, true, Message::Turn(body)));
}
/// The speaker is written last, when there is one (M5c spec, section 11).
#[test]
fn turn_with_a_speaker() {
let body = Turn {
session: SessionId::new("mm-r0000000000000000000000001").unwrap(),
content: "What time is it?".to_string(),
resume: true,
speaker: Some("kyle".to_string()),
};
check("turn_speaker.json", env(3, true, Message::Turn(body)));
}
/// `bxcore` does not check a speaker's name: `memoryd` checks it against Honcho's pattern (M5c
/// spec, section 3). A Mattermost username with a `.` is carried as it is.
#[test]
fn a_speaker_is_carried_as_it_is() {
let body = Turn {
session: SessionId::new("mm-r0000000000000000000000001").unwrap(),
content: "hi".to_string(),
resume: false,
speaker: Some("first.last".to_string()),
};
let text = serde_json::to_string(&body).unwrap();
assert!(text.ends_with(r#","speaker":"first.last"}"#), "{text}");
assert_eq!(serde_json::from_str::<Turn>(&text).unwrap(), body);
}
#[test]
fn turn_events() {
check(
@@ -262,6 +292,7 @@ fn usage_records() {
LogRecord::User {
time: Timestamp::parse("2026-09-18T08:05:01.000Z").unwrap(),
content: "What time is it?".to_string(),
speaker: None,
},
LogRecord::Assistant {
time: Timestamp::parse("2026-09-18T08:05:03.000Z").unwrap(),