Skip to main content

Conversation

Struct Conversation 

Source
pub struct Conversation { /* private fields */ }
Expand description

A conversation: its entries (each a message with an id and, when it is not the user’s own or the model’s, an author), its asides, why its last user message is unanswered, and the changes made to it that nobody has saved yet. Every edit builds a Change, applies it with the same code a fold (apply) uses, and keeps it in the outbox (unsaved).

Two conversations are equal when their entries (messages, ids and authors), saved asides and halt are: the outbox, the revision, unsaved asides and when entries were made are not compared, so a value folded from a log equals the live one and two values built alike are equal.

Its serde form is its state: entries, saved asides, halt and the next ids, without the outbox, the revision or the lineage. A value read back from it is Lineage::DETACHED.

Implementations§

Source§

impl Conversation

Source

pub fn turns( &self, ) -> impl DoubleEndedIterator<Item = (AsideId, TurnRecord)> + '_

The turn records, oldest first, with their asides’ ids; the newest is turns().next_back(), found from the end.

Source

pub fn open_turn(&mut self) -> TurnRecord

Records a turn that begins now, numbered after the last record and starting at turn_start. Returns the new record.

Source

pub fn end_turn(&mut self, end: TurnEnd) -> bool

Ends the last turn record, when it is open, with end. Returns whether it was open.

Source§

impl Conversation

Source

pub fn new() -> Self

An empty conversation.

Source

pub fn from_messages( messages: impl IntoIterator<Item = impl Into<Arc<Message>>>, ) -> Self

A conversation of messages, each its own entry, recorded so that saving it writes them (an import, a library user’s history).

Source

pub fn messages(&self) -> &[Arc<Message>]

The messages, oldest first: what a request sends.

Source

pub fn into_messages(self) -> Vec<Arc<Message>>

The messages, oldest first, taken out of the conversation: what a request sends, without a copy.

Source

pub fn entries( &self, ) -> impl DoubleEndedIterator<Item = EntryRef<'_>> + ExactSizeIterator

The entries, oldest first.

Source

pub fn entry(&self, at: usize) -> Option<Entry>

Entry at, with its author, id and when it was made, to splice back changed.

Source

pub fn id(&self, at: usize) -> Option<MessageId>

The id of entry at.

Source

pub fn key(&self, at: usize) -> Option<MessageKey>

The identity of entry at beyond this conversation.

Source

pub fn index_of_key(&self, key: MessageKey) -> Option<usize>

Where the entry with identity key is now; None when it is not here, also when an entry with its id was made at another time.

Source

pub fn author(&self, at: usize) -> Option<&Author>

Who wrote entry at; None for the user’s own text, the model’s reply, a tool result, or no such entry.

Source

pub fn index_of(&self, id: MessageId) -> Option<usize>

Where entry id is now; None once an edit took it out.

Source

pub fn start_of(&self, id: MessageId) -> usize

Where a span that began at entry id begins now, such as a turn: its index while it is there; the end for an entry not made yet; 0 for one an edit took out, as a summary then stands for what came before it.

Source

pub fn turn_start(&self) -> MessageId

Where a turn starting now begins: the first of the user messages at the end, which it answers, else the first entry it adds.

Source

pub fn asked(&self, start: MessageId) -> impl Iterator<Item = EntryRef<'_>>

The entries a turn that began at start (its turn_start) answers: the user messages in a row from where it begins now (start_of). After a stopped turn they begin with that turn’s tool results and the STOPPED note, before what was sent next.

Source

pub fn request(&self, start: MessageId) -> Option<EntryRef<'_>>

The message that asked for the turn that began at start: the first of the entries it answers (asked) that is a request (EntryRef::is_request).

Source

pub fn halted(&self) -> Option<Halt>

Why the user’s last message is left unanswered, if it was halted. Cleared when an entry is pushed or a splice reaches the end.

Source

pub fn awaits_model(&self) -> bool

Whether the model owes an answer: the last message a model reads is the user’s, and it was not halted. A failed or stopped reply after it is never read (StopReason::is_failure), so the answer is still owed.

Source

pub fn pending_calls(&self) -> Vec<ToolCall>

The tool calls of the last assistant message that nothing answers yet. See pairing::pending_calls.

Source

pub fn validate(&self) -> Result<(), PairingError>

