Struct ChatSessionState

Source
pub struct ChatSessionState {
    pub id: ChatSessionId,
    pub title: String,
    pub status: ChatSessionStatus,
    pub messages: Vec<ChatMessage>,
    pub active_request: Option<ChatRequestId>,
    pub last_error: Option<String>,
}
Expand description

Serializable, ordered state of one chat session.

The public fields allow adapters to restore provider snapshots directly. Self::apply_event provides the canonical incremental update semantics.

§Examples

use ailloli_ui_core::{
    ChatEvent, ChatItemId, ChatSessionId, ChatSessionState,
};

let mut session = ChatSessionState::new(ChatSessionId::from_index(1), "Demo");
assert!(session.apply_event(ChatEvent::MessageAdded(
    ailloli_ui_core::ChatMessage::user(ChatItemId::from_index(1), "Hi"),
)));
assert_eq!(session.summary().message_count, 1);

Fields§

§id: ChatSessionId

Stable session identity.

§title: String

Consumer-facing title; an empty title is allowed.

§status: ChatSessionStatus

Aggregate lifecycle of the session.

§messages: Vec<ChatMessage>

Items in insertion order; replacing an existing ID preserves its index.

§active_request: Option<ChatRequestId>

In-flight provider request, or None when no request is tracked.

§last_error: Option<String>

Latest session-level failure text, or None when absent or cleared.

Implementations§

Source§

impl ChatSessionState

Source

pub fn new(id: ChatSessionId, title: impl Into<String>) -> Self

Creates an empty session in ChatSessionStatus::Ready.

§Examples
use ailloli_ui_core::{ChatSessionId, ChatSessionState, ChatSessionStatus};
let session = ChatSessionState::new(ChatSessionId::new("session-1"), "Demo");
assert_eq!(session.status, ChatSessionStatus::Ready);
Source

pub fn summary(&self) -> ChatSessionSummary

Builds a compact owned summary of the current snapshot.

The preview is None when there are no messages. Otherwise it contains at most 72 Unicode scalar values from the final message followed by ... when truncated; an empty final message yields Some("").

§Performance

Clones the ID and title and counts the final message text to determine whether truncation is required.

§Examples
use ailloli_ui_core::{ChatSessionId, ChatSessionState};
let summary = ChatSessionState::new(ChatSessionId::new("session-1"), "Demo").summary();
assert_eq!(summary.message_count, 0);
Source

pub fn with_event(&self, event: ChatEvent) -> Self

Returns an updated clone, leaving this snapshot unchanged.

This has the same event semantics as Self::apply_event.

§Performance

Clones the complete session before applying the event.

§Examples
use ailloli_ui_core::{ChatEvent, ChatSessionId, ChatSessionState, ChatSessionStatus};
let session = ChatSessionState::new(ChatSessionId::new("session-1"), "Demo");
let failed = session.with_event(ChatEvent::Failed { message: "offline".into() });
assert_eq!(failed.status, ChatSessionStatus::Failed);
assert_eq!(session.status, ChatSessionStatus::Ready);
Source

pub fn apply_event(&mut self, event: ChatEvent) -> bool

Applies one reducer event and reports whether the snapshot changed.

Message IDs are upserted: an existing item is replaced at its current index and a new item is appended. A delta for an unknown item creates a streaming assistant text item without a request ID. Finishing an assistant item marks the session completed and clears the active request even when that item is unknown. Finishing a request clears active_request only when IDs match, but always marks the session completed. ChatEvent::RequestStarted is the event that clears last_error; ordinary message events preserve it.

§Performance

Clones the complete pre-event state to compute the boolean result and performs a linear search through messages for each upsert or lookup.

§Examples
use ailloli_ui_core::{
    ChatEvent, ChatItemId, ChatMessageKind, ChatRequestId,
    ChatSessionId, ChatSessionState,
};

let mut chat = ChatSessionState::new(ChatSessionId::from_index(1), "Demo");
let item = ChatItemId::from_index(1);
chat.apply_event(ChatEvent::AssistantMessageStarted {
    item_id: item.clone(),
    request_id: ChatRequestId::from_index(1),
    kind: ChatMessageKind::Text,
});
chat.apply_event(ChatEvent::AssistantMessageDelta {
    item_id: item.clone(),
    delta: "Hello".into(),
});
assert_eq!(chat.message(&item).unwrap().text, "Hello");
Source

pub fn message(&self, item_id: &ChatItemId) -> Option<&ChatMessage>

Finds a message by ID without changing insertion order.

Returns None if the ID has not been observed. Lookup is linear in the number of messages.

§Examples
use ailloli_ui_core::{ChatEvent, ChatItemId, ChatMessage, ChatSessionId, ChatSessionState};
let id = ChatItemId::new("item-1");
let mut session = ChatSessionState::new(ChatSessionId::new("session-1"), "Demo");
session.apply_event(ChatEvent::MessageAdded(ChatMessage::user(id.clone(), "Hello")));
assert_eq!(session.message(&id).unwrap().text, "Hello");

Trait Implementations§

Source§

impl Clone for ChatSessionState

Source§

fn clone(&self) -> ChatSessionState

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ChatSessionState

Source§

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

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

impl<'de> Deserialize<'de> for ChatSessionState

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for ChatSessionState

Source§

fn eq(&self, other: &ChatSessionState) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for ChatSessionState

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for ChatSessionState

Source§

impl StructuralPartialEq for ChatSessionState

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,