use super::{Batch, Record};
use serde_json::json;
impl Record {
pub(super) fn stale_completion(&self) -> bool {
self.batch.as_ref().is_some_and(|batch| {
batch.items.iter().any(|item| {
matches!(
item["kind"].as_str(),
Some("text" | "thought" | "tool_call")
) && item["conversation"]
.as_str()
.and_then(|id| self.conversations.get(id))
.is_some_and(|conversation| {
item["seq"]
.as_u64()
.is_some_and(|seq| seq <= conversation.live_seq)
})
})
})
}
pub(super) fn promote_committed(&mut self) -> anyhow::Result<bool> {
let head=self.native.read("documents.get",&json!({"selection":{"branch":"main"},"collection":"_assistant","document_id":format!("{}/head",self.person)}));
let expected = match head {
Ok(answer) => answer["selection"]["version"].clone(),
Err(error) => {
self.failed(&error.code)?;
return Ok(false);
}
};
let original = self
.batch
.as_ref()
.ok_or_else(|| anyhow::anyhow!("record_batch_absent"))?
.items
.clone();
let mut records = Vec::new();
let mut items = Vec::new();
for old in original {
let id = old["conversation"]
.as_str()
.ok_or_else(|| anyhow::anyhow!("record_conversation_invalid"))?
.to_owned();
let seq = self.next_sequence(&id)?;
let old_seq = old["seq"]
.as_u64()
.ok_or_else(|| anyhow::anyhow!("record_sequence_invalid"))?;
let marker = json!({"conversation":id,"seq":old_seq,"durable":true,"kind":"state","state":"record_recovered","superseded_by":seq});
records.push(json!({"document_id":format!("{}/{id}/{old_seq:020}",self.person),"document":marker}));
let mut item = old;
item["seq"] = json!(seq);
item["durable"] = json!(true);
records.push(
json!({"document_id":format!("{}/{id}/{seq:020}",self.person),"document":item}),
);
items.push(item);
}
for (id, conversation) in &self.conversations {
records.push(json!({"document_id":format!("{}/{id}/meta",self.person),"document":conversation.meta}));
}
let arguments = json!({"request_id":super::super::permission::operation()?,"branch":"main","expected":expected,"collection":"_assistant","records":records});
self.batch_bytes = self
.measured(&arguments)?
.checked_add(serde_json::to_vec(&items)?.len())
.ok_or_else(|| anyhow::anyhow!("record_buffer_bound_overflow"))?;
self.batch = Some(Batch {
arguments,
items,
uncertain: false,
attempted: false,
});
self.check_bound()?;
self.commit()
}
}