Use agent reply text in turn notifications (#3756)
Instead of "Agent turn complete", turn-complete notifications now include the first handful of chars from the agent's final message.
This commit is contained in:
@@ -255,7 +255,7 @@ impl ChatWidget {
|
||||
self.request_redraw();
|
||||
}
|
||||
|
||||
fn on_task_complete(&mut self) {
|
||||
fn on_task_complete(&mut self, last_agent_message: Option<String>) {
|
||||
// If a stream is currently active, finalize only that stream to flush any tail
|
||||
// without emitting stray headers for other streams.
|
||||
if self.stream.is_write_cycle_active() {
|
||||
@@ -270,7 +270,9 @@ impl ChatWidget {
|
||||
// If there is a queued user message, send exactly one now to begin the next turn.
|
||||
self.maybe_send_next_queued_input();
|
||||
// Emit a notification when the turn completes (suppressed if focused).
|
||||
self.notify(Notification::AgentTurnComplete);
|
||||
self.notify(Notification::AgentTurnComplete {
|
||||
response: last_agent_message.unwrap_or_default(),
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn set_token_info(&mut self, info: Option<TokenUsageInfo>) {
|
||||
@@ -1082,7 +1084,9 @@ impl ChatWidget {
|
||||
}
|
||||
EventMsg::AgentReasoningSectionBreak(_) => self.on_reasoning_section_break(),
|
||||
EventMsg::TaskStarted(_) => self.on_task_started(),
|
||||
EventMsg::TaskComplete(TaskCompleteEvent { .. }) => self.on_task_complete(),
|
||||
EventMsg::TaskComplete(TaskCompleteEvent { last_agent_message }) => {
|
||||
self.on_task_complete(last_agent_message)
|
||||
}
|
||||
EventMsg::TokenCount(ev) => self.set_token_info(ev.info),
|
||||
EventMsg::Error(ErrorEvent { message }) => self.on_error(message),
|
||||
EventMsg::TurnAborted(ev) => match ev.reason {
|
||||
@@ -1479,7 +1483,7 @@ impl WidgetRef for &ChatWidget {
|
||||
}
|
||||
|
||||
enum Notification {
|
||||
AgentTurnComplete,
|
||||
AgentTurnComplete { response: String },
|
||||
ExecApprovalRequested { command: String },
|
||||
EditApprovalRequested { cwd: PathBuf, changes: Vec<PathBuf> },
|
||||
}
|
||||
@@ -1487,7 +1491,10 @@ enum Notification {
|
||||
impl Notification {
|
||||
fn display(&self) -> String {
|
||||
match self {
|
||||
Notification::AgentTurnComplete => "Agent turn complete".to_string(),
|
||||
Notification::AgentTurnComplete { response } => {
|
||||
Notification::agent_turn_preview(response)
|
||||
.unwrap_or_else(|| "Agent turn complete".to_string())
|
||||
}
|
||||
Notification::ExecApprovalRequested { command } => {
|
||||
format!("Approval requested: {}", truncate_text(command, 30))
|
||||
}
|
||||
@@ -1507,7 +1514,7 @@ impl Notification {
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
match self {
|
||||
Notification::AgentTurnComplete => "agent-turn-complete",
|
||||
Notification::AgentTurnComplete { .. } => "agent-turn-complete",
|
||||
Notification::ExecApprovalRequested { .. }
|
||||
| Notification::EditApprovalRequested { .. } => "approval-requested",
|
||||
}
|
||||
@@ -1519,8 +1526,26 @@ impl Notification {
|
||||
Notifications::Custom(allowed) => allowed.iter().any(|a| a == self.type_name()),
|
||||
}
|
||||
}
|
||||
|
||||
fn agent_turn_preview(response: &str) -> Option<String> {
|
||||
let mut normalized = String::new();
|
||||
for part in response.split_whitespace() {
|
||||
if !normalized.is_empty() {
|
||||
normalized.push(' ');
|
||||
}
|
||||
normalized.push_str(part);
|
||||
}
|
||||
let trimmed = normalized.trim();
|
||||
if trimmed.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(truncate_text(trimmed, AGENT_NOTIFICATION_PREVIEW_GRAPHEMES))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const AGENT_NOTIFICATION_PREVIEW_GRAPHEMES: usize = 200;
|
||||
|
||||
const EXAMPLE_PROMPTS: [&str; 6] = [
|
||||
"Explain this codebase",
|
||||
"Summarize recent commits",
|
||||
|
||||
Reference in New Issue
Block a user