Support long-running agent turns

This commit is contained in:
Georg Bauer
2026-07-26 11:07:28 +02:00
parent 2a14b93335
commit 3c75b8f6c1
14 changed files with 432 additions and 90 deletions

View File

@@ -76,6 +76,7 @@ pub(crate) struct App {
project_name_input: String,
model_download: ModelDownload,
pub(super) composer: String,
pub(super) queued_inputs: VecDeque<String>,
pub(super) conversation: Vec<ChatMessage>,
pub(super) generating: bool,
pub(super) context_used: u32,
@@ -107,6 +108,8 @@ pub(crate) struct App {
_endpoint: Option<crate::server::ServerHandle>,
error: Option<String>,
pub(super) activity: Option<String>,
stop_requested: bool,
system_prompt_seen_at: u32,
#[cfg(target_os = "macos")]
skip_compaction_once: bool,
}
@@ -285,6 +288,7 @@ impl App {
project_name_input: String::new(),
model_download: ModelDownload::Idle,
composer: String::new(),
queued_inputs: VecDeque::new(),
conversation: Vec::new(),
generating: false,
context_used: 0,
@@ -324,6 +328,8 @@ impl App {
}
},
activity: None,
stop_requested: false,
system_prompt_seen_at: 0,
#[cfg(target_os = "macos")]
skip_compaction_once: false,
}
@@ -379,6 +385,7 @@ impl App {
project_name_input: String::new(),
model_download: ModelDownload::Idle,
composer: String::new(),
queued_inputs: VecDeque::new(),
conversation: Vec::new(),
generating: false,
context_used: 0,
@@ -412,6 +419,8 @@ impl App {
None => error,
}),
activity: None,
stop_requested: false,
system_prompt_seen_at: 0,
#[cfg(target_os = "macos")]
skip_compaction_once: false,
}
@@ -767,6 +776,8 @@ impl App {
return scroll_chat_to_end();
}
Message::StopGeneration => {
self.stop_requested = true;
self.activity = Some("Stopping…".into());
#[cfg(target_os = "macos")]
if let Some(active) = &self.active_generation {
active.cancel.store(true, Ordering::Relaxed);
@@ -863,6 +874,8 @@ impl App {
self.selected_session = None;
self.conversation.clear();
self.composer.clear();
self.queued_inputs.clear();
self.system_prompt_seen_at = 0;
self.context_used = 0;
self.tokens_per_second = None;
}
@@ -1015,6 +1028,8 @@ impl App {
self.composer.clear();
self.remember_project(project_id);
self.selected_session = Some(session_id);
self.system_prompt_seen_at = 0;
self.queued_inputs.clear();
let (used, limit, tokens_per_second) = saved_context.unwrap_or_default();
self.context_used = used.max(0) as u32;
self.context_limit = if limit > 0 {
@@ -1056,6 +1071,8 @@ impl App {
self.selected_session = None;
self.conversation.clear();
self.composer.clear();
self.queued_inputs.clear();
self.system_prompt_seen_at = 0;
self.context_used = 0;
self.tokens_per_second = None;
}
@@ -1599,6 +1616,7 @@ mod tests {
id: 1,
user: false,
tool: false,
system: false,
reasoning: Some(String::new()),
reasoning_complete: false,
reasoning_open: true,