pub struct Session<T, S = Value> { /* private fields */ }Expand description
A conversation with an agent.
Holds the thread id, the messages both sides have said, and the application
state. S is the type the state deserializes into, and it is inferred from
whatever the caller does with an Update::State — a Session handed to a
function expecting Session<T, MyState>, or a match arm that keeps the
state in a typed local, needs no turbofish at all. Spell it only when
nothing else names it: Session::<_>::new(transport, thread) falls back to
the serde_json::Value default, and Session::<_, MyState>::new(…) pins
it by hand.
To stream updates, S must be Deserialize + Clone + Unpin — an
Update::State carries the state by value, so a view can hold it after
the run has moved on. #[derive(Clone, Deserialize)] on a plain struct is
all that takes.
Implementations§
Source§impl<T, S> Session<T, S>
impl<T, S> Session<T, S>
Sourcepub fn new(transport: T, thread_id: impl Into<ThreadId>) -> Selfwhere
T: Transport,
pub fn new(transport: T, thread_id: impl Into<ThreadId>) -> Selfwhere
T: Transport,
A new conversation over transport.
The T: Transport bound is checked here, at the construction site,
rather than on Session itself — so something that is not a transport
is an error on this line instead of on the first
send, which is usually in another file:
use ag_ui::client::Session;
// error[E0277]: the trait bound `str: Transport` is not satisfied,
// and the note lists the types that do implement it.
let session = Session::<_>::new("http://localhost:8080/agent", "thread-1");(A URL is the mistake worth catching: it is what a transport is made
from, so it reads plausible.) The bound stays off the struct because a
bound there is viral — every application helper naming Session<T, S>
would have to repeat it, including ones that only read
messages. tests/bounds.rs is what says so.
Sourcepub fn builder(
transport: T,
thread_id: impl Into<ThreadId>,
) -> SessionBuilder<T, S>where
T: Transport,
pub fn builder(
transport: T,
thread_id: impl Into<ThreadId>,
) -> SessionBuilder<T, S>where
T: Transport,
Sourcepub fn messages(&self) -> &[Message]
pub fn messages(&self) -> &[Message]
The assembled conversation, oldest first — everything the user sent and everything the agent has said across every run.
Sourcepub fn state(&self) -> Option<&S>
pub fn state(&self) -> Option<&S>
The application state in the caller’s type, once the agent has published one that deserializes.
Sourcepub fn raw_state(&self) -> &Value
pub fn raw_state(&self) -> &Value
The application state as raw JSON. Always current, even when the typed view is not.
Sourcepub fn reasoning(&self) -> &[ReasoningMessage]
pub fn reasoning(&self) -> &[ReasoningMessage]
The reasoning messages, kept out of the transcript.
Sourcepub fn interrupts(&self) -> &[Interrupt]
pub fn interrupts(&self) -> &[Interrupt]
What the agent is waiting for, if the last run paused.
Sourcepub fn subagents(&self) -> &[Subagent]
pub fn subagents(&self) -> &[Subagent]
The subagent invocations announced so far, across runs — a suspended one stays until the run that resumes it announces it again.
Sourcepub fn subagent(&self, run_id: &SubagentRunId) -> Option<&Subagent>
pub fn subagent(&self, run_id: &SubagentRunId) -> Option<&Subagent>
One subagent invocation by id — what a view does with the
Message::subagent_run_id on a message it is about to draw.
Sourcepub fn applier(&self) -> &Applier
pub fn applier(&self) -> &Applier
The applier underneath, for a view that wants the raw materialised state.
Sourcepub fn agent(&self) -> &RemoteAgent<T>
pub fn agent(&self) -> &RemoteAgent<T>
The low-level agent underneath.
Sourcepub fn push_message(&mut self, message: Message)
pub fn push_message(&mut self, message: Message)
Appends a message without starting a run — a tool result computed on the client, or history loaded from a store.
Sourcepub fn set_state(&mut self, state: impl Into<Value>)
pub fn set_state(&mut self, state: impl Into<Value>)
Replaces the state without going through the agent.
Sourcepub fn set_tools(&mut self, tools: impl Into<Vec<Tool>>)
pub fn set_tools(&mut self, tools: impl Into<Vec<Tool>>)
Offers a different set of tools from the next run on.
Sourcepub fn set_next_run_id(&mut self, run_id: impl Into<RunId>)
pub fn set_next_run_id(&mut self, run_id: impl Into<RunId>)
Names the next run explicitly, instead of the generated
{thread}-run-{n}.
Servers that key resumption on a run id need this; most do not.
Source§impl<T: Transport, S> Session<T, S>
impl<T: Transport, S> Session<T, S>
Sourcepub fn send(&mut self, text: impl Into<String>) -> RunStream<'_, T, S>
pub fn send(&mut self, text: impl Into<String>) -> RunStream<'_, T, S>
Sends the user’s turn and streams what the agent does about it.
The message is appended to the conversation before the request goes out,
so it is in Session::messages whatever happens to the run.
Sourcepub fn send_message(&mut self, message: Message) -> RunStream<'_, T, S>
pub fn send_message(&mut self, message: Message) -> RunStream<'_, T, S>
Sends a message of any role and streams the run.
Sourcepub fn run(&mut self) -> RunStream<'_, T, S>
pub fn run(&mut self) -> RunStream<'_, T, S>
Starts a run without adding anything — after pushing a tool result, or to let an agent continue on its own.
Sourcepub fn resume(
&mut self,
interrupt: &Interrupt,
payload: impl Into<Value>,
) -> RunStream<'_, T, S>
pub fn resume( &mut self, interrupt: &Interrupt, payload: impl Into<Value>, ) -> RunStream<'_, T, S>
Answers one interrupt and resumes the paused run.
The answer’s shape is up to the agent; when the interrupt carried a
responseSchema, payload should satisfy it.
Sourcepub fn cancel(&mut self, interrupt: &Interrupt) -> RunStream<'_, T, S>
pub fn cancel(&mut self, interrupt: &Interrupt) -> RunStream<'_, T, S>
Declines one interrupt and resumes the paused run.
Sourcepub fn resume_many(
&mut self,
entries: impl IntoIterator<Item = ResumeEntry>,
) -> RunStream<'_, T, S>
pub fn resume_many( &mut self, entries: impl IntoIterator<Item = ResumeEntry>, ) -> RunStream<'_, T, S>
Answers several interrupts at once — a run can pause on more than one.
Any interrupt left unanswered is dropped: the resumed run supersedes the
paused one, and the agent only sees what is in this request. Use
ResumeBuilder to answer them all.