Skip to main content

AssistantSessions

Struct AssistantSessions 

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

Every assistant session this server knows about.

Implementations§

Source§

impl AssistantSessions

Source

pub async fn create( &self, subject: &str, harness: Option<&str>, account: Option<&str>, title: Option<String>, ) -> Result<AssistantSessionSummary, AssistantSessionError>

Open a session on a catalogue harness.

Records the session; the harness starts on the first turn. The returned summary therefore reports dormant — no process, and continuable — which is the truthful answer for a conversation nobody has said anything in yet.

The pick is REMEMBERED, caller-scoped, so the next new-conversation form opens on the harness this operator last used. It is written from what they actually opened rather than from a preference they set, and it is written only after the session record exists — a remembered pick for a session that was refused would be a choice nobody made.

§Errors

[AssistantSessionError::NotCommissioned] when the store is unusable, [AssistantSessionError::UnknownHarness] / UnknownAccount when the caller names one that does not exist, [AssistantSessionError::HarnessUnavailable] when the chosen harness’s launch program is not on this server’s PATH — refused HERE rather than accepted and failed at the first message — or whatever the store reports.

Source

pub async fn current( &self, subject: &str, ) -> Result<Option<AssistantSessionSummary>, AssistantSessionError>

The caller’s CURRENT session: the newest one that is not ended.

One thread is the shape an operator actually holds — the dock panel and the inline editor bar are two views of ONE conversation, not two conversations — so “which session am I in” is a first-class read rather than something each surface derives from a list and could derive differently.

Ok(None) when the caller has no continuable session. That is an absence, not a refusal: a caller with no session is the ordinary state of somebody who has not started one.

§Errors

Whatever the store reports.

Source

pub async fn read( &self, subject: &str, session_id: AssistantSessionId, ) -> Result<(AssistantSessionSummary, Vec<AssistantSessionFrame>), AssistantSessionError>

A session’s summary and its whole transcript.

§Errors

Not found (including another subject’s session), or whatever the store reports.

Source

pub async fn watch( &self, subject: &str, session_id: AssistantSessionId, after: Option<u64>, ) -> Result<(Vec<AssistantSessionFrame>, Receiver<AssistantSessionFrame>), AssistantSessionError>

The transcript so far, then every frame as it arrives.

The replay is read BEFORE the subscription is taken so nothing can land between the two: a frame committed after the read and before the subscribe would be in neither, and a client would have a hole it could not see. Taking the receiver first means the worst case is a DUPLICATE frame, which a client can drop by index.

§Errors

Not found, or whatever the store reports.

Source

pub async fn push_context( &self, subject: &str, session_id: AssistantSessionId, context: AssistantTurnContext, ) -> Result<(), AssistantSessionError>

Share the operator’s on-screen context without asking anything.

Appended to the transcript, which IS the shared context: the harness’s assistant_context tool reads the latest one, and both console surfaces read the same record. There is no second store to keep in step.

§Errors

Not found, or whatever the store reports.

Source

pub async fn turn( &self, subject: &str, session_id: AssistantSessionId, text: String, context: Option<AssistantTurnContext>, command: Option<AssistantCommandInvocation>, ) -> Result<String, AssistantSessionError>

Ask the agent something.

Starts the harness when none is running — freshly for a session that has never opened, or with session/load for a dormant one whose agent can reload its own conversation.

§Errors

Not found; [AssistantSessionError::Busy] when a turn is already open; [AssistantSessionError::Ended] when the session cannot be continued; [AssistantSessionError::HarnessFailed] when the harness will not start.

Source

pub async fn cancel( &self, subject: &str, session_id: AssistantSessionId, ) -> Result<(), AssistantSessionError>

Stop the open turn.

§Errors

Not found, or [AssistantSessionError::Ended] when no process is running to cancel.

Source

pub async fn set_config_option( &self, subject: &str, session_id: AssistantSessionId, option_id: &str, value: &Value, ) -> Result<Vec<AssistantConfigOption>, AssistantSessionError>

Set one advertised configuration option on a live session — the model picker’s write side.

Refused BY NAME when the harness has not advertised the option, or (for a select) the value: a client offers what the session’s config_options say, and anything else is a control that should never have been on the screen — the exact rule turns follow for commands. The agent’s answer, the full option set as it now stands, is recorded on the transcript exactly as an advertisement is (which also refreshes the record’s cache), and returned.

§Errors

Not found / not yours; [AssistantSessionError::UnknownConfigOption] for an unadvertised option or value, or a value of the wrong shape; [AssistantSessionError::Ended] when no process is running; [AssistantSessionError::HarnessFailed] when the agent refuses, the transport fails, or the answer cannot be read as an option set.

Source

pub async fn resume( &self, subject: &str, session_id: AssistantSessionId, ) -> Result<AssistantSessionSummary, AssistantSessionError>

Say whether a session can be continued, settling it when it cannot.

There is no promptless spawn to perform here — ACP opens a conversation by asking something — so this does not start a process. What it does is make the resume decision READABLE before an operator types: a session whose agent never advertised loadSession is settled ended by an appended record naming the capability, so the panel can say so instead of offering a box that would refuse.

§Errors

Not found, or whatever the store reports.

Source

pub async fn delete( &self, subject: &str, session_id: AssistantSessionId, ) -> Result<(), AssistantSessionError>

Put a session away: shut its harness down and settle it.

