chat: route_entry returns Vec for multi-tool-call entries
An assistant entry can have text + multiple tool calls. route_entry now returns Vec<(PaneTarget, String, Marker)> — tool calls go to tools pane, text goes to conversation, all from the same entry. Pop phase iterates the vec in reverse to pop correct number of pane items per entry. Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
222b2cbeb2
commit
65d23692fb
1 changed files with 32 additions and 24 deletions
|
|
@ -66,39 +66,50 @@ impl InteractScreen {
|
|||
}
|
||||
}
|
||||
|
||||
/// Route an agent entry to the appropriate pane.
|
||||
/// Returns None for entries that shouldn't be displayed (memory, system).
|
||||
fn route_entry(&mut self, entry: &crate::agent::context::ConversationEntry) -> Option<&mut PaneState> {
|
||||
/// Route an agent entry to pane items.
|
||||
/// Returns empty vec for entries that shouldn't be displayed.
|
||||
fn route_entry(entry: &crate::agent::context::ConversationEntry) -> Vec<(PaneTarget, String, Marker)> {
|
||||
use crate::agent::api::types::Role;
|
||||
use crate::agent::context::ConversationEntry;
|
||||
|
||||
if let ConversationEntry::Memory { .. } = entry {
|
||||
return None;
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let msg = entry.message();
|
||||
let text = msg.content_text().to_string();
|
||||
|
||||
match msg.role {
|
||||
if text.is_empty() { return None; }
|
||||
if text.starts_with("<system-reminder>") { return None; }
|
||||
if text.starts_with("<system-reminder>") {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
Role::User => Some(&mut self.conversation),
|
||||
match msg.role {
|
||||
Role::User => {
|
||||
if text.is_empty() { return vec![]; }
|
||||
vec![(PaneTarget::Conversation, text, Marker::User)]
|
||||
}
|
||||
Role::Assistant => {
|
||||
let mut items = Vec::new();
|
||||
// Tool calls → tools pane
|
||||
if let Some(ref calls) = msg.tool_calls {
|
||||
for call in calls {
|
||||
let line = format!("[{}] {}",
|
||||
call.function.name,
|
||||
call.function.arguments.chars().take(80).collect::<String>());
|
||||
// TODO: return multiple targets — for now just return first tool call
|
||||
return Some((PaneTarget::Tools, line, Marker::None));
|
||||
items.push((PaneTarget::Tools, line, Marker::None));
|
||||
}
|
||||
}
|
||||
Some((PaneTarget::ConversationAssistant, text, Marker::Assistant))
|
||||
// Text content → conversation
|
||||
if !text.is_empty() {
|
||||
items.push((PaneTarget::ConversationAssistant, text, Marker::Assistant));
|
||||
}
|
||||
Role::Tool => Some(&mut self.tools),
|
||||
Role::System => None,
|
||||
items
|
||||
}
|
||||
Role::Tool => {
|
||||
if text.is_empty() { return vec![]; }
|
||||
vec![(PaneTarget::ToolResult, text, Marker::None)]
|
||||
}
|
||||
Role::System => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +133,7 @@ impl InteractScreen {
|
|||
break;
|
||||
}
|
||||
let popped = self.last_entries.pop().unwrap();
|
||||
if let Some((target, _, _)) = Self::route_entry(&popped) {
|
||||
for (target, _, _) in Self::route_entry(&popped) {
|
||||
match target {
|
||||
PaneTarget::Conversation | PaneTarget::ConversationAssistant
|
||||
=> self.conversation.pop_line(),
|
||||
|
|
@ -136,17 +147,14 @@ impl InteractScreen {
|
|||
// Phase 2: push new entries
|
||||
let start = self.last_entries.len();
|
||||
for entry in entries.iter().skip(start) {
|
||||
if let Some((target, text, marker)) = Self::route_entry(entry) {
|
||||
for (target, text, marker) in Self::route_entry(entry) {
|
||||
match target {
|
||||
PaneTarget::Conversation => {
|
||||
self.conversation.push_line_with_marker(text, Color::Cyan, marker);
|
||||
}
|
||||
PaneTarget::ConversationAssistant => {
|
||||
self.conversation.push_line_with_marker(text, Color::Reset, marker);
|
||||
}
|
||||
PaneTarget::Tools => {
|
||||
self.tools.push_line(text, Color::Yellow);
|
||||
}
|
||||
PaneTarget::Conversation =>
|
||||
self.conversation.push_line_with_marker(text, Color::Cyan, marker),
|
||||
PaneTarget::ConversationAssistant =>
|
||||
self.conversation.push_line_with_marker(text, Color::Reset, marker),
|
||||
PaneTarget::Tools =>
|
||||
self.tools.push_line(text, Color::Yellow),
|
||||
PaneTarget::ToolResult => {
|
||||
for line in text.lines().take(20) {
|
||||
self.tools.push_line(format!(" {}", line), Color::DarkGray);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue