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

@@ -71,6 +71,9 @@ impl App {
);
}
for (index, message) in self.conversation.iter().enumerate() {
if message.system {
continue;
}
let label = if message.user {
"You"
} else if message.tool {
@@ -165,13 +168,20 @@ impl App {
.width(Length::Fill)
.into()
} else {
text_input("Ask DS4Server anything…", &self.composer)
.id(composer_id())
.on_input(Message::ComposerChanged)
.on_submit(Message::SubmitPrompt)
.padding(12)
.size(14)
.into()
text_input(
if self.generating {
"Add guidance to the queue…"
} else {
"Ask DS4Server anything…"
},
&self.composer,
)
.id(composer_id())
.on_input(Message::ComposerChanged)
.on_submit(Message::SubmitPrompt)
.padding(12)
.size(14)
.into()
};
let action = if self.generating {
action_button(text("Stop").size(12)).on_press(Message::StopGeneration)
@@ -187,50 +197,60 @@ impl App {
} else {
self.context_used.min(self.context_limit) as f32 / self.context_limit as f32
};
let mut composer_content = column![composer].spacing(6);
for queued in &self.queued_inputs {
let mut queued = queued.replace('\n', " ");
if queued.chars().count() > 120 {
queued = queued.chars().take(119).collect::<String>() + "";
}
composer_content = composer_content.push(
text(format!("Queued · {queued}"))
.size(12)
.color(muted_text()),
);
}
composer_content =
composer_content.push(
row![
icon(ICON_PAPERCLIP, 19),
tooltip(
context_pie(context_fraction, 19),
container(
text(format!(
"{} / {} tokens ({:.0}%)",
self.context_used,
self.context_limit,
context_fraction * 100.0
))
.size(12)
)
.padding(10)
.style(preference_group_style),
tooltip::Position::Top,
)
.gap(6),
text(self.tokens_per_second.map_or_else(
|| "— tok/s".to_owned(),
|speed| format!("{speed:.1} tok/s")
))
.size(11)
.color(muted_text()),
Space::with_width(Length::Fill),
icon(ICON_MODEL, 16),
text(self.config.model.to_string()).size(12),
action,
]
.spacing(6)
.align_y(Alignment::Center),
);
let conversation = column![
scrollable(messages)
.id(chat_scroll_id())
.height(Length::Fill),
container(
column![
composer,
row![
icon(ICON_PAPERCLIP, 19),
tooltip(
context_pie(context_fraction, 19),
container(
text(format!(
"{} / {} tokens ({:.0}%)",
self.context_used,
self.context_limit,
context_fraction * 100.0
))
.size(12)
)
.padding(10)
.style(preference_group_style),
tooltip::Position::Top,
)
.gap(6),
text(self.tokens_per_second.map_or_else(
|| "— tok/s".to_owned(),
|speed| format!("{speed:.1} tok/s")
))
.size(11)
.color(muted_text()),
Space::with_width(Length::Fill),
icon(ICON_MODEL, 16),
text(self.config.model.to_string()).size(12),
action,
]
.spacing(6)
.align_y(Alignment::Center),
]
.spacing(8),
)
.padding(16)
.width(Length::Fill)
.style(overview_style),
container(composer_content,)
.padding(16)
.width(Length::Fill)
.style(overview_style),
]
.height(Length::Fill)
.spacing(8);