Skip to content

[codex-rs][experiment] New session crate to manage backgrounded codex execution #684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 45 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
314d221
codex draft
oai-ragona Apr 26, 2025
abf0198
progress
oai-ragona Apr 26, 2025
b41f26f
metadata
oai-ragona Apr 26, 2025
342ac71
use dot dir
oai-ragona Apr 26, 2025
9aaa947
numeric prefix
oai-ragona Apr 26, 2025
8f8479f
add repl subcommand
oai-ragona Apr 26, 2025
2aa7f42
fmt
oai-ragona Apr 26, 2025
63ec189
display kind
oai-ragona Apr 26, 2025
f2b7b14
draft of tui sock
oai-ragona Apr 26, 2025
1d0d725
draft broken
oai-ragona Apr 26, 2025
786c81d
draft still broken
oai-ragona Apr 26, 2025
9f10ec5
remove tui socket stuff
oai-ragona Apr 26, 2025
dab7b17
fmt
oai-ragona Apr 26, 2025
d0e8aa5
impl kill
oai-ragona Apr 26, 2025
a09be21
stdout tailing
oai-ragona Apr 26, 2025
6f0e4a5
tail
oai-ragona Apr 26, 2025
a7a8fa1
session validation
oai-ragona Apr 26, 2025
1e2983d
cleanup on failure
oai-ragona Apr 26, 2025
3d9ce18
fix for tail
oai-ragona Apr 26, 2025
d3b69e9
fmt
oai-ragona Apr 26, 2025
e782378
gate on windows
oai-ragona Apr 26, 2025
96d8d2a
save session metadata
oai-ragona Apr 26, 2025
3371647
fmt
oai-ragona Apr 26, 2025
f1c6625
shorten timestamp
oai-ragona Apr 26, 2025
07911dd
cleanup pass
oai-ragona Apr 26, 2025
8ed2704
in progress cleanup
oai-ragona Apr 26, 2025
2420a6a
clippy
oai-ragona Apr 26, 2025
2b55e5a
remove overcomments
oai-ragona Apr 26, 2025
56e609d
cleanup on clap args
oai-ragona Apr 26, 2025
a4197ec
truncate
oai-ragona Apr 26, 2025
ee51ffc
fmt
oai-ragona Apr 26, 2025
026990f
fmt
oai-ragona Apr 26, 2025
4d26c77
drop ascii art
oai-ragona Apr 26, 2025
8c672d5
cuter job names
oai-ragona Apr 27, 2025
359a09c
fmt
oai-ragona Apr 27, 2025
e96055b
move to_args closer to args
oai-ragona Apr 27, 2025
66a2e97
humansize
oai-ragona Apr 27, 2025
aef7f25
cleanup
oai-ragona Apr 27, 2025
0fbe5f2
cleanup
oai-ragona Apr 27, 2025
b344757
first pass at get
oai-ragona Apr 27, 2025
ffe7e22
artial, broken
oai-ragona Apr 27, 2025
c7596de
cleanup
oai-ragona Apr 27, 2025
34e849a
windows build cleanup
oai-ragona Apr 27, 2025
798364e
remove unused platform method
oai-ragona Apr 27, 2025
5b6224d
Merge branch 'main' into codex-rs-session
oai-ragona Apr 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
280 changes: 274 additions & 6 deletions codex-rs/Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions codex-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ members = [
"execpolicy",
"interactive",
"repl",
"session",
"tui",
]
6 changes: 4 additions & 2 deletions codex-rs/core/src/approval_mode_cli_arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use clap::ValueEnum;

use crate::protocol::AskForApproval;
use crate::protocol::SandboxPolicy;
use serde::Deserialize;
use serde::Serialize;

