From 603d58e68645774a0623d8301da60bf00913c7e1 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Wed, 8 Apr 2026 12:05:49 -0400 Subject: [PATCH] Fix Thinking/Log panics: skip entries with empty token_ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Entries with empty token_ids (Thinking, Log) are not part of the prompt and don't have messages. Skip them in streaming_index(), route_entry(), and sync_from_agent() instead of calling .message() which panics. Using token_ids.is_empty() as the guard in streaming_index means the check is tied to the data, not the type — any entry that doesn't produce tokens is safely skipped. Co-Authored-By: Proof of Concept --- src/agent/mod.rs | 1 + src/user/chat.rs | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/agent/mod.rs b/src/agent/mod.rs index 6fcd403..449c2eb 100644 --- a/src/agent/mod.rs +++ b/src/agent/mod.rs @@ -370,6 +370,7 @@ impl Agent { /// Find the index of the in-progress streaming entry (unstamped assistant message). fn streaming_index(&self) -> Option { self.context.conversation.entries().iter().rposition(|ce| { + if ce.token_ids.is_empty() { return false; } let m = ce.entry.message(); m.role == Role::Assistant && m.timestamp.is_none() }) diff --git a/src/user/chat.rs b/src/user/chat.rs index 92126cb..334958d 100644 --- a/src/user/chat.rs +++ b/src/user/chat.rs @@ -417,8 +417,11 @@ impl InteractScreen { use crate::agent::api::Role; use crate::agent::context::ConversationEntry; - if let ConversationEntry::Memory { .. } = entry { - return vec![]; + match entry { + ConversationEntry::Memory { .. } + | ConversationEntry::Thinking(_) + | ConversationEntry::Log(_) => return vec![], + _ => {} } let msg = entry.message(); @@ -489,7 +492,8 @@ impl InteractScreen { } // Only stop at assistant if it matches - otherwise keep going - if matches && self.last_entries[i].entry.message().role == Role::Assistant { + if matches && !self.last_entries[i].token_ids.is_empty() + && self.last_entries[i].entry.message().role == Role::Assistant { break; } }