pub struct Session { /* private fields */ }Expand description
Stateful multi-turn session manager.
Wraps a Codex client and automatically threads conversation state
across turns. On the first turn, an ExecCommand is used; on subsequent
turns, an ExecResumeCommand resumes the session using the thread_id
extracted from the JSONL event stream.
The thread_id is preserved even when a turn fails, as long as at least
one event in the output carried it.
§Example
use std::sync::Arc;
use codex_wrapper::{Codex, Session};
let codex = Arc::new(Codex::builder().build()?);
let mut session = Session::new(codex);
let events = session.send("summarize this repo").await?;
assert!(session.id().is_some());
assert_eq!(session.total_turns(), 1);
let events = session.send("now add more detail").await?;
assert_eq!(session.total_turns(), 2);Implementations§
Source§impl Session
impl Session
Sourcepub fn new(codex: Arc<Codex>) -> Self
pub fn new(codex: Arc<Codex>) -> Self
Create a new session with no prior state.
The first call to send will use ExecCommand.
Sourcepub fn resume(codex: Arc<Codex>, thread_id: impl Into<String>) -> Self
pub fn resume(codex: Arc<Codex>, thread_id: impl Into<String>) -> Self
Resume an existing session by its thread_id.
The next call to send will use
ExecResumeCommand with the provided ID.
Sourcepub fn with_budget(self, budget: TokenBudget) -> Self
pub fn with_budget(self, budget: TokenBudget) -> Self
Attach a TokenBudget.
Every turn’s reported usage is added to it, and each turn is refused
with Error::TokenBudgetExceeded once the ceiling is reached. The
check happens before a turn starts, so the ceiling can be overshot by
at most the turn that crosses it: usage is only known once spent.
The budget is Clone over shared state, so one can span several
sessions.
use std::sync::Arc;
use codex_wrapper::{Codex, Session, TokenBudget};
let codex = Arc::new(Codex::builder().build()?);
let budget = TokenBudget::builder().max_tokens(200_000).build();
let session = Session::new(codex).with_budget(budget.clone());Sourcepub fn budget(&self) -> Option<&TokenBudget>
pub fn budget(&self) -> Option<&TokenBudget>
The attached budget, if any.
Sourcepub async fn send(
&mut self,
prompt: impl Into<String>,
) -> Result<Vec<JsonLineEvent>>
pub async fn send( &mut self, prompt: impl Into<String>, ) -> Result<Vec<JsonLineEvent>>
Send a prompt, automatically routing to exec or exec resume.
On the first turn (no thread_id), dispatches via ExecCommand.
On subsequent turns, dispatches via ExecResumeCommand with the
captured thread_id.
Returns the parsed JSONL events for this turn.
Sourcepub async fn execute(&mut self, cmd: ExecCommand) -> Result<Vec<JsonLineEvent>>
pub async fn execute(&mut self, cmd: ExecCommand) -> Result<Vec<JsonLineEvent>>
Execute an ExecCommand with full control over its options.
Use this when you need to configure model, sandbox, approval policy,
or other flags beyond what send provides.
The session still captures the thread_id from the output.
Sourcepub async fn execute_resume(
&mut self,
cmd: ExecResumeCommand,
) -> Result<Vec<JsonLineEvent>>
pub async fn execute_resume( &mut self, cmd: ExecResumeCommand, ) -> Result<Vec<JsonLineEvent>>
Execute an ExecResumeCommand with full control over its options.
Use this when you need to configure flags on the resume command
beyond what send provides.
The session still captures the thread_id from the output.
Sourcepub async fn stream<F>(
&mut self,
prompt: impl Into<String>,
handler: F,
) -> Result<Vec<JsonLineEvent>>where
F: FnMut(JsonLineEvent),
pub async fn stream<F>(
&mut self,
prompt: impl Into<String>,
handler: F,
) -> Result<Vec<JsonLineEvent>>where
F: FnMut(JsonLineEvent),
Send a prompt, streaming events to handler as they arrive.
The streaming equivalent of send: routes to exec
or exec resume the same way, and leaves the session in the same
state. Events are handed to handler as the CLI emits them and are
also retained, so thread_id, history, and cost are captured exactly
as they would be on the buffered path.
Returns the full event stream for the turn.
use std::sync::Arc;
use codex_wrapper::{Codex, Session};
let codex = Arc::new(Codex::builder().build()?);
let mut session = Session::new(codex);
session
.stream("summarize this repo", |event| {
println!("{}", event.event_type);
})
.await?;
assert_eq!(session.total_turns(), 1);Sourcepub async fn stream_execute<F>(
&mut self,
cmd: ExecCommand,
handler: F,
) -> Result<Vec<JsonLineEvent>>where
F: FnMut(JsonLineEvent),
pub async fn stream_execute<F>(
&mut self,
cmd: ExecCommand,
handler: F,
) -> Result<Vec<JsonLineEvent>>where
F: FnMut(JsonLineEvent),
Stream an ExecCommand with full control over its options.
The streaming equivalent of execute.
Sourcepub async fn stream_execute_resume<F>(
&mut self,
cmd: ExecResumeCommand,
handler: F,
) -> Result<Vec<JsonLineEvent>>where
F: FnMut(JsonLineEvent),
pub async fn stream_execute_resume<F>(
&mut self,
cmd: ExecResumeCommand,
handler: F,
) -> Result<Vec<JsonLineEvent>>where
F: FnMut(JsonLineEvent),
Stream an ExecResumeCommand with full control over its options.
The streaming equivalent of execute_resume.
Sourcepub fn id(&self) -> Option<&str>
pub fn id(&self) -> Option<&str>
Returns the thread_id captured from the most recent turn, if any.
Sourcepub fn total_turns(&self) -> usize
pub fn total_turns(&self) -> usize
Total number of completed turns in this session.
Sourcepub fn history(&self) -> &[TurnRecord]
pub fn history(&self) -> &[TurnRecord]
Borrow the full turn history.
Sourcepub fn last_result(&self) -> Option<&QueryResult>
pub fn last_result(&self) -> Option<&QueryResult>
The typed result of the most recent completed turn.
Sourcepub fn total_tokens(&self) -> u64
pub fn total_tokens(&self) -> u64
Sum of the per-turn token totals the CLI reported.
Turns that reported no usage contribute nothing, so a total of 0 can
mean either “nothing was used” or “nothing was reported”. Pair this
with turns_missing_usage to tell those
apart.
There is no cost equivalent: the CLI reports tokens, not money. See
TokenUsage.
Sourcepub fn turns_missing_usage(&self) -> usize
pub fn turns_missing_usage(&self) -> usize
How many completed turns reported no usable token total.
Non-zero means total_tokens is an undercount
rather than a full accounting.