The transcript is KEPT. Deleting a session deletes a process, not a record — an operator reading back what an agent did a week ago is exactly who this surface exists for.

What it settles to follows the same fact every resume decision follows: whether the agent can reload the conversation. A session whose agent advertised loadSession and left a handle settles AssistantSessionState::Closed — out of the operator’s way, never current, but reopened by the next turn taken on it from history. One whose agent cannot reload settles AssistantSessionState::Ended, and the transcript is all that is left of it.

§Errors

Not found, or whatever the store reports.

Source

pub async fn sweep_orphans(&self) -> Result<usize, AssistantSessionError>

Settle every session whose process is gone, at boot.

WRITTEN BACK, not merely displayed: the settlement is an appended record with its cause, so the next reader projects it rather than recomputing the same decision — and so the decision itself is auditable.

Returns how many sessions were settled.

§Errors

Whatever the store reports.

Source

pub async fn shutdown(&self)

Shut every live harness down — the server is stopping.

Source§

impl AssistantSessions

Source

pub fn new( store: Arc<dyn AssistantSessionStore>, config: ResolvedAssistantConfig, endpoint: Option<AssistantEndpoints>, catalogue: &'static [CatalogueHarness], ) -> Self

Build the registry over one durable store and the operator’s configuration.

Source

pub fn config(&self) -> &ResolvedAssistantConfig

The operator’s resolved [assistant] configuration.

Source

pub fn availability(&self) -> Availability

Whether this server can open a session at all, and why not when it cannot.

A stock server can: there is no [assistant] section to write, the harness catalogue ships with the build, and “not configured” is no longer a reason anything may give (RULED 2026-08-29). What CAN take the surface down is the durable store the sessions live in — a session is a record and a transcript before it is a process — and that is a refusal the product can name, with the store’s own error in it.

Read from the boot sweep, which is the one place this server has already exercised the store end to end. Nothing probes on the descriptor path: a full listing per description would make the panel’s own refresh the heaviest read on the box.

Whether a PARTICULAR harness can run is a different question with a different answer per entry, and it is answered on the descriptor’s harnesses[] (available, with the install hint) rather than folded into one sentence here.

Source

pub async fn last_harness_pick( &self, subject: &str, ) -> Result<Option<String>, AssistantSessionError>

The harness this caller last opened a session on, or None.

Read from the store, so it survives the restart that a remembered in-process choice would not. None is a complete answer — a caller who has picked nothing has picked nothing — and the console preselects the first available catalogue entry rather than the server inventing one.

§Errors

Whatever the store reports.

Source

pub fn hands_over_assistant_tools(&self) -> bool

Whether a session’s agent is handed this server’s own assistant tool server — the assistant_context route.

Independent of [mcp] enabled and of [assistant.tools] aion: the only thing that can take it away is this server being unable to state an address an agent could dial back on.

Source

pub fn hands_over_general_mcp(&self) -> bool

Whether a session’s agent is handed this server’s GENERAL MCP endpoint — the workflow tools.

One switch, [mcp] enabled, and no second one: the [assistant.tools] aion knob was retired with the rest of the section. Whether this server publishes workflow tools at all is a question an operator answers once, where the tools are; asking it again under the assistant would be a second thing to keep in step, and a session whose agent silently lacked the tools the server publishes is exactly the confusion that costs.

Source

pub async fn record( &self, session_id: AssistantSessionId, ) -> Result<Option<AssistantSessionRecord>, AssistantSessionError>

One session’s record, with NO caller narrowing.

The narrowed read (Self::owned_record) is for a human caller, whose authority is a subject. The assistant MCP route’s caller is a SESSION — it holds that session’s own minted bearer and no subject at all — so it reads the record it is about to prove it is, and the proof is the digest comparison rather than a subject match.

§Errors

Whatever the store reports.

Source

pub async fn state_of_session( &self, session_id: AssistantSessionId, ) -> Result<(AssistantSessionState, Option<String>), AssistantSessionError>

A session’s projected state and cause.

The public read of Self::state_of, for the assistant MCP route: a bearer is honoured only while the session it names is not ended, and that decision has to read the same projection every other surface reads.

§Errors

Whatever the store reports.

Source

pub async fn list( &self, subject: &str, ) -> Result<Vec<AssistantSessionSummary>, AssistantSessionError>

Every session this caller owns, newest first.

CALLER-scoped, not namespace-scoped: a session is one operator’s conversation with an agent and lives in no namespace. The store enumerates what it holds and the narrowing happens here, where the caller identity is.

§Errors

Whatever the store reports.

Source

pub async fn latest_context( &self, session_id: AssistantSessionId, ) -> Result<Option<AssistantTurnContext>, AssistantSessionError>

The most recently shared on-screen context for a session.

What the assistant_context MCP tool answers with, read off the transcript: the transcript IS the shared context, so there is no second store to keep in step and a restart loses nothing.

§Errors

Whatever Self::projection reports.

Trait Implementations§

Source§

impl Clone for AssistantSessions

Source§

fn clone(&self) -> AssistantSessions

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

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
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> IntoMaybeUndefined<T> for T

Source§

fn into_maybe_undefined(self) -> MaybeUndefined<T>

Converts this value into a three-state builder argument.
Source§

impl<T> IntoOption<T> for T

Source§

fn into_option(self) -> Option<T>

Converts this value into an optional builder argument.
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
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> 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> 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