Skip to main content

SessionSource

Trait SessionSource 

Source
pub trait SessionSource:
    Send
    + Sync
    + 'static {
    // Required method
    fn create<'life0, 'async_trait>(
        &'life0 self,
        cwd: PathBuf,
        mcp: Vec<McpServer>,
    ) -> Pin<Box<dyn Future<Output = Result<PreparedRun, RunError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;

    // Provided methods
    fn resume<'life0, 'life1, 'async_trait>(
        &'life0 self,
        agent_id: &'life1 str,
        cwd: PathBuf,
        mcp: Vec<McpServer>,
    ) -> Pin<Box<dyn Future<Output = Result<PreparedRun, RunError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
    fn lists_sessions(&self) -> bool { ... }
    fn list_sessions<'life0, 'async_trait>(
        &'life0 self,
        cwd: PathBuf,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<PersistedSession>, RunError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
    fn deletes_sessions(&self) -> bool { ... }
    fn delete<'life0, 'life1, 'async_trait>(
        &'life0 self,
        agent_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<(), RunError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
}
Expand description

Where a hosted session’s PreparedRun comes from.

The same seam as prepare_with_session, at the host layer: a Rust process that already owns a mentra runtime — custom tools, its own store, a provider basis does not know — can serve it through an adapter instead of letting basis build one.

A source that builds its own runtime owns its tool authorizer, and an adapter that offers a mode picker replaces it for the sessions it serves: basis-acp installs PolicyGate on each live session, over whatever the runtime carries, because a read-only mode has to refuse where mentra treats the refusal as final. So the mode picker now works whatever a source’s runtime authorizer does — and a source with a stricter one of its own does not keep it for those sessions. A posture that must survive belongs in a RuntimeBuilder::with_interceptor guard, which runs ahead of the authorizer and is not replaceable per session. Installing ApprovalGate — what basis’s own source gets from the Runtime it builds — is still what a source wants for every other consumer of its runtime.

Required Methods§

Source

fn create<'life0, 'async_trait>( &'life0 self, cwd: PathBuf, mcp: Vec<McpServer>, ) -> Pin<Box<dyn Future<Output = Result<PreparedRun, RunError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Opens a conversation in cwd, for session/new, with the MCP servers the client configured for this session.

Provided Methods§

Source

fn resume<'life0, 'life1, 'async_trait>( &'life0 self, agent_id: &'life1 str, cwd: PathBuf, mcp: Vec<McpServer>, ) -> Pin<Box<dyn Future<Output = Result<PreparedRun, RunError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Picks up the conversation persisted under agent_id, for session/load. The default refuses, which is the honest answer for a source whose sessions do not outlive the process.

Source

fn lists_sessions(&self) -> bool

Whether this source can enumerate the conversations it has persisted.

session/list is advertised and answered only when this is true. A source that keeps no registry would otherwise report “no sessions” for a workspace that has some, and a capability that answers wrongly is worse than one that was never claimed — an unregistered method at least says so, with -32601.

Source

fn list_sessions<'life0, 'async_trait>( &'life0 self, cwd: PathBuf, ) -> Pin<Box<dyn Future<Output = Result<Vec<PersistedSession>, RunError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Every conversation persisted for cwd, most recently used first.

The order is the source’s to decide and is sent on unchanged: a list is read to find the conversation you were just in, and a source knows what “just” means for the store it keeps. basis’s own answers from store::list, which sorts by when a row was last written.

Only called when lists_sessions is true, so the default is unreachable rather than a claim about anything.

Source

fn deletes_sessions(&self) -> bool

Whether this source can remove a conversation for good.

Separate from lists_sessions because the two are separate promises: a source can perfectly well enumerate a store it has no authority to write to, and session/delete is advertised only on the strength of this one. The rule is the same either way — a capability that answers wrongly is worse than one never claimed.

Source

fn delete<'life0, 'life1, 'async_trait>( &'life0 self, agent_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(), RunError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Removes the conversation persisted under agent_id, for session/delete.

No cwd, unlike create and list_sessions, because session/delete sends none — and needs to send none: a store is indexed by conversation, so the id is the whole of what identifies one.

Only called when deletes_sessions is true. Deleting one that is not there must succeed: a client deletes by an id it read from a list, and “it is gone” is the outcome either way.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§