pub struct Thread {
pub id: String,
pub subject: String,
pub created: i64,
pub updated: i64,
pub active_policy: Option<String>,
pub orchestrator: Option<String>,
pub server_thread: Option<String>,
pub pending_job: Option<String>,
pub draft: Option<String>,
pub messages: Vec<Message>,
}Expand description
A stored conversation. server_thread is the x-nsed-session-id used for
cheap same-policy continuation; it is an optimisation, not the source of
truth — the source of truth is messages.
Fields§
§id: String§subject: String§created: i64§updated: i64§active_policy: Option<String>§orchestrator: Option<String>§server_thread: Option<String>§pending_job: Option<String>Job id of a launched turn whose reply hasn’t landed yet. Persisted so a deliberation that finishes while the TUI is closed can be reconciled on reopen (fetch the result by this id). Cleared when the reply is appended.
draft: Option<String>Unsent compose text (pastes already expanded), persisted so a long draft survives a restart / a failed send instead of being lost with the TUI process. Restored into the compose box on reopen; cleared once sent.
messages: Vec<Message>Implementations§
Source§impl Thread
impl Thread
Sourcepub fn new(subject: impl Into<String>) -> Self
pub fn new(subject: impl Into<String>) -> Self
A fresh thread with a generated id and the current timestamps.
Sourcepub fn push_message(&mut self, turn: Message)
pub fn push_message(&mut self, turn: Message)
Append a message and bump updated. An unrooted turn (parent_id
unset) continues the current tip — linear-append, the common case — so
callers that don’t care about branching keep working. Use Self::reply
to root a turn under a specific node (or as a new root).
Sourcepub fn children(&self, parent_id: Option<&str>) -> Vec<&Message>
pub fn children(&self, parent_id: Option<&str>) -> Vec<&Message>
Direct replies to parent_id (None = root turns).
Sourcepub fn fork_depth(&self, id: &str) -> usize
pub fn fork_depth(&self, id: &str) -> usize
How many forks lie in a node’s ancestry — its indent depth in the
reader. A linear lineage shares one branch (depth 0); each fork along the
path introduces a new branch (+1). = distinct branch_ids on the path − 1.
Sourcepub fn path_to_root(&self, id: &str) -> Vec<&Message>
pub fn path_to_root(&self, id: &str) -> Vec<&Message>
Root→node path following parent_id. Empty if id is unknown.
Sourcepub fn tip(&self) -> Option<&Message>
pub fn tip(&self) -> Option<&Message>
The newest message overall — the default reply target (“continue the
conversation”). None on an empty thread. Ties on ts (same-second
turns) resolve to the last appended: max_by_key returns the last of
equal maxima, and messages are pushed in order.
Sourcepub fn reply(
&mut self,
parent_id: Option<&str>,
role: impl Into<String>,
content: impl Into<String>,
) -> String
pub fn reply( &mut self, parent_id: Option<&str>, role: impl Into<String>, content: impl Into<String>, ) -> String
Attach a new turn under parent_id and return its id. Branch rule: a
reply to a current leaf inherits the parent’s branch (linear
continuation); a reply under a non-leaf node (or a root turn) starts a
fresh branch (a fork). The pre-append leaf check is what makes the FIRST
reply continue and a SECOND reply to the same node fork.
Sourcepub fn rollback_last_user_turn(&mut self) -> bool
pub fn rollback_last_user_turn(&mut self) -> bool
Roll back the most recently added turn — used when the orchestrator
rejects a just-sent turn (e.g. no agents online) so the thread doesn’t
keep a phantom “deliberating” turn with no job behind it. Removes the last
message only if it’s a childless user turn (the optimistic send) and
clears pending_job. Returns whether a turn was removed.
Sourcepub fn migrate_linear(&mut self)
pub fn migrate_linear(&mut self)
Backfill tree fields on a pre-tree (linear) thread: assign ids, chain each message under the previous one, and share a single branch. A no-op once every message already carries an id.
Sourcepub fn to_deliberation_query_from(
&self,
parent_id: Option<&str>,
new_user_message: &str,
) -> String
pub fn to_deliberation_query_from( &self, parent_id: Option<&str>, new_user_message: &str, ) -> String
Render the root→parent_id path plus a new user message into one task
string for the native deliberation API. A fork only carries its own
lineage (the path), which is what makes “reply under wsup? only” differ
from “continue after Hi!”. Subject leads as framing (see
Self::to_deliberation_query).
Sourcepub fn to_deliberation_query(&self, new_user_message: &str) -> String
pub fn to_deliberation_query(&self, new_user_message: &str) -> String
Render the stored conversation plus a new user message into a single
task string for the native deliberation API (which takes one
user_query, not a message array). Mirrors the server compat layer’s
to_query_string so a multi-turn thread over the native transport reads
the same way: prior non-empty messages prefixed with [role], the new
question last. The thread’s subject (when set) leads the request as a
Subject: line so the agents see the conversation’s framing.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Thread
impl<'de> Deserialize<'de> for Thread
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for Thread
impl StructuralPartialEq for Thread
Auto Trait Implementations§
impl Freeze for Thread
impl RefUnwindSafe for Thread
impl Send for Thread
impl Sync for Thread
impl Unpin for Thread
impl UnsafeUnpin for Thread
impl UnwindSafe for Thread
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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 moreSource§impl<T, U> OverflowingInto<U> for Twhere
U: OverflowingFrom<T>,
impl<T, U> OverflowingInto<U> for Twhere
U: OverflowingFrom<T>,
fn overflowing_into(self) -> (U, bool)
Source§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more