#[derive(Clone, Copy, Debug, ValueEnum)]
#[derive(Clone, Copy, Debug, ValueEnum, Serialize, Deserialize)]
#[value(rename_all = "kebab-case")]
pub enum ApprovalModeCliArg {
/// Run all commands without asking for user approval.
Expand All @@ -24,7 +26,7 @@ pub enum ApprovalModeCliArg {
Never,
}

#[derive(Clone, Copy, Debug, ValueEnum)]
#[derive(Clone, Copy, Debug, ValueEnum, Serialize, Deserialize)]
#[value(rename_all = "kebab-case")]
pub enum SandboxModeCliArg {
/// Network syscalls will be blocked
Expand Down
36 changes: 35 additions & 1 deletion codex-rs/exec/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use clap::Parser;
use codex_core::SandboxModeCliArg;
use std::path::PathBuf;

#[derive(Parser, Debug)]
/// Command-line interface for the non-interactive `codex-exec` agent.
///
#[derive(Parser, Debug, Clone)]
#[command(version)]
pub struct Cli {
/// Optional image(s) to attach to the initial prompt.
Expand Down Expand Up @@ -30,3 +32,35 @@ pub struct Cli {
/// Initial instructions for the agent.
pub prompt: Option<String>,
}

impl Cli {
/// This is effectively the opposite of Clap; we want the ability to take
/// a structured `Cli` object, and then pass it to a binary as argv[].
pub fn to_args(&self) -> Vec<String> {
let mut args = Vec::new();

for img in &self.images {
args.push("--image".into());
args.push(img.to_string_lossy().into_owned());
}

if let Some(model) = &self.model {
args.push("--model".into());
args.push(model.clone());
}

if self.skip_git_repo_check {
args.push("--skip-git-repo-check".into());
}

if self.disable_response_storage {
args.push("--disable-response-storage".into());
}

if let Some(prompt) = &self.prompt {
args.push(prompt.clone());
}

args
}
}
2 changes: 1 addition & 1 deletion codex-rs/interactive/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use codex_core::ApprovalModeCliArg;
use codex_core::SandboxModeCliArg;
use std::path::PathBuf;

#[derive(Parser, Debug)]
#[derive(Parser, Debug, Clone)]
#[command(version)]
pub struct Cli {
/// Optional image(s) to attach to the initial prompt.
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/repl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ tokio = { version = "1", features = [
"signal",
] }
tracing = { version = "0.1.41", features = ["log"] }
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
71 changes: 70 additions & 1 deletion codex-rs/repl/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use clap::ArgAction;
use clap::Parser;
use clap::ValueEnum;
use codex_core::ApprovalModeCliArg;
use codex_core::SandboxModeCliArg;
use std::path::PathBuf;

/// Command‑line arguments.
#[derive(Debug, Parser)]
/// Command-line interface for the interactive `codex-repl` agent.
#[derive(Debug, Parser, Clone)]
#[command(
author,
version,
Expand Down Expand Up @@ -62,3 +64,70 @@ pub struct Cli {
#[arg(short = 'E', long)]
pub record_events: Option<PathBuf>,
}

impl Cli {
/// This is effectively the opposite of Clap; we want the ability to take
/// a structured `Cli` object, and then pass it to a binary as argv[].
pub fn to_args(&self) -> Vec<String> {
let mut args = vec![];

if let Some(model) = &self.model {
args.push("--model".into());
args.push(model.clone());
}

for img in &self.images {
args.push("--image".into());
args.push(img.to_string_lossy().into_owned());
}

if self.no_ansi {
args.push("--no-ansi".into());
}

for _ in 0..self.verbose {
args.push("-v".into());
}

args.push("--ask-for-approval".into());
args.push(
self.approval_policy
.to_possible_value()
.expect("foo")
.get_name()
.to_string(),
);

args.push("--sandbox".into());
args.push(
self.sandbox_policy
.to_possible_value()
.expect("foo")
.get_name()
.to_string(),
);

if self.allow_no_git_exec {
args.push("--allow-no-git-exec".into());
}

if self.disable_response_storage {
args.push("--disable-response-storage".into());
}

if let Some(path) = &self.record_submissions {
args.push("--record-submissions".into());
args.push(path.to_string_lossy().into_owned());
}

if let Some(path) = &self.record_events {
args.push("--record-events".into());
args.push(path.to_string_lossy().into_owned());
}

if let Some(prompt) = &self.prompt {
args.push(prompt.clone());
}
args
}
}
56 changes: 56 additions & 0 deletions codex-rs/session/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[package]
name = "codex-session"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "codex-session"
path = "src/main.rs"

[lib]
name = "codex_session"
path = "src/lib.rs"

[dependencies]
anyhow = "1"
clap = { version = "4", features = ["derive"] }
codex-core = { path = "../core" }
tokio = { version = "1", features = [
"io-std",
"macros",
"process",
"rt-multi-thread",
"signal",
] }
tracing = { version = "0.1.41", features = ["log"] }
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
uuid = { version = "1", features = ["v4"] }
chrono = { version = "0.4", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
dirs = "6"
sysinfo = "0.29"
tabwriter = "1.3"
names = { version = "0.14", default-features = false }
nix = { version = "0.28", default-features = false, features = ["process", "signal", "term", "fs"] }
petname = "2.0.2"
rand = "0.9.1"

# Re-use the codex-exec library for its CLI definition
codex_exec = { package = "codex-exec", path = "../exec" }
codex_repl = { package = "codex-repl", path = "../repl" }
humansize = "2.1.3"
command-group = { version = "5.0.1", features = ["with-tokio"] }

[dev-dependencies]
tempfile = "3"

[target.'cfg(unix)'.dependencies]
libc = "0.2"

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.48", features = [
"Win32_Foundation",
"Win32_System_Console",
"Win32_System_Threading",
] }
18 changes: 18 additions & 0 deletions codex-rs/session/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// build.rs -- emit the current git commit so the code can embed it in the
// session metadata file.

fn main() {
// Try to run `git rev-parse HEAD` -- if that fails we fall back to
// "unknown" so the build does not break when the source is not a git
// repository (e.g., during `cargo publish`).
let git_sha = std::process::Command::new("git")
.args(["rev-parse", "HEAD"])
.output()
.ok()
.filter(|o| o.status.success())
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_owned())
.unwrap_or_else(|| "unknown".into());

println!("cargo:rustc-env=GIT_SHA={git_sha}");
}
9 changes: 9 additions & 0 deletions codex-rs/session/src/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//! Build-time information helpers (git commit hash, version, ...).

/// Return the git commit hash that was recorded at compile time via the
/// `build.rs` build-script. Falls back to the static string "unknown" when the
/// build script failed to determine the hash (e.g. when building from a
/// source tarball without the `.git` directory).
pub fn git_sha() -> &'static str {
env!("GIT_SHA")
}
Loading
Loading