Whether the messages pair every tool call with its result. See pairing::validate.

Source

pub fn asides(&self) -> impl DoubleEndedIterator<Item = (AsideId, &Aside)>

The asides, in the order put.

Source

pub fn aside(&self, id: AsideId) -> Option<&Aside>

Aside id.

Source

pub fn aside_position(&self, aside: &Aside) -> usize

Where aside is drawn: before entry position, after entry position - 1. While an edit took out the entry it follows, after the entry that stands for it now (start_of).

Source

pub fn push(&mut self, entry: impl Into<Entry>) -> MessageId

Pushes entry, after a STOPPED entry by Author::rig in the same change when the user stopped the last request; a halt is cleared. Returns the new entry’s id; a pushed entry never reuses one.

Source

pub fn extend( &mut self, messages: impl IntoIterator<Item = impl Into<Arc<Message>>>, )

Pushes each of messages as its own entry without an author, in one change, as push does.

Source

pub fn splice( &mut self, range: impl RangeBounds<usize>, with: impl IntoIterator<Item = Entry>, by: Author, ) -> Spliced

Replaces entries in range, clamped to the conversation, with with, recorded as made by by. An entry of with keeps its id when that id was in the range and no earlier entry of with kept it; any other gets a new id. Nothing merges. A splice reaching the end clears the halt. An empty range replaced by nothing changes and records nothing.

Source

pub fn restore( &mut self, range: impl RangeBounds<usize>, with: impl IntoIterator<Item = Entry>, by: Author, ) -> Spliced

As splice, and an entry of with whose id this conversation made (below the next id), that no entry outside the range holds and no earlier entry of with took, keeps that id and when it was made (Entry::made, else now): entries put back as they were, such as a summary’s originals or an edit undone. Asides that followed such an entry follow it again. Only for entries this conversation held: an entry from elsewhere that carries an id would take one that meant another message here.

use rig_core::completion::Message;
use rig_core::conversation::{Author, Conversation, Entry};

let mut conversation = Conversation::from_messages([
    Message::user("one"),
    Message::assistant("two"),
]);
let ids: Vec<_> = conversation.entries().map(|entry| entry.id).collect();
let originals: Vec<Entry> = (0..2).filter_map(|at| conversation.entry(at)).collect();
let summary = Entry::new(Message::user("a summary"));
conversation.splice(.., [summary], Author::plugin("compact"));
let undone = conversation.restore(.., originals, Author::plugin("undo"));
assert_eq!(undone.restored, ids);
assert!(conversation.entries().map(|entry| entry.id).eq(ids));
Source

pub fn set_entries(&mut self, entries: Vec<Entry>, by: Author) -> Spliced

Makes the conversation hold entries, as made by by: one restore of the range between the longest start and end it shares with them (the same messages, ids and authors), so entries taken from it keep their ids. Nothing when they are equal.

Source

