use crate::ui::slash::CompactionRequest;
pub(crate) enum CompactionThen {
Nothing,
SendPrompt {
run_prompt: String,
record_text: String,
},
RetryAfterOverflow { prompt: String, made_progress: bool },
}
#[derive(Debug, PartialEq, Eq)]
pub(crate) enum OverflowRecovery {
Continue,
Resend,
GiveUp,
}
pub(crate) fn overflow_recovery(compacted: bool, made_progress: bool) -> OverflowRecovery {
match (compacted, made_progress) {
(true, true) => OverflowRecovery::Continue,
(true, false) => OverflowRecovery::Resend,
(false, _) => OverflowRecovery::GiveUp,
}
}
#[cfg(test)]
mod recovery_tests {
use super::{OverflowRecovery, overflow_recovery};
#[test]
fn made_progress_resumes_as_continuation() {
assert_eq!(overflow_recovery(true, true), OverflowRecovery::Continue);
}
#[test]
fn no_progress_resends_prompt() {
assert_eq!(overflow_recovery(true, false), OverflowRecovery::Resend);
}
#[test]
fn uncompacted_gives_up_regardless_of_progress() {
assert_eq!(overflow_recovery(false, true), OverflowRecovery::GiveUp);
assert_eq!(overflow_recovery(false, false), OverflowRecovery::GiveUp);
}
}
pub(crate) enum CompactionPhaseEvent {
Done { summary: String },
Failed { error: String },
}
pub(crate) struct CompactionPhaseHandle {
pub rx: tokio::sync::mpsc::Receiver<CompactionPhaseEvent>,
pub task: tokio::task::JoinHandle<()>,
pub cut_idx: usize,
pub tokens_before: u64,
pub then: CompactionThen,
}
pub(crate) fn spawn_local(
summary: String,
cut_idx: usize,
tokens_before: u64,
then: CompactionThen,
) -> CompactionPhaseHandle {
let (tx, rx) = tokio::sync::mpsc::channel::<CompactionPhaseEvent>(1);
let task = tokio::spawn(async move {
let _ = tx.send(CompactionPhaseEvent::Done { summary }).await;
});
CompactionPhaseHandle {
rx,
task,
cut_idx,
tokens_before,
then,
}
}
pub(crate) fn spawn(req: CompactionRequest, then: CompactionThen) -> CompactionPhaseHandle {
let CompactionRequest {
model,
prompt,
cut_idx,
tokens_before,
} = req;
let (tx, rx) = tokio::sync::mpsc::channel::<CompactionPhaseEvent>(1);
let task = tokio::spawn(async move {
let event = match crate::provider::run_compaction(model, prompt).await {
Ok(summary) => CompactionPhaseEvent::Done { summary },
Err(e) => CompactionPhaseEvent::Failed {
error: e.to_string(),
},
};
let _ = tx.send(event).await;
});
CompactionPhaseHandle {
rx,
task,
cut_idx,
tokens_before,
then,
}
}