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.
|
/// Route an agent entry to pane items.
|
||||||
/// Returns None for entries that shouldn't be displayed (memory, system).
|
/// Returns empty vec for entries that shouldn't be displayed.
|
||||||
fn route_entry(&mut self, entry: &crate::agent::context::ConversationEntry) -> Option<&mut PaneState> {
|
fn route_entry(entry: &crate::agent::context::ConversationEntry) -> Vec<(PaneTarget, String, Marker)> {
|
||||||
use crate::agent::api::types::Role;
|
use crate::agent::api::types::Role;
|
||||||
use crate::agent::context::ConversationEntry;
|
use crate::agent::context::ConversationEntry;
|
||||||
|
|
||||||
if let ConversationEntry::Memory { .. } = entry {
|
if let ConversationEntry::Memory { .. } = entry {
|
||||||
return None;
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg = entry.message();
|
let msg = entry.message();
|
||||||
let text = msg.content_text().to_string();
|
let text = msg.content_text().to_string();
|
||||||
|
|
||||||
match msg.role {
|
if text.starts_with("<system-reminder>") {
|
||||||
if text.is_empty() { return None; }
|
return vec![];
|
||||||
if text.starts_with("<system-reminder>") { return None; }
|
}
|
||||||
|
|
||||||
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 => {
|
Role::Assistant => {
|
||||||
|
let mut items = Vec::new();
|
||||||
// Tool calls → tools pane
|
// Tool calls → tools pane
|
||||||
if let Some(ref calls) = msg.tool_calls {
|
if let Some(ref calls) = msg.tool_calls {
|
||||||
for call in calls {
|
for call in calls {
|
||||||
let line = format!("[{}] {}",
|
let line = format!("[{}] {}",
|
||||||
call.function.name,
|
call.function.name,
|
||||||
call.function.arguments.chars().take(80).collect::<String>());
|
call.function.arguments.chars().take(80).collect::<String>());
|
||||||
// TODO: return multiple targets — for now just return first tool call
|
items.push((PaneTarget::Tools, line, Marker::None));
|
||||||
return Some((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));
|
||||||
|
}
|
||||||
|
items
|
||||||
}
|
}
|
||||||
Role::Tool => Some(&mut self.tools),
|
Role::Tool => {
|
||||||
Role::System => None,
|
if text.is_empty() { return vec![]; }
|
||||||
|
vec![(PaneTarget::ToolResult, text, Marker::None)]
|
||||||
|
}
|
||||||
|
Role::System => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,7 +133,7 @@ impl InteractScreen {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let popped = self.last_entries.pop().unwrap();
|
let popped = self.last_entries.pop().unwrap();
|
||||||
if let Some((target, _, _)) = Self::route_entry(&popped) {
|
for (target, _, _) in Self::route_entry(&popped) {
|
||||||
match target {
|
match target {
|
||||||
PaneTarget::Conversation | PaneTarget::ConversationAssistant
|
PaneTarget::Conversation | PaneTarget::ConversationAssistant
|
||||||
=> self.conversation.pop_line(),
|
=> self.conversation.pop_line(),
|
||||||
|
|
@ -136,17 +147,14 @@ impl InteractScreen {
|
||||||
// Phase 2: push new entries
|
// Phase 2: push new entries
|
||||||
let start = self.last_entries.len();
|
let start = self.last_entries.len();
|
||||||
for entry in entries.iter().skip(start) {
|
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 {
|
match target {
|
||||||
PaneTarget::Conversation => {
|
PaneTarget::Conversation =>
|
||||||
self.conversation.push_line_with_marker(text, Color::Cyan, marker);
|
self.conversation.push_line_with_marker(text, Color::Cyan, marker),
|
||||||
}
|
PaneTarget::ConversationAssistant =>
|
||||||
PaneTarget::ConversationAssistant => {
|
self.conversation.push_line_with_marker(text, Color::Reset, marker),
|
||||||
self.conversation.push_line_with_marker(text, Color::Reset, marker);
|
PaneTarget::Tools =>
|
||||||
}
|
self.tools.push_line(text, Color::Yellow),
|
||||||
PaneTarget::Tools => {
|
|
||||||
self.tools.push_line(text, Color::Yellow);
|
|
||||||
}
|
|
||||||
PaneTarget::ToolResult => {
|
PaneTarget::ToolResult => {
|
||||||
for line in text.lines().take(20) {
|
for line in text.lines().take(20) {
|
||||||
self.tools.push_line(format!(" {}", line), Color::DarkGray);
|
self.tools.push_line(format!(" {}", line), Color::DarkGray);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue