Add ConversationEntry::Thinking — 0 tokens, not sent to API

Thinking/reasoning content is now a first-class entry type:
- Serialized as {"thinking": "..."} in conversation log
- 0 tokens for budgeting (doesn't count against context window)
- Filtered from assemble_api_messages (not sent back to model)
- Displayed in UI with "thinking: ..." label and expandable content

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-07 22:46:06 -04:00
parent 7c5fddcb19
commit e0ee441aec
3 changed files with 32 additions and 13 deletions

View file

@ -8,7 +8,7 @@ use ratatui::{
Frame,
crossterm::event::KeyCode,
};
use crate::agent::context::ContextSection;
use crate::agent::context::{ContextSection, ConversationEntry};
/// UI-only tree node for the section tree display.
/// Built from ContextSection data; not used for budgeting.
@ -26,10 +26,10 @@ pub struct SectionView {
/// Each entry becomes a child with label + expandable content.
pub fn section_to_view(section: &ContextSection) -> SectionView {
let children: Vec<SectionView> = section.entries().iter().map(|ce| {
let content = if ce.entry.is_log() {
String::new()
} else {
ce.entry.message().content_text().to_string()
let content = match &ce.entry {
ConversationEntry::Log(_) => String::new(),
ConversationEntry::Thinking(text) => text.clone(),
_ => ce.entry.message().content_text().to_string(),
};
SectionView {
name: ce.entry.label(),