Skip to main content

Conversation

Struct Conversation 

Source
pub struct Conversation {
    pub messages: Vec<Message>,
    pub stream_buffer: Option<String>,
    pub tool_call_buffer: Option<ToolCallBuffer>,
    pub turn_tracker: TurnTracker,
    pub cold_summaries: Vec<String>,
}

Fields§

§messages: Vec<Message>§stream_buffer: Option<String>§tool_call_buffer: Option<ToolCallBuffer>§turn_tracker: TurnTracker§cold_summaries: Vec<String>

Cold zone: FIFO queue of compressed history summaries (max 3). Each entry is an LLM-generated summary of older turns.

Implementations§

Source§

impl Conversation

Source

pub fn new() -> Self

Source

pub fn load(path: &Path) -> Self

Load conversation history from disk. Never fails — returns empty on any error.

Source

pub fn save(&self, path: &Path)

Save conversation history to disk atomically (write to temp, then rename).

Source

pub fn history_path() -> PathBuf

Path to history file.

Source

pub fn add_user_message(&mut self, content: &str)

Source

pub fn cancel_current_turn(&mut self)

Cancel the current active turn: save all conversation content up to the moment of cancel. The user cancelled because they want to redirect the model, not because they want to lose context — the LLM needs to see what it already did so it can adjust.

If the model issued tool calls that never got results, we append (cancelled) ToolResult entries for them so the API doesn’t reject the message sequence with “messages illegal”.

Source

pub fn cancel_current_turn_including_user(&mut self)

Cancel the current active turn AND remove the user message. Used on Error exits where leaving an orphan user message (no assistant reply) would cause weak models to return 0 tokens on the next turn — two consecutive User messages with no intervening Assistant confuses OpenAI-compatible APIs.

Source

pub fn push_delta(&mut self, delta: &str)

Source

pub fn clear_stream_buffer(&mut self)

Clear the stream buffer without finalizing (used when text output is actually a malformed tool call that will be re-processed).

Source

pub fn finalize_stream(&mut self)

Source

pub fn add_assistant_tool_calls( &mut self, text: Option<&str>, tool_calls: Vec<ToolCall>, reasoning: Option<&str>, )

Source

pub fn add_assistant_tool_calls_with_thinking( &mut self, text: Option<&str>, tool_calls: Vec<ToolCall>, reasoning: Option<&str>, thinking_blocks: Vec<ThinkingBlock>, )

Like add_assistant_tool_calls but additionally stores Anthropic extended-thinking content blocks (text + signature pairs). The blocks must be echoed verbatim on subsequent requests when the upstream is Anthropic-style and thinking is enabled — otherwise the next request gets 400 The content[].thinking in the thinking mode must be passed back to the API. Other provider paths (OpenAI / Ollama) ignore this field via .. destructuring, so leaving it populated is harmless across cross-provider switches.

Source

pub fn add_tool_result(&mut self, result: ToolResult)

Source

pub fn finalize_stream_with_tool_call( &mut self, tool_call: ToolCall, reasoning: Option<&str>, )

Source

pub fn finalize_stream_with_tool_calls( &mut self, tool_calls: &[ToolCall], reasoning: Option<&str>, )

Finalize the current stream buffer with multiple tool calls at once (multi-tool support). reasoning carries thinking-model reasoning_content accumulated during the stream; it’s stored on the message so the send-side policy can echo it back when the provider demands (see ReasoningPolicy).

Source

pub fn finalize_stream_with_tool_calls_and_thinking( &mut self, tool_calls: &[ToolCall], reasoning: Option<&str>, thinking_blocks: Vec<ThinkingBlock>, )

Variant that additionally records Anthropic extended-thinking blocks for echo-back. See add_assistant_tool_calls_with_thinking.

Source

pub fn to_provider_messages(&self, system_prompt: &str) -> Vec<Message>

Source

pub fn to_provider_messages_windowed( &self, system_prompt: &str, window: usize, ) -> Vec<Message>

Like to_provider_messages but only sends the last window messages. Ensures the window starts at a valid boundary — never in the middle of a tool_call/tool_result pair (which causes API “messages illegal” errors).

Source

pub fn apply_compression(&mut self, remove_count: usize, summary: String)

Apply compression: store summary in cold zone, remove old messages. remove_count = number of messages from the front to remove. (Changed from turn-based to message-based to support single-user-message sessions where turn_tracker has only 1-2 turns but 30+ messages.)

── CRITICAL INVARIANT ── After compression:

  • All surviving turns must have: start_idx < new_messages.len()
  • All surviving turns must have: end_idx() <= new_messages.len()
  • All surviving turns must have: msg_count > 0 These invariants prevent underflow in on_user_message(msg_idx).

Trait Implementations§

Source§

impl Debug for Conversation

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Conversation

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more