fix: harden uploaded attachment retention and replay

This commit is contained in:
2026-09-03 05:50:47 +09:00
parent 6c5b8315a3
commit 8a70f3cb26
14 changed files with 321 additions and 29 deletions
+5
View File
@@ -88,6 +88,11 @@ impl WorkerHandle {
.delete_uploaded_file(self.session_id, artifact_id)
}
pub fn delete_uncommitted_uploaded_files(&self) -> Result<u64, session_store::StoreError> {
self.artifact_store
.delete_uncommitted_uploaded_files(self.session_id)
}
pub fn subscribe(&self) -> broadcast::Receiver<Event> {
self.working_event_tx.subscribe()
}
+1 -1
View File
@@ -340,7 +340,7 @@ mod tests {
owner,
"image.png",
"image/png",
&[0xff, 0xd8, 0x00],
b"\x89PNG\r\n\x1a\nbody",
session_store::UploadedFileLimits::default(),
)
.unwrap();
+22 -6
View File
@@ -3331,7 +3331,13 @@ impl<C: LlmClient + 'static, St: Store> Worker<C, St> {
}),
compacted_from: None,
};
let mut initial_entries = vec![entry.clone()];
let mut initial_entries = vec![
entry.clone(),
LogEntry::InputSegmentsCheckpoint {
ts: segment_log::now_millis(),
user_segments: self.user_segments.clone(),
},
];
if let Some(checkpoint) =
active_run_checkpoint_entry(w.active_run_turn_count(), w.turn_count())
{
@@ -4295,6 +4301,13 @@ impl<C: LlmClient + 'static, St: Store> Worker<C, St> {
})
.collect::<Vec<_>>();
let retained_user_segments = self
.user_segments
.iter()
.skip(self.user_segments.len().saturating_sub(retained_user_msgs))
.cloned()
.collect::<Vec<_>>();
// Build the SegmentStart entry for the new compacted segment.
// Inherits the source Segment's session_id so the compacted
// lineage stays grouped under the same Session. Atomically
@@ -4320,7 +4333,13 @@ impl<C: LlmClient + 'static, St: Store> Worker<C, St> {
at_turn_index: source_turn_count,
}),
};
let mut initial_entries = vec![entry.clone()];
let mut initial_entries = vec![
entry.clone(),
LogEntry::InputSegmentsCheckpoint {
ts: segment_log::now_millis(),
user_segments: retained_user_segments.clone(),
},
];
if let Some(checkpoint) =
active_run_checkpoint_entry(w.active_run_turn_count(), source_turn_count)
{
@@ -4372,10 +4391,7 @@ impl<C: LlmClient + 'static, St: Store> Worker<C, St> {
// segments; only the user_messages surviving in retained_items
// keep them. They are always the trailing K entries of
// `self.user_segments` because submissions are appended in order.
let drop_n = self.user_segments.len().saturating_sub(retained_user_msgs);
if drop_n > 0 {
self.user_segments.drain(..drop_n);
}
self.user_segments = retained_user_segments;
self.session.replace_history(compacted_history_entries);
// Compaction-introduced system messages are part of the new