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:
@@ -38,7 +38,8 @@ pub use ids::{CallId, Epoch, Hash32, SessionId, Timestamp, ValueError};
|
||||
pub use log::{LogRecord, ToolCall, Usage};
|
||||
pub use memory::{
|
||||
ConsolidateEntry, EntryAction, MemoryAdmin, MemoryAdminReply, MemoryArgs, MemoryBlockReply,
|
||||
MemoryCall, MemoryCommand, MemoryFile, RecallArgs, Reindexed, SessionUpdated,
|
||||
MemoryCall, MemoryCommand, MemoryFile, RecallArgs, Reindexed, SessionState, SessionStateReply,
|
||||
SessionUpdated,
|
||||
};
|
||||
pub use wire::{
|
||||
ApprovalList, Approve, ApproveResult, DenyReason, Empty, Envelope, ErrorCode, GrantProblem,
|
||||
|
||||
@@ -37,6 +37,10 @@ pub enum LogRecord {
|
||||
User {
|
||||
time: Timestamp,
|
||||
content: String,
|
||||
/// The turn's speaker (M5c spec, section 11). Written only when present, so a log written
|
||||
/// before M5c reads as it is, and a turn without a speaker is logged as before.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
speaker: Option<String>,
|
||||
},
|
||||
Assistant {
|
||||
time: Timestamp,
|
||||
|
||||
@@ -228,11 +228,30 @@ pub struct MemoryBlockReply {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// `loopd` → `memoryd`: this session's log has new records.
|
||||
/// `loopd` → `memoryd`: this session's log has new records, those of a turn that has ended.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct SessionUpdated {
|
||||
pub session: SessionId,
|
||||
/// The ended turn's number in the session (M5c spec, section 5). It has no default: a frame
|
||||
/// without it is refused, never read as turn 0.
|
||||
pub turn: u64,
|
||||
}
|
||||
|
||||
/// `memoryd` → `brokerd`, on `state.sock`: the session's state now (M5c spec, section 7).
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct SessionState {
|
||||
pub session: SessionId,
|
||||
}
|
||||
|
||||
/// `brokerd` → `memoryd`: the session's class, and whether it has read untrusted content. Neither
|
||||
/// field has a default: a reply without one is refused, never read as a clean session.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct SessionStateReply {
|
||||
pub class: DataClass,
|
||||
pub untrusted: bool,
|
||||
}
|
||||
|
||||
/// `brokerd` → `memoryd`: a decided `recall` or `memory` call, with the session's state when it
|
||||
|
||||
@@ -2,7 +2,8 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::gateway::{ApprovalOutcome, ApprovalPosted, ApprovalReply, ApprovalRequest};
|
||||
use crate::memory::{
|
||||
MemoryAdmin, MemoryAdminReply, MemoryBlockReply, MemoryCall, Reindexed, SessionUpdated,
|
||||
MemoryAdmin, MemoryAdminReply, MemoryBlockReply, MemoryCall, Reindexed, SessionState,
|
||||
SessionStateReply, SessionUpdated,
|
||||
};
|
||||
use crate::{CallId, DataClass, DecisionRecord, SessionId, Timestamp, Usage};
|
||||
|
||||
@@ -51,6 +52,8 @@ pub enum Message {
|
||||
Reindexed(Reindexed),
|
||||
MemoryAdmin(MemoryAdmin),
|
||||
MemoryAdminReply(MemoryAdminReply),
|
||||
SessionState(SessionState),
|
||||
SessionStateReply(SessionStateReply),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -126,13 +129,18 @@ pub enum DenyReason {
|
||||
StateUnreadable,
|
||||
}
|
||||
|
||||
// JSON: {"kind":"turn","body":{"session":"…","content":"…","resume":false}}
|
||||
// JSON: {"kind":"turn","body":{"session":"…","content":"…","resume":false,"speaker":"kyle"}}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Turn {
|
||||
pub session: SessionId,
|
||||
pub content: String,
|
||||
pub resume: bool,
|
||||
/// Who spoke the turn, when one person did (M5c spec, section 11). Written only when present,
|
||||
/// and a frame without it reads as `None`, the safe side: a turn without a speaker is never
|
||||
/// synced to Honcho.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub speaker: Option<String>,
|
||||
}
|
||||
|
||||
// JSON: {"event":"content","text":"…"} — the tag sits beside the fields, snake_case
|
||||
|
||||
Reference in New Issue
Block a user