pub fn edit_each( &mut self, by: Author, edit: impl FnMut(EntryRef<'_>) -> Option<Message>, ) -> Vec<MessageId>

Rewrites entries in place, as made by by: edit sees each entry, oldest first, and returns the message to put in its place, or None to leave it. The entries it rewrote keep their ids and authors, and the whole edit is one change: a splice of the entries from the first rewritten to the last. Nothing is recorded when it rewrote none. Returns the ids of the entries it rewrote.

use rig_core::completion::Message;
use rig_core::conversation::{Author, Conversation};

let mut conversation = Conversation::from_messages([
    Message::user("one"),
    Message::user("two"),
]);
let before = conversation.id(1);
let changed = conversation.edit_each(Author::plugin("shout"), |entry| {
    (entry.index == 1).then(|| Message::user("TWO"))
});
assert_eq!(changed, before.into_iter().collect::<Vec<_>>());
assert_eq!(conversation.messages().get(1).map(|message| &**message), Some(&Message::user("TWO")));
assert_eq!(conversation.id(1), before);
Source

pub fn normalize(&mut self, by: Author) -> Normalized

Repairs the entries as pairing::normalize does, saved with set_entries as made by by, so merged entries keep the first’s id, author and made-time. An aside that followed an entry merged into another follows that one; one that followed a dropped entry follows the entry before it (each move recorded, by by). Returns what it repaired.

Source

pub fn reread(&mut self, from_log: Conversation) -> Result<(), ApplyError>

Takes everything a log holds from from_log, a value read from that log: entries, saved asides, halt, next ids, lineage and revision. This value’s unsaved asides stay, with their ids. For a host whose log was rewritten under the value it holds.

§Errors

ApplyError::Mismatch, changing nothing, while either value has unsaved changes, or when an unsaved aside’s id is a saved one’s in from_log.

Source

pub fn halt(&mut self, halt: Halt) -> bool

Leaves the user’s last message unanswered, for halt. Whether it was halted now: not when the model owes no answer.

Source

pub fn resume(&mut self) -> bool

Asks the model again for an answer to the user’s last message, also a halted one; whether the last message is the user’s.

Source

pub fn add_aside(&mut self, aside: Aside) -> AsideId

Puts aside after the asides already put and returns its id. An unsaved aside is not recorded.

Source

pub fn replace_aside(&mut self, id: AsideId, aside: Aside) -> bool

Replaces aside id with aside, in its place; whether there was one. Replacing a saved aside with an unsaved one records its removal.

Source

pub fn remove_aside(&mut self, id: AsideId) -> Option<Aside>

Removes aside id and returns it, or None if there was none.

Source

pub fn apply(&mut self, change: &ChangeRecord) -> Result<(), ApplyError>

Applies a recorded change verbatim, such as one read from a log or sent by a process that mirrors this conversation. It is not put in the outbox. Fails, changing nothing, when it does not fit.

Source

pub fn dated<R>(&mut self, at: u64, edit: impl FnOnce(&mut Self) -> R) -> R

Makes the edits of edit as made at at, in milliseconds since the Unix epoch, such as messages imported at the times their source logged them: their records carry that time, which a writer keeps, and the entries they make were made then. An edit dated inside, by a nested call, keeps its own time.

use rig_core::conversation::Conversation;
use rig_core::message::Message;

let mut conversation = Conversation::new();
conversation.dated(1_790_848_800_000, |conversation| {
    conversation.push(Message::user("Imported"))
});
let at = conversation.unsaved().first().and_then(|recorded| recorded.at);
assert_eq!(at, Some(1_790_848_800_000));
Source

pub fn unsaved(&self) -> &[ChangeRecord]

The changes made that nobody has saved yet, oldest first.

Source

pub fn take_unsaved(&mut self) -> Vec<ChangeRecord>

Takes the changes made that nobody has saved yet, to save them.

Source

pub fn revision(&self) -> u64

The changes behind this value, one per record: those of the log it continues (lineage) when it was last loaded or saved, then each applied or made since. An unsaved aside counts none.

Source

pub fn lineage(&self) -> Lineage

The saved log this value continues: Lineage::EMPTY when it was begun here from nothing and never saved, Lineage::DETACHED when it was read back from its serde form.

Source

pub fn continues(&self, lineage: Lineage, changes: u64) -> bool

Whether this value’s unsaved changes, appended to the log of lineage that holds changes changes, give this value: it continues that log, holding all of its changes and since then only its unsaved ones. A value begun here from nothing continues any empty log.

Source

pub fn continue_log(&mut self, lineage: Lineage, changes: u64)

Marks this value as holding the changes changes of the log of lineage, then its unsaved ones: what a store does once it loaded the value from that log or saved it there.

Source

pub fn view(&self) -> Self

A copy with an empty outbox, for edits never saved (a preview, a reset’s state).

Source

pub fn request_view(&self) -> Self

A view without the asides, for a model request’s copy: a request never sends them, and one is built per model call.

Trait Implementations§

Source§

impl Clone for Conversation

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
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
Source§

impl<'de> Deserialize<'de> for Conversation

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 Conversation

Source§

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

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

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

Inequality operator !=. Read more
Source§

impl Serialize for Conversation

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

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

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

Source§

fn __clone_box(&self, _: Private) -> *mut ()

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> IntoToolOutput for T
where T: Serialize + 'static,

Source§

fn into_tool_output(self) -> Result<ToolOutput, ToolExecutionError>

Convert this value without routing structured data through a string.
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: Sized + 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: Sized + 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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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 = !

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

fn try_from(value: U) -> Result<T, !>

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WasmCompatSend for T
where T: Send,

Source§

impl<T> WasmCompatSync for T
where T: Sync,

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