diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..39df722 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,149 @@ +# CI: fmt, clippy, tests, MSRV, docs, cargo-deny and codegen drift. +# +# The private gate: every job has `if: ${{ !github.event.repository.private }}`. +# While the repo is private (where Actions minutes cost money) each job is +# skipped, and a skipped job uses no minutes. The day the repo is made public +# the condition turns true and the jobs run, with no further commit. + +name: CI + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +env: + CARGO_TERM_COLOR: always + # The toolchain the crate is developed against (ccwire's). + RUST_TOOLCHAIN: "1.98.1" + +jobs: + fmt: + name: rustfmt + if: ${{ !github.event.repository.private }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + # dtolnay/rust-toolchain master @ 2026-10-16; installs env.RUST_TOOLCHAIN (1.98.1) + - uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + components: rustfmt + - run: cargo fmt --all --check + + clippy: + name: clippy + if: ${{ !github.event.repository.private }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + # dtolnay/rust-toolchain master @ 2026-10-16; installs env.RUST_TOOLCHAIN (1.98.1) + - uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + components: clippy + - uses: Swatinem/rust-cache@v2 + - run: cargo clippy --all-targets -- -D warnings + + test: + name: test + if: ${{ !github.event.repository.private }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + # dtolnay/rust-toolchain master @ 2026-10-16; installs env.RUST_TOOLCHAIN (1.98.1) + - uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + - uses: Swatinem/rust-cache@v2 + # Includes tests/corpus.rs (recorded app-server output) and + # tests/spawn.rs (the fake codex, tests/fake_codex: python3, which the + # runner has). + - run: cargo test --all-targets --locked + # The README's example, compiled (lib.rs includes the README). + - run: cargo test --doc --locked + + check-codegen: + name: codegen drift + if: ${{ !github.event.repository.private }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + # dtolnay/rust-toolchain master @ 2026-10-16; installs env.RUST_TOOLCHAIN (1.98.1) + - uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + components: rustfmt + # Offline: regenerates src/protocol.rs from schema/ (python3 and + # rustfmt) and fails if it differs from the committed one. + - run: scripts/check-codegen + + msrv: + name: MSRV + if: ${{ !github.event.repository.private }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - name: Read rust-version from Cargo.toml + id: msrv + run: | + if grep -Eq '^rust-version\.workspace|^rust-version *= *\{' Cargo.toml; then + echo "::error::Cargo.toml inherits rust-version from a workspace; this repo needs an explicit rust-version = \"x.y\"" + exit 1 + fi + msrv=$(sed -n 's/^rust-version *= *"\(.*\)"/\1/p' Cargo.toml) + if [ -z "$msrv" ]; then + echo "::error::no rust-version = \"...\" in Cargo.toml" + exit 1 + fi + echo "MSRV: $msrv" + echo "version=$msrv" >> "$GITHUB_OUTPUT" + # Re-resolve Cargo.lock with a current cargo, whose rust-version-aware + # resolver (resolver 3, edition 2024) picks dependency versions that + # still build on the MSRV. + # dtolnay/rust-toolchain master @ 2026-10-16; installs env.RUST_TOOLCHAIN (1.98.1) + - uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + - run: cargo generate-lockfile + # dtolnay/rust-toolchain master @ 2026-10-16; installs the MSRV (rust-version) + - uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 + with: + toolchain: ${{ steps.msrv.outputs.version }} + - uses: Swatinem/rust-cache@v2 + - run: cargo +${{ steps.msrv.outputs.version }} build --locked + + doc: + name: docs + if: ${{ !github.event.repository.private }} + runs-on: ubuntu-latest + env: + RUSTDOCFLAGS: -D warnings + steps: + - uses: actions/checkout@v7 + # dtolnay/rust-toolchain master @ 2026-10-16; installs env.RUST_TOOLCHAIN (1.98.1) + - uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + - uses: Swatinem/rust-cache@v2 + - run: cargo doc --no-deps + + deny: + name: cargo-deny + if: ${{ !github.event.repository.private }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + # Licenses (permissive only), advisories, bans and sources: see + # deny.toml. + - uses: EmbarkStudios/cargo-deny-action@v2 + with: + command: check diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0efa7b8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,278 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "codexwire" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "tempfile", + "tokio", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "mio" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rustix" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5e76742e5294153d4dde1207dbec5bdd81eef6fabdc0d2118babadabfd858aa" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "tokio" +version = "1.54.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b52fd3255258d26fac7264ab5a76b53c13367136dc011d3d6ad4f8ed070396a3" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..caeb065 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "codexwire" +description = "A Rust client for the OpenAI Codex app-server: its JSON-RPC protocol, typed" +version = "0.1.0" +edition = "2024" +license = "Apache-2.0" +repository = "https://github.com/talaagent/codexwire" +authors = ["Ian Macalinao "] +rust-version = "1.85" +publish = false +keywords = ["codex", "openai", "agent", "json-rpc", "sdk"] +categories = ["api-bindings"] +# The schema and its generator stay in the repo: src/protocol.rs is what +# they make, committed. +exclude = ["schema", "scripts"] + +# Its own workspace, not a member of an enclosing one. +[workspace] + +[dependencies] +serde = { version = "1", features = ["derive"] } +serde_json = "1" +# The client: the child process and its stdio (process, io-util), the +# reader task and response channels (rt, sync), auth.json (fs). +tokio = { version = "1", default-features = false, features = [ + "fs", + "io-util", + "process", + "rt", + "sync", +] } + +[dev-dependencies] +tempfile = "3" +tokio = { version = "1", default-features = false, features = [ + "fs", + "io-util", + "process", + "rt", + "sync", + "macros", + "time", +] } + +[lints.clippy] +pedantic = { level = "warn", priority = -1 } +complexity = { level = "deny", priority = -1 } +must_use_candidate = "allow" +module_name_repetitions = "allow" +struct_excessive_bools = "allow" +unwrap_used = "deny" +std_instead_of_alloc = "deny" +std_instead_of_core = "deny" +cognitive_complexity = "deny" +too_many_lines = "deny" +clone_on_ref_ptr = "deny" +# No lock guard across an await; the blocking calls clippy.toml lists are +# off limits outside tests. +await_holding_lock = "deny" +disallowed_methods = "deny" +disallowed_types = "deny" diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..dc97475 --- /dev/null +++ b/NOTICE @@ -0,0 +1,12 @@ +codexwire +Copyright 2026 Ian Macalinao + +This product is licensed under the Apache License, Version 2.0 (see LICENSE). + +schema/codex_app_server_protocol.schemas.json is the app-server protocol +schema of OpenAI Codex (https://github.com/openai/codex), dumped with +`codex app-server generate-json-schema` from the version in schema/VERSION; +the types in src/protocol.rs, and their doc comments, are generated from it +(scripts/gen-codex-protocol). OpenAI Codex is Copyright 2025 OpenAI and +licensed under the Apache License, Version 2.0 +(https://github.com/openai/codex/blob/main/LICENSE). diff --git a/README.md b/README.md index 68939c0..a6819c5 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,79 @@ A Rust client for [OpenAI Codex](https://github.com/openai/codex)'s app-server: it runs `codex app-server` and speaks its JSON-RPC over the -child's stdio, with serde types generated from the app-server's JSON Schema -and pinned to one Codex version. The Codex counterpart to +child's stdio, the way Codex's IDE extensions do. The Codex counterpart to [ccwire](https://github.com/talaagent/ccwire). -Status: scaffold. The crate lands in the first PR. +Status: early. Checked against Codex 0.158.0 (`codexwire::CODEX_VERSION`). +Unix only (the child's process handling, `auth.json`'s file modes). + +- `codexwire::protocol`: serde types for the requests, responses, + notifications and server requests codexwire uses, generated from the + app-server's JSON Schema (`codex app-server generate-json-schema`) of the + pinned Codex. `Request` ties a params type to its method and response. +- `codexwire::rpc`: the JSON-RPC framing (one message a line). +- `codexwire::client`: `spawn_app_server` runs the child with an allowlisted + environment; `Client` writes requests and matches responses by id, and + hands the server's notifications and requests over a channel, in order. + A line that isn't JSON-RPC (or UTF-8) comes out as `Malformed` and the + connection goes on; once the server's output ends, every call fails + `Closed`. Calls have no timeout of their own: wrap them in + `tokio::time::timeout` (a dropped call forgets its request). + `redact` scrubs secrets out of its stderr. +- `codexwire::auth`: a session's private copy of `auth.json`, copied back + only if Codex refreshed it and the real one didn't change meanwhile. + +From `examples/initialize.rs`: + +```rust,no_run +use codexwire::client::{ServerMessage, spawn_app_server}; +use codexwire::protocol::{ClientInfo, InitializeParams}; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<(), Box> { + let mut server = spawn_app_server("codex", &[], &[], std::path::Path::new("."))?; + let init = server + .client + .request(&InitializeParams { + capabilities: None, + client_info: ClientInfo { + name: "example".into(), + title: None, + version: "0.1.0".into(), + }, + }) + .await?; + println!("codex: {}", init.user_agent); + server.client.notify("initialized", None).await?; + // thread/start, turn/start (protocol::{ThreadStartParams, TurnStartParams}), + // then read what the server sends: + while let Some(msg) = server.messages.recv().await { + if let ServerMessage::Notification { method, .. } = msg { + println!("{method}"); + } + } + Ok(()) +} +``` + +## The schema and its pin + +`schema/` holds the app-server schema and the Codex version it came from +(`schema/VERSION`); `src/protocol.rs` is generated from it and committed. + +- `scripts/gen-codex-protocol`: regenerate `src/protocol.rs` (offline). +- `scripts/gen-codex-protocol --refresh [CODEX]`: re-dump the schema from a + `codex` binary and move the pin to its version, then regenerate. +- `scripts/gen-codex-protocol --check [CODEX]`: fail unless the binary is + the pinned version. This checks the binary's version only, not the + generated code: that is `check-codegen`. +- `scripts/check-codegen`: fail if `src/protocol.rs` isn't what the schema + makes (CI runs it). + +A client can compare the server's version (`user_agent_version` of the +`initialize` response's `userAgent`) to `CODEX_VERSION`. ## License -Apache-2.0 (see LICENSE). +Apache-2.0 (see LICENSE). The schema is OpenAI Codex's, Apache-2.0 (see +NOTICE). diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..d21c3f3 --- /dev/null +++ b/clippy.toml @@ -0,0 +1,12 @@ +# Clippy config for CI, like ccwire's. Cargo.toml's [lints] deny unwrap_used +# and disallowed_methods; this allows unwrap in tests and lists the methods. +allow-unwrap-in-tests = true +disallowed-methods = [ + { path = "tokio::runtime::Runtime::block_on", reason = "await it; block_on only in tests and main" }, + { path = "tokio::runtime::Handle::block_on", reason = "await it; block_on only in tests and main" }, + { path = "std::thread::spawn", reason = "tokio::spawn (or spawn_blocking with a `// spawn_blocking:` reason)" }, + { path = "std::thread::sleep", reason = "tokio::time::sleep" }, + { path = "futures::executor::block_on", reason = "await it: one tokio runtime per binary" }, +] +# The README is the crate doc; "OpenAI" in its prose is a name, not code. +doc-valid-idents = ["OpenAI", ".."] diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..79a7bc0 --- /dev/null +++ b/deny.toml @@ -0,0 +1,54 @@ +# cargo-deny: `cargo deny check` (CI's `deny` job). +# https://embarkstudios.github.io/cargo-deny/ + +[graph] +all-features = true + +[advisories] +version = 2 +# Every RustSec advisory fails the check, unmaintained and unsound included; +# add an `ignore` entry (with a reason) only after reading the advisory. +unmaintained = "all" +yanked = "deny" +ignore = [] + +[licenses] +version = 2 +# Permissive licenses only. Anything not listed fails the check, so every +# copyleft license (GPL, LGPL, AGPL, MPL, EPL, ...) does. Add a license here +# only if it is permissive. +allow = [ + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "ISC", + "MIT", + "Unicode-3.0", + "Zlib", + "CC0-1.0", +] +confidence-threshold = 0.9 +# The list is the policy, not an inventory: no warning for an allowed +# license no dependency uses (yet). +unused-allowed-license = "allow" +exceptions = [] + +[licenses.private] +ignore = false + +[bans] +multiple-versions = "warn" +wildcards = "deny" +allow-wildcard-paths = false +highlight = "all" +deny = [] +skip = [] +skip-tree = [] + +[sources] +# crates.io only: no git dependencies, no other registries. +unknown-registry = "deny" +unknown-git = "deny" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] diff --git a/examples/initialize.rs b/examples/initialize.rs new file mode 100644 index 0000000..56607b6 --- /dev/null +++ b/examples/initialize.rs @@ -0,0 +1,33 @@ +//! Start `codex app-server`, initialize, and print what it sends. + +// `#[tokio::main]` expands to `block_on`: allowed in a main. +#![allow(clippy::disallowed_methods)] + +use codexwire::client::{ServerMessage, spawn_app_server}; +use codexwire::protocol::{ClientInfo, InitializeParams}; + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<(), Box> { + let mut server = spawn_app_server("codex", &[], &[], std::path::Path::new("."))?; + let init = server + .client + .request(&InitializeParams { + capabilities: None, + client_info: ClientInfo { + name: "example".into(), + title: None, + version: "0.1.0".into(), + }, + }) + .await?; + println!("codex: {}", init.user_agent); + server.client.notify("initialized", None).await?; + // thread/start, turn/start (protocol::{ThreadStartParams, TurnStartParams}), + // then read what the server sends: + while let Some(msg) = server.messages.recv().await { + if let ServerMessage::Notification { method, .. } = msg { + println!("{method}"); + } + } + Ok(()) +} diff --git a/schema/VERSION b/schema/VERSION new file mode 100644 index 0000000..4397dd1 --- /dev/null +++ b/schema/VERSION @@ -0,0 +1 @@ +0.158.0 diff --git a/schema/codex_app_server_protocol.schemas.json b/schema/codex_app_server_protocol.schemas.json new file mode 100644 index 0000000..94cfea4 --- /dev/null +++ b/schema/codex_app_server_protocol.schemas.json @@ -0,0 +1,26352 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AbsolutePathBuf": { + "description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.", + "type": "string" + }, + "AdditionalPermissionProfile": { + "properties": { + "fileSystem": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AdditionalFileSystemPermissions" + }, + { + "type": "null" + } + ] + }, + "network": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AdditionalNetworkPermissions" + }, + { + "type": "null" + } + ], + "description": "Partial overlay used for per-command permission requests." + } + }, + "type": "object" + }, + "ApplyPatchApprovalParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "callId": { + "description": "Use to correlate this with [codex_protocol::protocol::PatchApplyBeginEvent] and [codex_protocol::protocol::PatchApplyEndEvent].", + "type": "string" + }, + "conversationId": { + "$ref": "#/definitions/v2/ThreadId" + }, + "fileChanges": { + "additionalProperties": { + "$ref": "#/definitions/FileChange" + }, + "type": "object" + }, + "grantRoot": { + "description": "When set, the agent is asking the user to allow writes under this root for the remainder of the session (unclear if this is honored today).", + "type": [ + "string", + "null" + ] + }, + "reason": { + "description": "Optional explanatory reason (e.g. request for extra write access).", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "callId", + "conversationId", + "fileChanges" + ], + "title": "ApplyPatchApprovalParams", + "type": "object" + }, + "ApplyPatchApprovalResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "decision": { + "$ref": "#/definitions/ReviewDecision" + } + }, + "required": [ + "decision" + ], + "title": "ApplyPatchApprovalResponse", + "type": "object" + }, + "AttestationGenerateParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AttestationGenerateParams", + "type": "object" + }, + "AttestationGenerateResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "token": { + "description": "Opaque client attestation token.", + "type": "string" + } + }, + "required": [ + "token" + ], + "title": "AttestationGenerateResponse", + "type": "object" + }, + "ChatgptAuthTokensRefreshParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "previousAccountId": { + "description": "Workspace/account identifier that Codex was previously using.\n\nClients that manage multiple accounts/workspaces can use this as a hint to refresh the token for the correct workspace.\n\nThis may be `null` when the prior auth state did not include a workspace identifier (`chatgpt_account_id`).", + "type": [ + "string", + "null" + ] + }, + "reason": { + "$ref": "#/definitions/ChatgptAuthTokensRefreshReason" + } + }, + "required": [ + "reason" + ], + "title": "ChatgptAuthTokensRefreshParams", + "type": "object" + }, + "ChatgptAuthTokensRefreshReason": { + "oneOf": [ + { + "description": "Codex attempted a backend request and received `401 Unauthorized`.", + "enum": [ + "unauthorized" + ], + "type": "string" + } + ] + }, + "ChatgptAuthTokensRefreshResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "accessToken": { + "type": "string" + }, + "chatgptAccountId": { + "type": "string" + }, + "chatgptPlanType": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "accessToken", + "chatgptAccountId" + ], + "title": "ChatgptAuthTokensRefreshResponse", + "type": "object" + }, + "ClientInfo": { + "properties": { + "name": { + "type": "string" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "ClientNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "oneOf": [ + { + "properties": { + "method": { + "enum": [ + "initialized" + ], + "title": "InitializedNotificationMethod", + "type": "string" + } + }, + "required": [ + "method" + ], + "title": "InitializedNotification", + "type": "object" + } + ], + "title": "ClientNotification" + }, + "ClientRequest": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Request from the client to the server.", + "oneOf": [ + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "initialize" + ], + "title": "InitializeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/InitializeParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "InitializeRequest", + "type": "object" + }, + { + "description": "NEW APIs", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/start" + ], + "title": "Thread/startRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadStartParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/startRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/resume" + ], + "title": "Thread/resumeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadResumeParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/resumeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/fork" + ], + "title": "Thread/forkRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadForkParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/forkRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/archive" + ], + "title": "Thread/archiveRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadArchiveParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/archiveRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/delete" + ], + "title": "Thread/deleteRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadDeleteParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/deleteRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/unsubscribe" + ], + "title": "Thread/unsubscribeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadUnsubscribeParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/unsubscribeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/name/set" + ], + "title": "Thread/name/setRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadSetNameParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/name/setRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/goal/set" + ], + "title": "Thread/goal/setRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadGoalSetParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/goal/setRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/goal/get" + ], + "title": "Thread/goal/getRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadGoalGetParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/goal/getRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/goal/clear" + ], + "title": "Thread/goal/clearRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadGoalClearParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/goal/clearRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/metadata/update" + ], + "title": "Thread/metadata/updateRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadMetadataUpdateParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/metadata/updateRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/attachment/add" + ], + "title": "Thread/attachment/addRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadAttachmentAddParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/attachment/addRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/attachment/list" + ], + "title": "Thread/attachment/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadAttachmentListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/attachment/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/attachment/remove" + ], + "title": "Thread/attachment/removeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadAttachmentRemoveParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/attachment/removeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/section/move" + ], + "title": "Thread/section/moveRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadSectionMoveParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/section/moveRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/unarchive" + ], + "title": "Thread/unarchiveRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadUnarchiveParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/unarchiveRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/compact/start" + ], + "title": "Thread/compact/startRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadCompactStartParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/compact/startRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/shellCommand" + ], + "title": "Thread/shellCommandRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadShellCommandParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/shellCommandRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/approveGuardianDeniedAction" + ], + "title": "Thread/approveGuardianDeniedActionRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadApproveGuardianDeniedActionParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/approveGuardianDeniedActionRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/revert" + ], + "title": "Thread/revertRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRevertParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/revertRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/list" + ], + "title": "Thread/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "threadSection/list" + ], + "title": "ThreadSection/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadSectionListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ThreadSection/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "threadSection/create" + ], + "title": "ThreadSection/createRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadSectionCreateParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ThreadSection/createRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "threadSection/update" + ], + "title": "ThreadSection/updateRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadSectionUpdateParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ThreadSection/updateRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "threadSection/delete" + ], + "title": "ThreadSection/deleteRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadSectionDeleteParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ThreadSection/deleteRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/loaded/list" + ], + "title": "Thread/loaded/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadLoadedListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/loaded/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/read" + ], + "title": "Thread/readRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadReadParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/turns/list" + ], + "title": "Thread/turns/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadTurnsListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/turns/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/items/list" + ], + "title": "Thread/items/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadItemsListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/items/listRequest", + "type": "object" + }, + { + "description": "Append raw Responses API items to the thread history without starting a user turn.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "thread/inject_items" + ], + "title": "Thread/injectItemsRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadInjectItemsParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Thread/injectItemsRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "skills/list" + ], + "title": "Skills/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/SkillsListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Skills/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "skills/extraRoots/set" + ], + "title": "Skills/extraRoots/setRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/SkillsExtraRootsSetParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Skills/extraRoots/setRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "hooks/list" + ], + "title": "Hooks/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/HooksListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Hooks/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "marketplace/add" + ], + "title": "Marketplace/addRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/MarketplaceAddParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Marketplace/addRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "marketplace/remove" + ], + "title": "Marketplace/removeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/MarketplaceRemoveParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Marketplace/removeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "marketplace/upgrade" + ], + "title": "Marketplace/upgradeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/MarketplaceUpgradeParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Marketplace/upgradeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/list" + ], + "title": "Plugin/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/installed" + ], + "title": "Plugin/installedRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginInstalledParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/installedRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/reconcile" + ], + "title": "Plugin/reconcileRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginReconcileParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/reconcileRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/read" + ], + "title": "Plugin/readRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginReadParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/skill/read" + ], + "title": "Plugin/skill/readRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginSkillReadParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/skill/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/share/save" + ], + "title": "Plugin/share/saveRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginShareSaveParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/share/saveRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/share/updateTargets" + ], + "title": "Plugin/share/updateTargetsRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginShareUpdateTargetsParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/share/updateTargetsRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/share/list" + ], + "title": "Plugin/share/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginShareListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/share/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/share/checkout" + ], + "title": "Plugin/share/checkoutRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginShareCheckoutParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/share/checkoutRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/share/delete" + ], + "title": "Plugin/share/deleteRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginShareDeleteParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/share/deleteRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "app/read" + ], + "title": "App/readRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AppsReadParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "App/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "app/list" + ], + "title": "App/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AppsListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "App/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "app/installed" + ], + "title": "App/installedRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AppsInstalledParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "App/installedRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/readFile" + ], + "title": "Fs/readFileRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsReadFileParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/readFileRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/writeFile" + ], + "title": "Fs/writeFileRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsWriteFileParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/writeFileRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/createDirectory" + ], + "title": "Fs/createDirectoryRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsCreateDirectoryParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/createDirectoryRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/getMetadata" + ], + "title": "Fs/getMetadataRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsGetMetadataParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/getMetadataRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/readDirectory" + ], + "title": "Fs/readDirectoryRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsReadDirectoryParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/readDirectoryRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/remove" + ], + "title": "Fs/removeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsRemoveParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/removeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/copy" + ], + "title": "Fs/copyRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsCopyParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/copyRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/watch" + ], + "title": "Fs/watchRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsWatchParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/watchRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fs/unwatch" + ], + "title": "Fs/unwatchRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsUnwatchParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Fs/unwatchRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "skills/config/write" + ], + "title": "Skills/config/writeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/SkillsConfigWriteParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Skills/config/writeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/install" + ], + "title": "Plugin/installRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginInstallParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/installRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "plugin/uninstall" + ], + "title": "Plugin/uninstallRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PluginUninstallParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Plugin/uninstallRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "turn/start" + ], + "title": "Turn/startRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TurnStartParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Turn/startRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "turn/steer" + ], + "title": "Turn/steerRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TurnSteerParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Turn/steerRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "turn/interrupt" + ], + "title": "Turn/interruptRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TurnInterruptParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Turn/interruptRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "review/start" + ], + "title": "Review/startRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ReviewStartParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Review/startRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "model/list" + ], + "title": "Model/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ModelListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Model/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/gatewayOAuth/read" + ], + "title": "Account/gatewayOAuth/readRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "Account/gatewayOAuth/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/gatewayOAuth/login" + ], + "title": "Account/gatewayOAuth/loginRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "Account/gatewayOAuth/loginRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/gatewayOAuth/cancel" + ], + "title": "Account/gatewayOAuth/cancelRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "Account/gatewayOAuth/cancelRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "modelProvider/capabilities/read" + ], + "title": "ModelProvider/capabilities/readRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ModelProviderCapabilitiesReadParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ModelProvider/capabilities/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "experimentalFeature/list" + ], + "title": "ExperimentalFeature/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ExperimentalFeatureListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ExperimentalFeature/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "permissionProfile/list" + ], + "title": "PermissionProfile/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PermissionProfileListParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "PermissionProfile/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "experimentalFeature/enablement/set" + ], + "title": "ExperimentalFeature/enablement/setRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ExperimentalFeatureEnablementSetParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ExperimentalFeature/enablement/setRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "mcpServer/oauth/login" + ], + "title": "McpServer/oauth/loginRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpServerOauthLoginParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "McpServer/oauth/loginRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "config/mcpServer/reload" + ], + "title": "Config/mcpServer/reloadRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "Config/mcpServer/reloadRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "mcpServerStatus/list" + ], + "title": "McpServerStatus/listRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ListMcpServerStatusParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "McpServerStatus/listRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "mcpServer/resource/read" + ], + "title": "McpServer/resource/readRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpResourceReadParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "McpServer/resource/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "mcpServer/tool/call" + ], + "title": "McpServer/tool/callRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpServerToolCallParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "McpServer/tool/callRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "windowsSandbox/setupStart" + ], + "title": "WindowsSandbox/setupStartRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/WindowsSandboxSetupStartParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "WindowsSandbox/setupStartRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "windowsSandbox/readiness" + ], + "title": "WindowsSandbox/readinessRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "WindowsSandbox/readinessRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/login/start" + ], + "title": "Account/login/startRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/LoginAccountParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Account/login/startRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/login/cancel" + ], + "title": "Account/login/cancelRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CancelLoginAccountParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Account/login/cancelRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/logout" + ], + "title": "Account/logoutRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "Account/logoutRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/rateLimits/read" + ], + "title": "Account/rateLimits/readRequestMethod", + "type": "string" + }, + "params": { + "anyOf": [ + { + "$ref": "#/definitions/v2/GetAccountRateLimitsParams" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "id", + "method" + ], + "title": "Account/rateLimits/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/rateLimitResetCredit/consume" + ], + "title": "Account/rateLimitResetCredit/consumeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ConsumeAccountRateLimitResetCreditParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Account/rateLimitResetCredit/consumeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/usage/read" + ], + "title": "Account/usage/readRequestMethod", + "type": "string" + }, + "params": { + "anyOf": [ + { + "$ref": "#/definitions/v2/GetAccountTokenUsageParams" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "id", + "method" + ], + "title": "Account/usage/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/workspaceMessages/read" + ], + "title": "Account/workspaceMessages/readRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "Account/workspaceMessages/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/sendAddCreditsNudgeEmail" + ], + "title": "Account/sendAddCreditsNudgeEmailRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/SendAddCreditsNudgeEmailParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Account/sendAddCreditsNudgeEmailRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "feedback/upload" + ], + "title": "Feedback/uploadRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FeedbackUploadParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Feedback/uploadRequest", + "type": "object" + }, + { + "description": "Execute a standalone command (argv vector) under the server's sandbox.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "command/exec" + ], + "title": "Command/execRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CommandExecParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Command/execRequest", + "type": "object" + }, + { + "description": "Write stdin bytes to a running `command/exec` session or close stdin.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "command/exec/write" + ], + "title": "Command/exec/writeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CommandExecWriteParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Command/exec/writeRequest", + "type": "object" + }, + { + "description": "Terminate a running `command/exec` session by client-supplied `processId`.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "command/exec/terminate" + ], + "title": "Command/exec/terminateRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CommandExecTerminateParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Command/exec/terminateRequest", + "type": "object" + }, + { + "description": "Resize a running PTY-backed `command/exec` session by client-supplied `processId`.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "command/exec/resize" + ], + "title": "Command/exec/resizeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CommandExecResizeParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Command/exec/resizeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "config/read" + ], + "title": "Config/readRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ConfigReadParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Config/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "externalAgentConfig/detect" + ], + "title": "ExternalAgentConfig/detectRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ExternalAgentConfigDetectParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ExternalAgentConfig/detectRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "externalAgentConfig/import" + ], + "title": "ExternalAgentConfig/importRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ExternalAgentConfig/importRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "externalAgentConfig/import/recordHistory" + ], + "title": "ExternalAgentConfig/import/recordHistoryRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportHistoryRecordParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ExternalAgentConfig/import/recordHistoryRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "externalAgentConfig/import/readHistories" + ], + "title": "ExternalAgentConfig/import/readHistoriesRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "ExternalAgentConfig/import/readHistoriesRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "config/value/write" + ], + "title": "Config/value/writeRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ConfigValueWriteParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Config/value/writeRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "config/batchWrite" + ], + "title": "Config/batchWriteRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ConfigBatchWriteParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Config/batchWriteRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "configRequirements/read" + ], + "title": "ConfigRequirements/readRequestMethod", + "type": "string" + }, + "params": { + "type": "null" + } + }, + "required": [ + "id", + "method" + ], + "title": "ConfigRequirements/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/read" + ], + "title": "Account/readRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/GetAccountParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Account/readRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "fuzzyFileSearch" + ], + "title": "FuzzyFileSearchRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/FuzzyFileSearchParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "FuzzyFileSearchRequest", + "type": "object" + } + ], + "title": "ClientRequest" + }, + "CommandExecutionApprovalDecision": { + "oneOf": [ + { + "description": "User approved the command.", + "enum": [ + "accept" + ], + "type": "string" + }, + { + "description": "User approved the command and future prompts in the same session-scoped approval cache should run without prompting.", + "enum": [ + "acceptForSession" + ], + "type": "string" + }, + { + "additionalProperties": false, + "description": "User approved the command, and wants to apply the proposed execpolicy amendment so future matching commands can run without prompting.", + "properties": { + "acceptWithExecpolicyAmendment": { + "properties": { + "execpolicy_amendment": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "execpolicy_amendment" + ], + "type": "object" + } + }, + "required": [ + "acceptWithExecpolicyAmendment" + ], + "title": "AcceptWithExecpolicyAmendmentCommandExecutionApprovalDecision", + "type": "object" + }, + { + "additionalProperties": false, + "description": "User chose a persistent network policy rule (allow/deny) for this host.", + "properties": { + "applyNetworkPolicyAmendment": { + "properties": { + "network_policy_amendment": { + "$ref": "#/definitions/NetworkPolicyAmendment" + } + }, + "required": [ + "network_policy_amendment" + ], + "type": "object" + } + }, + "required": [ + "applyNetworkPolicyAmendment" + ], + "title": "ApplyNetworkPolicyAmendmentCommandExecutionApprovalDecision", + "type": "object" + }, + { + "description": "User denied the command. The agent will continue the turn.", + "enum": [ + "decline" + ], + "type": "string" + }, + { + "description": "User denied the command. The turn will also be immediately interrupted.", + "enum": [ + "cancel" + ], + "type": "string" + } + ] + }, + "CommandExecutionApprovalKind": { + "description": "Distinguishes a command approval from input sent to an existing terminal.", + "enum": [ + "command", + "writeStdin" + ], + "type": "string" + }, + "CommandExecutionRequestApprovalParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "approvalId": { + "description": "Unique identifier for this specific approval callback.\n\nFor regular shell/unified_exec approvals, this is null.\n\nFor zsh-exec-bridge subcommand approvals, multiple callbacks can belong to one parent `itemId`, so `approvalId` is a distinct opaque callback id (a UUID) used to disambiguate routing. Stdin approvals also use a distinct callback id; inspect `kind` to distinguish them.", + "type": [ + "string", + "null" + ] + }, + "command": { + "description": "The command to be executed.", + "type": [ + "string", + "null" + ] + }, + "commandActions": { + "description": "Best-effort parsed command actions for friendly display.", + "items": { + "$ref": "#/definitions/v2/CommandAction" + }, + "type": [ + "array", + "null" + ] + }, + "cwd": { + "anyOf": [ + { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + { + "type": "null" + } + ], + "description": "The command's working directory." + }, + "environmentId": { + "default": null, + "description": "Environment in which the command will run.", + "type": [ + "string", + "null" + ] + }, + "itemId": { + "type": "string" + }, + "kind": { + "allOf": [ + { + "$ref": "#/definitions/CommandExecutionApprovalKind" + } + ], + "default": "command", + "description": "Kind of action under review. Defaults to `command` for older servers." + }, + "networkApprovalContext": { + "anyOf": [ + { + "$ref": "#/definitions/NetworkApprovalContext" + }, + { + "type": "null" + } + ], + "description": "Optional context for a managed-network approval prompt." + }, + "proposedExecpolicyAmendment": { + "description": "Optional proposed execpolicy amendment to allow similar commands without prompting.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "proposedNetworkPolicyAmendments": { + "description": "Optional proposed network policy amendments (allow/deny host) for future requests.", + "items": { + "$ref": "#/definitions/NetworkPolicyAmendment" + }, + "type": [ + "array", + "null" + ] + }, + "reason": { + "description": "Optional explanatory reason (e.g. request for network access).", + "type": [ + "string", + "null" + ] + }, + "startedAtMs": { + "description": "Unix timestamp (in milliseconds) when this approval request started.", + "format": "int64", + "type": "integer" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "startedAtMs", + "threadId", + "turnId" + ], + "title": "CommandExecutionRequestApprovalParams", + "type": "object" + }, + "CommandExecutionRequestApprovalResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "decision": { + "$ref": "#/definitions/CommandExecutionApprovalDecision" + } + }, + "required": [ + "decision" + ], + "title": "CommandExecutionRequestApprovalResponse", + "type": "object" + }, + "DynamicToolCallParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "arguments": true, + "callId": { + "type": "string" + }, + "namespace": { + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + }, + "tool": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "arguments", + "callId", + "threadId", + "tool", + "turnId" + ], + "title": "DynamicToolCallParams", + "type": "object" + }, + "DynamicToolCallResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "contentItems": { + "items": { + "$ref": "#/definitions/v2/DynamicToolCallOutputContentItem" + }, + "type": "array" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "contentItems", + "success" + ], + "title": "DynamicToolCallResponse", + "type": "object" + }, + "ExecCommandApprovalParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "approvalId": { + "description": "Identifier for this specific approval callback.", + "type": [ + "string", + "null" + ] + }, + "callId": { + "description": "Use to correlate this with [codex_protocol::protocol::ExecCommandBeginEvent] and [codex_protocol::protocol::ExecCommandEndEvent].", + "type": "string" + }, + "command": { + "items": { + "type": "string" + }, + "type": "array" + }, + "conversationId": { + "$ref": "#/definitions/v2/ThreadId" + }, + "cwd": { + "type": "string" + }, + "parsedCmd": { + "items": { + "$ref": "#/definitions/ParsedCommand" + }, + "type": "array" + }, + "reason": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "callId", + "command", + "conversationId", + "cwd", + "parsedCmd" + ], + "title": "ExecCommandApprovalParams", + "type": "object" + }, + "ExecCommandApprovalResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "decision": { + "$ref": "#/definitions/ReviewDecision" + } + }, + "required": [ + "decision" + ], + "title": "ExecCommandApprovalResponse", + "type": "object" + }, + "FileChange": { + "oneOf": [ + { + "properties": { + "content": { + "type": "string" + }, + "type": { + "enum": [ + "add" + ], + "title": "AddFileChangeType", + "type": "string" + } + }, + "required": [ + "content", + "type" + ], + "title": "AddFileChange", + "type": "object" + }, + { + "properties": { + "content": { + "type": "string" + }, + "type": { + "enum": [ + "delete" + ], + "title": "DeleteFileChangeType", + "type": "string" + } + }, + "required": [ + "content", + "type" + ], + "title": "DeleteFileChange", + "type": "object" + }, + { + "properties": { + "move_path": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "update" + ], + "title": "UpdateFileChangeType", + "type": "string" + }, + "unified_diff": { + "type": "string" + } + }, + "required": [ + "type", + "unified_diff" + ], + "title": "UpdateFileChange", + "type": "object" + } + ] + }, + "FileChangeApprovalDecision": { + "oneOf": [ + { + "description": "User approved the file changes.", + "enum": [ + "accept" + ], + "type": "string" + }, + { + "description": "User approved the file changes and future changes to the same files should run without prompting.", + "enum": [ + "acceptForSession" + ], + "type": "string" + }, + { + "description": "User denied the file changes. The agent will continue the turn.", + "enum": [ + "decline" + ], + "type": "string" + }, + { + "description": "User denied the file changes. The turn will also be immediately interrupted.", + "enum": [ + "cancel" + ], + "type": "string" + } + ] + }, + "FileChangeRequestApprovalParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "grantRoot": { + "description": "[UNSTABLE] When set, the agent is asking the user to allow writes under this root for the remainder of the session (unclear if this is honored today).", + "type": [ + "string", + "null" + ] + }, + "itemId": { + "type": "string" + }, + "reason": { + "description": "Optional explanatory reason (e.g. request for extra write access).", + "type": [ + "string", + "null" + ] + }, + "startedAtMs": { + "description": "Unix timestamp (in milliseconds) when this approval request started.", + "format": "int64", + "type": "integer" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "startedAtMs", + "threadId", + "turnId" + ], + "title": "FileChangeRequestApprovalParams", + "type": "object" + }, + "FileChangeRequestApprovalResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "decision": { + "$ref": "#/definitions/FileChangeApprovalDecision" + } + }, + "required": [ + "decision" + ], + "title": "FileChangeRequestApprovalResponse", + "type": "object" + }, + "FuzzyFileSearchMatchType": { + "enum": [ + "file", + "directory" + ], + "type": "string" + }, + "FuzzyFileSearchParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cancellationToken": { + "type": [ + "string", + "null" + ] + }, + "query": { + "type": "string" + }, + "roots": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "query", + "roots" + ], + "title": "FuzzyFileSearchParams", + "type": "object" + }, + "FuzzyFileSearchResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "files": { + "items": { + "$ref": "#/definitions/FuzzyFileSearchResult" + }, + "type": "array" + } + }, + "required": [ + "files" + ], + "title": "FuzzyFileSearchResponse", + "type": "object" + }, + "FuzzyFileSearchResult": { + "description": "Superset of [`codex_file_search::FileMatch`]", + "properties": { + "file_name": { + "type": "string" + }, + "indices": { + "items": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "type": [ + "array", + "null" + ] + }, + "match_type": { + "$ref": "#/definitions/FuzzyFileSearchMatchType" + }, + "path": { + "type": "string" + }, + "root": { + "type": "string" + }, + "score": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + } + }, + "required": [ + "file_name", + "match_type", + "path", + "root", + "score" + ], + "type": "object" + }, + "FuzzyFileSearchSessionCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "sessionId": { + "type": "string" + } + }, + "required": [ + "sessionId" + ], + "title": "FuzzyFileSearchSessionCompletedNotification", + "type": "object" + }, + "FuzzyFileSearchSessionUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "files": { + "items": { + "$ref": "#/definitions/FuzzyFileSearchResult" + }, + "type": "array" + }, + "query": { + "type": "string" + }, + "sessionId": { + "type": "string" + } + }, + "required": [ + "files", + "query", + "sessionId" + ], + "title": "FuzzyFileSearchSessionUpdatedNotification", + "type": "object" + }, + "GrantedPermissionProfile": { + "properties": { + "fileSystem": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AdditionalFileSystemPermissions" + }, + { + "type": "null" + } + ] + }, + "network": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AdditionalNetworkPermissions" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "InitializeCapabilities": { + "description": "Client-declared capabilities negotiated during initialize.", + "properties": { + "experimentalApi": { + "default": false, + "description": "Opt into receiving experimental API methods and fields.", + "type": "boolean" + }, + "explicitGatewayOauth": { + "description": "Use explicit gateway OAuth login instead of automatic browser authorization. Applies to this app-server's gateway runtime; later connections cannot undo it.", + "type": "boolean" + }, + "extensions": { + "additionalProperties": true, + "description": "MCP extension settings declared by the app-server client.", + "type": [ + "object", + "null" + ] + }, + "mcpServerOpenaiFormElicitation": { + "description": "Legacy opt-in for the `openai/form` MCP extension.\n\nNew clients should declare `openai/form` in [`Self::extensions`].", + "type": "boolean" + }, + "optOutNotificationMethods": { + "description": "Exact notification method names that should be suppressed for this connection (for example `thread/started`).", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "requestAttestation": { + "default": false, + "description": "Opt into `attestation/generate` requests for upstream `x-oai-attestation`.", + "type": "boolean" + } + }, + "type": "object" + }, + "InitializeParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "capabilities": { + "anyOf": [ + { + "$ref": "#/definitions/InitializeCapabilities" + }, + { + "type": "null" + } + ] + }, + "clientInfo": { + "$ref": "#/definitions/ClientInfo" + } + }, + "required": [ + "clientInfo" + ], + "title": "InitializeParams", + "type": "object" + }, + "InitializeResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "codexHome": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute path to the server's $CODEX_HOME directory." + }, + "platformFamily": { + "description": "Platform family for the running app-server target, for example `\"unix\"` or `\"windows\"`.", + "type": "string" + }, + "platformOs": { + "description": "Operating system for the running app-server target, for example `\"macos\"`, `\"linux\"`, or `\"windows\"`.", + "type": "string" + }, + "userAgent": { + "type": "string" + } + }, + "required": [ + "codexHome", + "platformFamily", + "platformOs", + "userAgent" + ], + "title": "InitializeResponse", + "type": "object" + }, + "JSONRPCError": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "A response to a request that indicates an error occurred.", + "properties": { + "error": { + "$ref": "#/definitions/JSONRPCErrorError" + }, + "id": { + "$ref": "#/definitions/v2/RequestId" + } + }, + "required": [ + "error", + "id" + ], + "title": "JSONRPCError", + "type": "object" + }, + "JSONRPCErrorError": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "code": { + "format": "int64", + "type": "integer" + }, + "data": true, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "title": "JSONRPCErrorError", + "type": "object" + }, + "JSONRPCMessage": { + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + { + "$ref": "#/definitions/JSONRPCRequest" + }, + { + "$ref": "#/definitions/JSONRPCNotification" + }, + { + "$ref": "#/definitions/JSONRPCResponse" + }, + { + "$ref": "#/definitions/JSONRPCError" + } + ], + "description": "Refers to any valid JSON-RPC object that can be decoded off the wire, or encoded to be sent.", + "title": "JSONRPCMessage" + }, + "JSONRPCNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "A notification which does not expect a response.", + "properties": { + "method": { + "type": "string" + }, + "params": true + }, + "required": [ + "method" + ], + "title": "JSONRPCNotification", + "type": "object" + }, + "JSONRPCRequest": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "A request that expects a response.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "type": "string" + }, + "params": true, + "trace": { + "anyOf": [ + { + "$ref": "#/definitions/W3cTraceContext" + }, + { + "type": "null" + } + ], + "description": "Optional W3C Trace Context for distributed tracing." + } + }, + "required": [ + "id", + "method" + ], + "title": "JSONRPCRequest", + "type": "object" + }, + "JSONRPCResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "A successful (non-error) response to a request.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "result": true + }, + "required": [ + "id", + "result" + ], + "title": "JSONRPCResponse", + "type": "object" + }, + "McpElicitationArrayType": { + "enum": [ + "array" + ], + "type": "string" + }, + "McpElicitationBooleanSchema": { + "additionalProperties": false, + "properties": { + "default": { + "type": [ + "boolean", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationBooleanType" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "McpElicitationBooleanType": { + "enum": [ + "boolean" + ], + "type": "string" + }, + "McpElicitationConstOption": { + "additionalProperties": false, + "properties": { + "const": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "const", + "title" + ], + "type": "object" + }, + "McpElicitationEnumSchema": { + "anyOf": [ + { + "$ref": "#/definitions/McpElicitationSingleSelectEnumSchema" + }, + { + "$ref": "#/definitions/McpElicitationMultiSelectEnumSchema" + }, + { + "$ref": "#/definitions/McpElicitationLegacyTitledEnumSchema" + } + ] + }, + "McpElicitationLegacyTitledEnumSchema": { + "additionalProperties": false, + "properties": { + "default": { + "type": [ + "string", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "enum": { + "items": { + "type": "string" + }, + "type": "array" + }, + "enumNames": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationStringType" + } + }, + "required": [ + "enum", + "type" + ], + "type": "object" + }, + "McpElicitationMultiSelectEnumSchema": { + "anyOf": [ + { + "$ref": "#/definitions/McpElicitationUntitledMultiSelectEnumSchema" + }, + { + "$ref": "#/definitions/McpElicitationTitledMultiSelectEnumSchema" + } + ] + }, + "McpElicitationNumberSchema": { + "additionalProperties": false, + "properties": { + "default": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "maximum": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "minimum": { + "format": "double", + "type": [ + "number", + "null" + ] + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationNumberType" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "McpElicitationNumberType": { + "enum": [ + "number", + "integer" + ], + "type": "string" + }, + "McpElicitationObjectType": { + "enum": [ + "object" + ], + "type": "string" + }, + "McpElicitationPrimitiveSchema": { + "anyOf": [ + { + "$ref": "#/definitions/McpElicitationEnumSchema" + }, + { + "$ref": "#/definitions/McpElicitationStringSchema" + }, + { + "$ref": "#/definitions/McpElicitationNumberSchema" + }, + { + "$ref": "#/definitions/McpElicitationBooleanSchema" + } + ] + }, + "McpElicitationSchema": { + "additionalProperties": false, + "description": "Typed form schema for MCP `elicitation/create` requests.\n\nThis matches the `requestedSchema` shape from the MCP 2025-11-25 `ElicitRequestFormParams` schema.", + "properties": { + "$schema": { + "type": [ + "string", + "null" + ] + }, + "properties": { + "additionalProperties": { + "$ref": "#/definitions/McpElicitationPrimitiveSchema" + }, + "type": "object" + }, + "required": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationObjectType" + } + }, + "required": [ + "properties", + "type" + ], + "type": "object" + }, + "McpElicitationSingleSelectEnumSchema": { + "anyOf": [ + { + "$ref": "#/definitions/McpElicitationUntitledSingleSelectEnumSchema" + }, + { + "$ref": "#/definitions/McpElicitationTitledSingleSelectEnumSchema" + } + ] + }, + "McpElicitationStringFormat": { + "enum": [ + "email", + "uri", + "date", + "date-time" + ], + "type": "string" + }, + "McpElicitationStringSchema": { + "additionalProperties": false, + "properties": { + "default": { + "type": [ + "string", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "format": { + "anyOf": [ + { + "$ref": "#/definitions/McpElicitationStringFormat" + }, + { + "type": "null" + } + ] + }, + "maxLength": { + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "minLength": { + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationStringType" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "McpElicitationStringType": { + "enum": [ + "string" + ], + "type": "string" + }, + "McpElicitationTitledEnumItems": { + "additionalProperties": false, + "properties": { + "anyOf": { + "items": { + "$ref": "#/definitions/McpElicitationConstOption" + }, + "type": "array" + } + }, + "required": [ + "anyOf" + ], + "type": "object" + }, + "McpElicitationTitledMultiSelectEnumSchema": { + "additionalProperties": false, + "properties": { + "default": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "items": { + "$ref": "#/definitions/McpElicitationTitledEnumItems" + }, + "maxItems": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "minItems": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationArrayType" + } + }, + "required": [ + "items", + "type" + ], + "type": "object" + }, + "McpElicitationTitledSingleSelectEnumSchema": { + "additionalProperties": false, + "properties": { + "default": { + "type": [ + "string", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "oneOf": { + "items": { + "$ref": "#/definitions/McpElicitationConstOption" + }, + "type": "array" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationStringType" + } + }, + "required": [ + "oneOf", + "type" + ], + "type": "object" + }, + "McpElicitationUntitledEnumItems": { + "additionalProperties": false, + "properties": { + "enum": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "$ref": "#/definitions/McpElicitationStringType" + } + }, + "required": [ + "enum", + "type" + ], + "type": "object" + }, + "McpElicitationUntitledMultiSelectEnumSchema": { + "additionalProperties": false, + "properties": { + "default": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "items": { + "$ref": "#/definitions/McpElicitationUntitledEnumItems" + }, + "maxItems": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "minItems": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationArrayType" + } + }, + "required": [ + "items", + "type" + ], + "type": "object" + }, + "McpElicitationUntitledSingleSelectEnumSchema": { + "additionalProperties": false, + "properties": { + "default": { + "type": [ + "string", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "enum": { + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "type": { + "$ref": "#/definitions/McpElicitationStringType" + } + }, + "required": [ + "enum", + "type" + ], + "type": "object" + }, + "McpServerElicitationAction": { + "enum": [ + "accept", + "decline", + "cancel" + ], + "type": "string" + }, + "McpServerElicitationRequestParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "oneOf": [ + { + "properties": { + "_meta": true, + "message": { + "type": "string" + }, + "mode": { + "enum": [ + "form" + ], + "type": "string" + }, + "requestedSchema": { + "$ref": "#/definitions/McpElicitationSchema" + } + }, + "required": [ + "message", + "mode", + "requestedSchema" + ], + "type": "object" + }, + { + "properties": { + "_meta": true, + "message": { + "type": "string" + }, + "mode": { + "enum": [ + "openai/form" + ], + "type": "string" + }, + "requestedSchema": true + }, + "required": [ + "message", + "mode", + "requestedSchema" + ], + "type": "object" + }, + { + "properties": { + "_meta": true, + "message": { + "type": "string" + }, + "mode": { + "enum": [ + "openaiForm" + ], + "type": "string" + }, + "requestedSchema": true + }, + "required": [ + "message", + "mode", + "requestedSchema" + ], + "type": "object" + }, + { + "properties": { + "_meta": true, + "elicitationId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "mode": { + "enum": [ + "url" + ], + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "elicitationId", + "message", + "mode", + "url" + ], + "type": "object" + } + ], + "properties": { + "serverName": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "description": "Active Codex turn when this elicitation was observed, if app-server could correlate one.\n\nThis is nullable because MCP models elicitation as a standalone server-to-client request identified by the MCP server request id. It may be triggered during a turn, but turn context is app-server correlation rather than part of the protocol identity of the elicitation itself.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "serverName", + "threadId" + ], + "title": "McpServerElicitationRequestParams", + "type": "object" + }, + "McpServerElicitationRequestResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "_meta": { + "description": "Optional client metadata for form-mode action handling." + }, + "action": { + "$ref": "#/definitions/McpServerElicitationAction" + }, + "content": { + "description": "Structured user input for accepted elicitations, mirroring RMCP `CreateElicitationResult`.\n\nThis is nullable because decline/cancel responses have no content." + } + }, + "required": [ + "action" + ], + "title": "McpServerElicitationRequestResponse", + "type": "object" + }, + "NetworkApprovalContext": { + "properties": { + "host": { + "type": "string" + }, + "protocol": { + "$ref": "#/definitions/v2/NetworkApprovalProtocol" + } + }, + "required": [ + "host", + "protocol" + ], + "type": "object" + }, + "NetworkPolicyAmendment": { + "properties": { + "action": { + "$ref": "#/definitions/NetworkPolicyRuleAction" + }, + "host": { + "type": "string" + } + }, + "required": [ + "action", + "host" + ], + "type": "object" + }, + "NetworkPolicyRuleAction": { + "enum": [ + "allow", + "deny" + ], + "type": "string" + }, + "ParsedCommand": { + "oneOf": [ + { + "properties": { + "cmd": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "description": "(Best effort) Path to the file being read by the command. When possible, this is an absolute path, though when relative, it should be resolved against the `cwd`` that will be used to run the command to derive the absolute path.", + "type": "string" + }, + "type": { + "enum": [ + "read" + ], + "title": "ReadParsedCommandType", + "type": "string" + } + }, + "required": [ + "cmd", + "name", + "path", + "type" + ], + "title": "ReadParsedCommand", + "type": "object" + }, + { + "properties": { + "cmd": { + "type": "string" + }, + "path": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "list_files" + ], + "title": "ListFilesParsedCommandType", + "type": "string" + } + }, + "required": [ + "cmd", + "type" + ], + "title": "ListFilesParsedCommand", + "type": "object" + }, + { + "properties": { + "cmd": { + "type": "string" + }, + "path": { + "type": [ + "string", + "null" + ] + }, + "query": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "search" + ], + "title": "SearchParsedCommandType", + "type": "string" + } + }, + "required": [ + "cmd", + "type" + ], + "title": "SearchParsedCommand", + "type": "object" + }, + { + "properties": { + "cmd": { + "type": "string" + }, + "type": { + "enum": [ + "unknown" + ], + "title": "UnknownParsedCommandType", + "type": "string" + } + }, + "required": [ + "cmd", + "type" + ], + "title": "UnknownParsedCommand", + "type": "object" + } + ] + }, + "PermissionGrantScope": { + "enum": [ + "turn", + "session" + ], + "type": "string" + }, + "PermissionsRequestApprovalParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cwd": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "environmentId": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "itemId": { + "type": "string" + }, + "permissions": { + "$ref": "#/definitions/v2/RequestPermissionProfile" + }, + "reason": { + "type": [ + "string", + "null" + ] + }, + "startedAtMs": { + "description": "Unix timestamp (in milliseconds) when this approval request started.", + "format": "int64", + "type": "integer" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "cwd", + "itemId", + "permissions", + "startedAtMs", + "threadId", + "turnId" + ], + "title": "PermissionsRequestApprovalParams", + "type": "object" + }, + "PermissionsRequestApprovalResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "permissions": { + "$ref": "#/definitions/GrantedPermissionProfile" + }, + "scope": { + "allOf": [ + { + "$ref": "#/definitions/PermissionGrantScope" + } + ], + "default": "turn" + }, + "strictAutoReview": { + "description": "Review every subsequent command in this turn before normal sandboxed execution.", + "type": [ + "boolean", + "null" + ] + } + }, + "required": [ + "permissions" + ], + "title": "PermissionsRequestApprovalResponse", + "type": "object" + }, + "RequestId": { + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + { + "type": "string" + }, + { + "format": "int64", + "type": "integer" + } + ], + "title": "RequestId" + }, + "ReviewDecision": { + "description": "User's decision in response to an ExecApprovalRequest.", + "oneOf": [ + { + "description": "User has approved this command and the agent should execute it.", + "enum": [ + "approved" + ], + "type": "string" + }, + { + "additionalProperties": false, + "description": "User has approved this command and wants to apply the proposed execpolicy amendment so future matching commands are permitted.", + "properties": { + "approved_execpolicy_amendment": { + "properties": { + "proposed_execpolicy_amendment": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "proposed_execpolicy_amendment" + ], + "type": "object" + } + }, + "required": [ + "approved_execpolicy_amendment" + ], + "title": "ApprovedExecpolicyAmendmentReviewDecision", + "type": "object" + }, + { + "description": "User has approved this request and wants future prompts in the same session-scoped approval cache to be automatically approved for the remainder of the session.", + "enum": [ + "approved_for_session" + ], + "type": "string" + }, + { + "description": "User has approved this MCP tool call and wants to amend its policy so matching future calls are automatically approved across sessions.", + "enum": [ + "approved_mcp_policy_amendment" + ], + "type": "string" + }, + { + "additionalProperties": false, + "description": "User chose to persist a network policy rule (allow/deny) for future requests to the same host.", + "properties": { + "network_policy_amendment": { + "properties": { + "network_policy_amendment": { + "$ref": "#/definitions/NetworkPolicyAmendment" + } + }, + "required": [ + "network_policy_amendment" + ], + "type": "object" + } + }, + "required": [ + "network_policy_amendment" + ], + "title": "NetworkPolicyAmendmentReviewDecision", + "type": "object" + }, + { + "additionalProperties": false, + "description": "User has denied this command and the agent should not execute it, but it should continue the session and try something else.", + "properties": { + "denied": { + "properties": { + "rejection": { + "type": "string" + } + }, + "required": [ + "rejection" + ], + "type": "object" + } + }, + "required": [ + "denied" + ], + "title": "DeniedReviewDecision", + "type": "object" + }, + { + "description": "Automatic approval review timed out before reaching a decision.", + "enum": [ + "timed_out" + ], + "type": "string" + }, + { + "description": "User has denied this command and the agent should not do anything until the user's next command.", + "enum": [ + "abort" + ], + "type": "string" + } + ] + }, + "ServerNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Notification sent from the server to the client.", + "oneOf": [ + { + "description": "NEW NOTIFICATIONS", + "properties": { + "method": { + "enum": [ + "error" + ], + "title": "ErrorNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ErrorNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "ErrorNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/started" + ], + "title": "Thread/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/status/changed" + ], + "title": "Thread/status/changedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadStatusChangedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/status/changedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/archived" + ], + "title": "Thread/archivedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadArchivedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/archivedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/deleted" + ], + "title": "Thread/deletedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadDeletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/deletedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/unarchived" + ], + "title": "Thread/unarchivedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadUnarchivedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/unarchivedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/closed" + ], + "title": "Thread/closedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadClosedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/closedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/reverted" + ], + "title": "Thread/revertedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRevertedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/revertedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "skills/changed" + ], + "title": "Skills/changedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/SkillsChangedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Skills/changedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/name/updated" + ], + "title": "Thread/name/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadNameUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/name/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/attachment/updated" + ], + "title": "Thread/attachment/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadAttachmentUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/attachment/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/goal/updated" + ], + "title": "Thread/goal/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadGoalUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/goal/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/goal/cleared" + ], + "title": "Thread/goal/clearedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadGoalClearedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/goal/clearedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/queue/changed" + ], + "title": "Thread/queue/changedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadQueueChangedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/queue/changedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "project/changed" + ], + "title": "Project/changedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ProjectChangedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Project/changedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/project/updated" + ], + "title": "Thread/project/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadProjectUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/project/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/environment/connected" + ], + "title": "Thread/environment/connectedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/EnvironmentConnectionNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/environment/connectedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/environment/disconnected" + ], + "title": "Thread/environment/disconnectedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/EnvironmentConnectionNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/environment/disconnectedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/settings/updated" + ], + "title": "Thread/settings/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadSettingsUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/settings/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/tokenUsage/updated" + ], + "title": "Thread/tokenUsage/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadTokenUsageUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/tokenUsage/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "turn/started" + ], + "title": "Turn/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TurnStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Turn/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "hook/started" + ], + "title": "Hook/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/HookStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Hook/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "turn/completed" + ], + "title": "Turn/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TurnCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Turn/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "hook/completed" + ], + "title": "Hook/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/HookCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Hook/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "turn/diff/updated" + ], + "title": "Turn/diff/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TurnDiffUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Turn/diff/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "turn/plan/updated" + ], + "title": "Turn/plan/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TurnPlanUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Turn/plan/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/started" + ], + "title": "Item/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ItemStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/autoApprovalReview/started" + ], + "title": "Item/autoApprovalReview/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ItemGuardianApprovalReviewStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/autoApprovalReview/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/autoApprovalReview/completed" + ], + "title": "Item/autoApprovalReview/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ItemGuardianApprovalReviewCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/autoApprovalReview/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "autoApprovalReview/strictReviewRequired" + ], + "title": "AutoApprovalReview/strictReviewRequiredNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/StrictReviewRequiredNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "AutoApprovalReview/strictReviewRequiredNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/completed" + ], + "title": "Item/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ItemCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/agentMessage/delta" + ], + "title": "Item/agentMessage/deltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AgentMessageDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/agentMessage/deltaNotification", + "type": "object" + }, + { + "description": "EXPERIMENTAL - proposed plan streaming deltas for plan items.", + "properties": { + "method": { + "enum": [ + "item/plan/delta" + ], + "title": "Item/plan/deltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/PlanDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/plan/deltaNotification", + "type": "object" + }, + { + "description": "Stream base64-encoded stdout/stderr chunks for a running `command/exec` session.", + "properties": { + "method": { + "enum": [ + "command/exec/outputDelta" + ], + "title": "Command/exec/outputDeltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CommandExecOutputDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Command/exec/outputDeltaNotification", + "type": "object" + }, + { + "description": "Stream base64-encoded stdout/stderr chunks for a running `process/spawn` session.", + "properties": { + "method": { + "enum": [ + "process/outputDelta" + ], + "title": "Process/outputDeltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ProcessOutputDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Process/outputDeltaNotification", + "type": "object" + }, + { + "description": "Final exit notification for a `process/spawn` session.", + "properties": { + "method": { + "enum": [ + "process/exited" + ], + "title": "Process/exitedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ProcessExitedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Process/exitedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/commandExecution/outputDelta" + ], + "title": "Item/commandExecution/outputDeltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/CommandExecutionOutputDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/commandExecution/outputDeltaNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/commandExecution/terminalInteraction" + ], + "title": "Item/commandExecution/terminalInteractionNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TerminalInteractionNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/commandExecution/terminalInteractionNotification", + "type": "object" + }, + { + "description": "Deprecated legacy apply_patch output stream notification.", + "properties": { + "method": { + "enum": [ + "item/fileChange/outputDelta" + ], + "title": "Item/fileChange/outputDeltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FileChangeOutputDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/fileChange/outputDeltaNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/fileChange/patchUpdated" + ], + "title": "Item/fileChange/patchUpdatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FileChangePatchUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/fileChange/patchUpdatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "serverRequest/resolved" + ], + "title": "ServerRequest/resolvedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ServerRequestResolvedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "ServerRequest/resolvedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/mcpToolCall/progress" + ], + "title": "Item/mcpToolCall/progressNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpToolCallProgressNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/mcpToolCall/progressNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "mcpServer/oauthLogin/completed" + ], + "title": "McpServer/oauthLogin/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpServerOauthLoginCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "McpServer/oauthLogin/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "mcpServer/startupStatus/updated" + ], + "title": "McpServer/startupStatus/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpServerStatusUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "McpServer/startupStatus/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "mcpServer/event/stream/notification" + ], + "title": "McpServer/event/stream/notificationNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/McpServerEventStreamNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "McpServer/event/stream/notificationNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "account/updated" + ], + "title": "Account/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AccountUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Account/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "account/gatewayOAuth/changed" + ], + "title": "Account/gatewayOAuth/changedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/GatewayOAuthChangedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Account/gatewayOAuth/changedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "account/rateLimits/updated" + ], + "title": "Account/rateLimits/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AccountRateLimitsUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Account/rateLimits/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "app/list/updated" + ], + "title": "App/list/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AppListUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "App/list/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "remoteControl/status/changed" + ], + "title": "RemoteControl/status/changedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/RemoteControlStatusChangedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "RemoteControl/status/changedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "externalAgentConfig/import/progress" + ], + "title": "ExternalAgentConfig/import/progressNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportProgressNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "ExternalAgentConfig/import/progressNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "externalAgentConfig/import/completed" + ], + "title": "ExternalAgentConfig/import/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "ExternalAgentConfig/import/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "fs/changed" + ], + "title": "Fs/changedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/FsChangedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Fs/changedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/reasoning/summaryTextDelta" + ], + "title": "Item/reasoning/summaryTextDeltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ReasoningSummaryTextDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/reasoning/summaryTextDeltaNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/reasoning/summaryPartAdded" + ], + "title": "Item/reasoning/summaryPartAddedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ReasoningSummaryPartAddedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/reasoning/summaryPartAddedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "item/reasoning/textDelta" + ], + "title": "Item/reasoning/textDeltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ReasoningTextDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Item/reasoning/textDeltaNotification", + "type": "object" + }, + { + "description": "Deprecated: Use `ContextCompaction` item type instead.", + "properties": { + "method": { + "enum": [ + "thread/compacted" + ], + "title": "Thread/compactedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ContextCompactedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/compactedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "model/rerouted" + ], + "title": "Model/reroutedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ModelReroutedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Model/reroutedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "model/verification" + ], + "title": "Model/verificationNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ModelVerificationNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Model/verificationNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "modelProvider/authRecoveryStarted" + ], + "title": "ModelProvider/authRecoveryStartedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AuthRecoveryNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "ModelProvider/authRecoveryStartedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "modelProvider/authRecoveryCompleted" + ], + "title": "ModelProvider/authRecoveryCompletedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AuthRecoveryNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "ModelProvider/authRecoveryCompletedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "turn/moderationMetadata" + ], + "title": "Turn/moderationMetadataNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/TurnModerationMetadataNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Turn/moderationMetadataNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "model/safetyBuffering/updated" + ], + "title": "Model/safetyBuffering/updatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ModelSafetyBufferingUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Model/safetyBuffering/updatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "warning" + ], + "title": "WarningNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/WarningNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "WarningNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "guardianWarning" + ], + "title": "GuardianWarningNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/GuardianWarningNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "GuardianWarningNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "deprecationNotice" + ], + "title": "DeprecationNoticeNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/DeprecationNoticeNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "DeprecationNoticeNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "configWarning" + ], + "title": "ConfigWarningNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ConfigWarningNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "ConfigWarningNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "fuzzyFileSearch/sessionUpdated" + ], + "title": "FuzzyFileSearch/sessionUpdatedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/FuzzyFileSearchSessionUpdatedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "FuzzyFileSearch/sessionUpdatedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "fuzzyFileSearch/sessionCompleted" + ], + "title": "FuzzyFileSearch/sessionCompletedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/FuzzyFileSearchSessionCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "FuzzyFileSearch/sessionCompletedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/started" + ], + "title": "Thread/realtime/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/itemAdded" + ], + "title": "Thread/realtime/itemAddedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeItemAddedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/itemAddedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/item/started" + ], + "title": "Thread/realtime/item/startedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeItemStartedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/item/startedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/item/transcript/delta" + ], + "title": "Thread/realtime/item/transcript/deltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeItemTranscriptDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/item/transcript/deltaNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/item/completed" + ], + "title": "Thread/realtime/item/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeItemCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/item/completedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/transcript/delta" + ], + "title": "Thread/realtime/transcript/deltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeTranscriptDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/transcript/deltaNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/transcript/done" + ], + "title": "Thread/realtime/transcript/doneNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeTranscriptDoneNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/transcript/doneNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/outputAudio/delta" + ], + "title": "Thread/realtime/outputAudio/deltaNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeOutputAudioDeltaNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/outputAudio/deltaNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/sdp" + ], + "title": "Thread/realtime/sdpNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeSdpNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/sdpNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/error" + ], + "title": "Thread/realtime/errorNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeErrorNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/errorNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "thread/realtime/closed" + ], + "title": "Thread/realtime/closedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/ThreadRealtimeClosedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Thread/realtime/closedNotification", + "type": "object" + }, + { + "description": "Notifies the user of world-writable directories on Windows, which cannot be protected by the sandbox.", + "properties": { + "method": { + "enum": [ + "windows/worldWritableWarning" + ], + "title": "Windows/worldWritableWarningNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/WindowsWorldWritableWarningNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Windows/worldWritableWarningNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "windowsSandbox/setupCompleted" + ], + "title": "WindowsSandbox/setupCompletedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/WindowsSandboxSetupCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "WindowsSandbox/setupCompletedNotification", + "type": "object" + }, + { + "properties": { + "method": { + "enum": [ + "account/login/completed" + ], + "title": "Account/login/completedNotificationMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/v2/AccountLoginCompletedNotification" + } + }, + "required": [ + "method", + "params" + ], + "title": "Account/login/completedNotification", + "type": "object" + } + ], + "properties": { + "emittedAtMs": { + "description": "Unix timestamp (in milliseconds) when app-server emitted this notification.", + "format": "int64", + "type": "integer" + } + }, + "title": "ServerNotification" + }, + "ServerRequest": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Request initiated from the server and sent to the client.", + "oneOf": [ + { + "description": "NEW APIs Sent when approval is requested for a specific command execution. This request is used for Turns started via turn/start.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "item/commandExecution/requestApproval" + ], + "title": "Item/commandExecution/requestApprovalRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/CommandExecutionRequestApprovalParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Item/commandExecution/requestApprovalRequest", + "type": "object" + }, + { + "description": "Sent when approval is requested for a specific file change. This request is used for Turns started via turn/start.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "item/fileChange/requestApproval" + ], + "title": "Item/fileChange/requestApprovalRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/FileChangeRequestApprovalParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Item/fileChange/requestApprovalRequest", + "type": "object" + }, + { + "description": "EXPERIMENTAL - Request input from the user for a tool call.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "item/tool/requestUserInput" + ], + "title": "Item/tool/requestUserInputRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/ToolRequestUserInputParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Item/tool/requestUserInputRequest", + "type": "object" + }, + { + "description": "Request input for an MCP server elicitation.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "mcpServer/elicitation/request" + ], + "title": "McpServer/elicitation/requestRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/McpServerElicitationRequestParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "McpServer/elicitation/requestRequest", + "type": "object" + }, + { + "description": "Request approval for additional permissions from the user.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "item/permissions/requestApproval" + ], + "title": "Item/permissions/requestApprovalRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/PermissionsRequestApprovalParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Item/permissions/requestApprovalRequest", + "type": "object" + }, + { + "description": "Execute a dynamic tool call on the client.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "item/tool/call" + ], + "title": "Item/tool/callRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/DynamicToolCallParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Item/tool/callRequest", + "type": "object" + }, + { + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "account/chatgptAuthTokens/refresh" + ], + "title": "Account/chatgptAuthTokens/refreshRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/ChatgptAuthTokensRefreshParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Account/chatgptAuthTokens/refreshRequest", + "type": "object" + }, + { + "description": "Generate a fresh upstream attestation result on demand.", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "attestation/generate" + ], + "title": "Attestation/generateRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/AttestationGenerateParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "Attestation/generateRequest", + "type": "object" + }, + { + "description": "DEPRECATED APIs below Request to approve a patch. This request is used for Turns started via the legacy APIs (i.e. SendUserTurn, SendUserMessage).", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "applyPatchApproval" + ], + "title": "ApplyPatchApprovalRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/ApplyPatchApprovalParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ApplyPatchApprovalRequest", + "type": "object" + }, + { + "description": "Request to exec a command. This request is used for Turns started via the legacy APIs (i.e. SendUserTurn, SendUserMessage).", + "properties": { + "id": { + "$ref": "#/definitions/v2/RequestId" + }, + "method": { + "enum": [ + "execCommandApproval" + ], + "title": "ExecCommandApprovalRequestMethod", + "type": "string" + }, + "params": { + "$ref": "#/definitions/ExecCommandApprovalParams" + } + }, + "required": [ + "id", + "method", + "params" + ], + "title": "ExecCommandApprovalRequest", + "type": "object" + } + ], + "title": "ServerRequest" + }, + "ToolRequestUserInputAnswer": { + "description": "EXPERIMENTAL. Captures a user's answer to a request_user_input question.", + "properties": { + "answers": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "answers" + ], + "type": "object" + }, + "ToolRequestUserInputOption": { + "description": "EXPERIMENTAL. Defines a single selectable option for request_user_input.", + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": [ + "description", + "label" + ], + "type": "object" + }, + "ToolRequestUserInputParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL. Params sent with a request_user_input event.", + "properties": { + "autoResolutionMs": { + "default": null, + "description": "@deprecated Use `isBlocking` to decide whether the request should block.", + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "isBlocking": { + "type": "boolean" + }, + "itemId": { + "type": "string" + }, + "questions": { + "items": { + "$ref": "#/definitions/ToolRequestUserInputQuestion" + }, + "type": "array" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "isBlocking", + "itemId", + "questions", + "threadId", + "turnId" + ], + "title": "ToolRequestUserInputParams", + "type": "object" + }, + "ToolRequestUserInputQuestion": { + "description": "EXPERIMENTAL. Represents one request_user_input question and its required options.", + "properties": { + "header": { + "type": "string" + }, + "id": { + "type": "string" + }, + "isOther": { + "default": false, + "type": "boolean" + }, + "isSecret": { + "default": false, + "type": "boolean" + }, + "options": { + "items": { + "$ref": "#/definitions/ToolRequestUserInputOption" + }, + "type": [ + "array", + "null" + ] + }, + "question": { + "type": "string" + } + }, + "required": [ + "header", + "id", + "question" + ], + "type": "object" + }, + "ToolRequestUserInputResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL. Response payload mapping question ids to answers.", + "properties": { + "answers": { + "additionalProperties": { + "$ref": "#/definitions/ToolRequestUserInputAnswer" + }, + "type": "object" + } + }, + "required": [ + "answers" + ], + "title": "ToolRequestUserInputResponse", + "type": "object" + }, + "W3cTraceContext": { + "properties": { + "traceparent": { + "type": [ + "string", + "null" + ] + }, + "tracestate": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "v2": { + "AbsolutePathBuf": { + "description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.", + "type": "string" + }, + "Account": { + "oneOf": [ + { + "properties": { + "type": { + "enum": [ + "apiKey" + ], + "title": "ApiKeyAccountType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "ApiKeyAccount", + "type": "object" + }, + { + "properties": { + "email": { + "type": [ + "string", + "null" + ] + }, + "planType": { + "$ref": "#/definitions/v2/PlanType" + }, + "type": { + "enum": [ + "chatgpt" + ], + "title": "ChatgptAccountType", + "type": "string" + } + }, + "required": [ + "email", + "planType", + "type" + ], + "title": "ChatgptAccount", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockAccountType", + "type": "string" + }, + "usesCodexManagedCredentials": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "type" + ], + "title": "AmazonBedrockAccount", + "type": "object" + } + ] + }, + "AccountLoginCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "error": { + "type": [ + "string", + "null" + ] + }, + "loginId": { + "type": [ + "string", + "null" + ] + }, + "onboardingEntrypoint": { + "anyOf": [ + { + "$ref": "#/definitions/v2/DesktopOnboardingEntrypoint" + }, + { + "type": "null" + } + ] + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "success" + ], + "title": "AccountLoginCompletedNotification", + "type": "object" + }, + "AccountRateLimitsUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Sparse rolling rate-limit update.\n\nClients should merge available values into the most recent `account/rateLimits/read` response or refetch that snapshot. Nullable account metadata may be unavailable in a rolling update and does not clear a previously observed value.", + "properties": { + "rateLimits": { + "$ref": "#/definitions/v2/RateLimitSnapshot" + } + }, + "required": [ + "rateLimits" + ], + "title": "AccountRateLimitsUpdatedNotification", + "type": "object" + }, + "AccountRoutingOverride": { + "description": "Backend routing policy. Wire values match the accounts/check contract.", + "enum": [ + "NO_CONSTRAINT", + "us", + "us_cr" + ], + "type": "string" + }, + "AccountTokenUsageDailyBucket": { + "properties": { + "startDate": { + "type": "string" + }, + "tokens": { + "format": "int64", + "type": "integer" + } + }, + "required": [ + "startDate", + "tokens" + ], + "type": "object" + }, + "AccountTokenUsageSummary": { + "properties": { + "currentStreakDays": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "lifetimeTokens": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "longestRunningTurnSec": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "longestStreakDays": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "peakDailyTokens": { + "format": "int64", + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" + }, + "AccountUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "authMode": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AuthMode" + }, + { + "type": "null" + } + ] + }, + "planType": { + "anyOf": [ + { + "$ref": "#/definitions/v2/PlanType" + }, + { + "type": "null" + } + ] + } + }, + "title": "AccountUpdatedNotification", + "type": "object" + }, + "ActivePermissionProfile": { + "properties": { + "extends": { + "default": null, + "description": "Parent profile identifier from the selected permissions profile's `extends` setting, when present.", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Identifier from `default_permissions` or the implicit built-in default, such as `:workspace` or a user-defined `[permissions.]` profile.", + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "AddCreditsNudgeCreditType": { + "enum": [ + "credits", + "usage_limit" + ], + "type": "string" + }, + "AddCreditsNudgeEmailStatus": { + "enum": [ + "sent", + "cooldown_active" + ], + "type": "string" + }, + "AdditionalContextEntry": { + "properties": { + "kind": { + "$ref": "#/definitions/v2/AdditionalContextKind" + }, + "value": { + "type": "string" + } + }, + "required": [ + "kind", + "value" + ], + "type": "object" + }, + "AdditionalContextKind": { + "enum": [ + "untrusted", + "application" + ], + "type": "string" + }, + "AdditionalFileSystemPermissions": { + "properties": { + "entries": { + "items": { + "$ref": "#/definitions/v2/FileSystemSandboxEntry" + }, + "type": [ + "array", + "null" + ] + }, + "globScanMaxDepth": { + "format": "uint", + "minimum": 1.0, + "type": [ + "integer", + "null" + ] + }, + "read": { + "description": "This will be removed in favor of `entries`.", + "items": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": [ + "array", + "null" + ] + }, + "write": { + "description": "This will be removed in favor of `entries`.", + "items": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "AdditionalNetworkPermissions": { + "properties": { + "enabled": { + "type": [ + "boolean", + "null" + ] + } + }, + "type": "object" + }, + "AgentMessageDelivery": { + "enum": [ + "async" + ], + "type": "string" + }, + "AgentMessageDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "delta": { + "type": "string" + }, + "itemId": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "delta", + "itemId", + "threadId", + "turnId" + ], + "title": "AgentMessageDeltaNotification", + "type": "object" + }, + "AgentMessageInputContent": { + "oneOf": [ + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "enum": [ + "input_text" + ], + "title": "InputTextAgentMessageInputContentType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "InputTextAgentMessageInputContent", + "type": "object" + }, + { + "properties": { + "encrypted_content": { + "type": "string" + }, + "type": { + "enum": [ + "encrypted_content" + ], + "title": "EncryptedContentAgentMessageInputContentType", + "type": "string" + } + }, + "required": [ + "encrypted_content", + "type" + ], + "title": "EncryptedContentAgentMessageInputContent", + "type": "object" + } + ] + }, + "AgentPath": { + "type": "string" + }, + "AllowDenyRequirement": { + "enum": [ + "allow", + "deny" + ], + "type": "string" + }, + "AnalyticsConfig": { + "additionalProperties": true, + "properties": { + "enabled": { + "type": [ + "boolean", + "null" + ] + } + }, + "type": "object" + }, + "AppBranding": { + "description": "EXPERIMENTAL - app metadata returned by app-list APIs.", + "properties": { + "category": { + "type": [ + "string", + "null" + ] + }, + "developer": { + "type": [ + "string", + "null" + ] + }, + "isDiscoverableApp": { + "type": "boolean" + }, + "privacyPolicy": { + "type": [ + "string", + "null" + ] + }, + "termsOfService": { + "type": [ + "string", + "null" + ] + }, + "website": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "isDiscoverableApp" + ], + "type": "object" + }, + "AppConfig": { + "properties": { + "approvals_reviewer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + { + "type": "null" + } + ] + }, + "default_tools_approval_mode": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppToolApproval" + }, + { + "type": "null" + } + ] + }, + "default_tools_enabled": { + "type": [ + "boolean", + "null" + ] + }, + "destructive_enabled": { + "type": [ + "boolean", + "null" + ] + }, + "enabled": { + "default": true, + "type": "boolean" + }, + "links": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppLinksConfig" + }, + { + "type": "null" + } + ], + "description": "Per-account approval settings keyed by link ID." + }, + "omit_tools_from": { + "description": "Additional model-facing surfaces omitted for this connector's tools.", + "items": { + "$ref": "#/definitions/v2/ToolExposureSurface" + }, + "type": [ + "array", + "null" + ] + }, + "open_world_enabled": { + "type": [ + "boolean", + "null" + ] + }, + "tools": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppToolsConfig" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "AppInfo": { + "description": "EXPERIMENTAL - app metadata returned by app-list APIs.", + "properties": { + "appMetadata": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppMetadata" + }, + { + "type": "null" + } + ] + }, + "branding": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppBranding" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "distributionChannel": { + "type": [ + "string", + "null" + ] + }, + "iconAssets": { + "additionalProperties": { + "type": "string" + }, + "type": [ + "object", + "null" + ] + }, + "iconDarkAssets": { + "additionalProperties": { + "type": "string" + }, + "type": [ + "object", + "null" + ] + }, + "id": { + "type": "string" + }, + "installUrl": { + "type": [ + "string", + "null" + ] + }, + "isAccessible": { + "default": false, + "type": "boolean" + }, + "isEnabled": { + "default": true, + "description": "Whether this app is enabled in config.toml. Example: ```toml [apps.bad_app] enabled = false ```", + "type": "boolean" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "type": [ + "object", + "null" + ] + }, + "logoUrl": { + "type": [ + "string", + "null" + ] + }, + "logoUrlDark": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "pluginDisplayNames": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + }, + "AppLinkConfig": { + "description": "Approval settings for a connected account within an app.", + "properties": { + "approvals_reviewer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + { + "type": "null" + } + ] + }, + "default_tools_approval_mode": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppToolApproval" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "AppLinksConfig": { + "description": "Account settings for a single app.", + "type": "object" + }, + "AppListUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - notification emitted when the app list changes.", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/AppInfo" + }, + "type": "array" + } + }, + "required": [ + "data" + ], + "title": "AppListUpdatedNotification", + "type": "object" + }, + "AppMetadata": { + "properties": { + "categories": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "developer": { + "type": [ + "string", + "null" + ] + }, + "firstPartyRequiresInstall": { + "type": [ + "boolean", + "null" + ] + }, + "review": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppReview" + }, + { + "type": "null" + } + ] + }, + "screenshots": { + "items": { + "$ref": "#/definitions/v2/AppScreenshot" + }, + "type": [ + "array", + "null" + ] + }, + "seoDescription": { + "type": [ + "string", + "null" + ] + }, + "showInComposerWhenUnlinked": { + "type": [ + "boolean", + "null" + ] + }, + "subCategories": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "version": { + "type": [ + "string", + "null" + ] + }, + "versionId": { + "type": [ + "string", + "null" + ] + }, + "versionNotes": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "AppReview": { + "properties": { + "status": { + "type": "string" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "AppScreenshot": { + "properties": { + "fileId": { + "type": [ + "string", + "null" + ] + }, + "url": { + "type": [ + "string", + "null" + ] + }, + "userPrompt": { + "type": "string" + } + }, + "required": [ + "userPrompt" + ], + "type": "object" + }, + "AppSummary": { + "description": "EXPERIMENTAL - app metadata summary for plugin responses.", + "properties": { + "category": { + "type": [ + "string", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string" + }, + "installUrl": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + }, + "AppTemplateSummary": { + "properties": { + "canonicalConnectorId": { + "type": [ + "string", + "null" + ] + }, + "category": { + "type": [ + "string", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "logoUrl": { + "type": [ + "string", + "null" + ] + }, + "logoUrlDark": { + "type": [ + "string", + "null" + ] + }, + "materializedAppIds": { + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "type": "string" + }, + "reason": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppTemplateUnavailableReason" + }, + { + "type": "null" + } + ] + }, + "templateId": { + "type": "string" + } + }, + "required": [ + "materializedAppIds", + "name", + "templateId" + ], + "type": "object" + }, + "AppTemplateUnavailableReason": { + "enum": [ + "NOT_CONFIGURED_FOR_WORKSPACE", + "NO_ACTIVE_WORKSPACE" + ], + "type": "string" + }, + "AppToolApproval": { + "enum": [ + "auto", + "prompt", + "writes", + "approve" + ], + "type": "string" + }, + "AppToolConfig": { + "properties": { + "approval_mode": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppToolApproval" + }, + { + "type": "null" + } + ] + }, + "enabled": { + "type": [ + "boolean", + "null" + ] + } + }, + "type": "object" + }, + "AppToolSummary": { + "description": "EXPERIMENTAL - metadata returned by app/read.", + "properties": { + "description": { + "type": "string" + }, + "disabledReason": { + "type": [ + "string", + "null" + ] + }, + "isEnabled": { + "default": true, + "type": "boolean" + }, + "isReadOnly": { + "default": false, + "type": "boolean" + }, + "name": { + "type": "string" + }, + "title": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "description", + "name" + ], + "type": "object" + }, + "AppToolsConfig": { + "type": "object" + }, + "ApplicationNetworkRequirements": { + "properties": { + "domains": { + "additionalProperties": { + "$ref": "#/definitions/v2/NetworkDomainPermission" + }, + "type": "object" + }, + "enabled": { + "description": "When enabled, only explicitly allowed exact domains may be contacted.", + "type": "boolean" + } + }, + "required": [ + "domains", + "enabled" + ], + "type": "object" + }, + "ApplicationRequirements": { + "properties": { + "network": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApplicationNetworkRequirements" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "ApprovalsReviewer": { + "description": "Configures who approval requests are routed to for review. Examples include sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations. Defaults to `user`. `auto_review` uses a carefully prompted subagent to gather relevant context and apply a risk-based decision framework before approving or denying the request. The legacy value `guardian_subagent` is accepted for compatibility.", + "enum": [ + "user", + "auto_review", + "guardian_subagent" + ], + "type": "string" + }, + "AppsConfig": { + "properties": { + "_default": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppsDefaultConfig" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "AppsDefaultConfig": { + "properties": { + "approvals_reviewer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + { + "type": "null" + } + ] + }, + "default_tools_approval_mode": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AppToolApproval" + }, + { + "type": "null" + } + ] + }, + "destructive_enabled": { + "default": true, + "type": "boolean" + }, + "enabled": { + "default": true, + "type": "boolean" + }, + "open_world_enabled": { + "default": true, + "type": "boolean" + } + }, + "type": "object" + }, + "AppsInstalledParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Read the committed installed connector runtime snapshot.", + "properties": { + "forceRefresh": { + "description": "When true and Apps are permitted, refresh and publish the hosted connector runtime tool snapshot first.", + "type": "boolean" + }, + "threadId": { + "description": "Optional loaded thread id used to evaluate effective app configuration.", + "type": [ + "string", + "null" + ] + } + }, + "title": "AppsInstalledParams", + "type": "object" + }, + "AppsInstalledResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "The installed connectors in one committed runtime snapshot.", + "properties": { + "apps": { + "items": { + "$ref": "#/definitions/v2/InstalledApp" + }, + "type": "array" + } + }, + "required": [ + "apps" + ], + "title": "AppsInstalledResponse", + "type": "object" + }, + "AppsListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - list available apps/connectors.", + "properties": { + "cursor": { + "description": "Opaque pagination cursor returned by a previous call.", + "type": [ + "string", + "null" + ] + }, + "forceRefetch": { + "description": "When true, bypass app caches and fetch the latest data from sources.", + "type": "boolean" + }, + "limit": { + "description": "Optional page size; defaults to a reasonable server-side value.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "threadId": { + "description": "Optional thread id used to evaluate app feature gating from that thread's config.", + "type": [ + "string", + "null" + ] + } + }, + "title": "AppsListParams", + "type": "object" + }, + "AppsListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - app list response.", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/AppInfo" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item. If None, there are no more items to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "AppsListResponse", + "type": "object" + }, + "AppsReadParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - read metadata for specific apps/connectors.", + "properties": { + "appIds": { + "description": "App ids to read. The server accepts at most 100 ids and deduplicates repeated ids while preserving their first-request order.", + "items": { + "type": "string" + }, + "type": "array" + }, + "includeTools": { + "description": "When true, include display-only public tool summaries in the returned metadata.", + "type": "boolean" + }, + "threadId": { + "description": "Optional loaded thread id used to evaluate effective app configuration.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "appIds" + ], + "title": "AppsReadParams", + "type": "object" + }, + "AppsReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - app/read response.", + "properties": { + "apps": { + "items": { + "$ref": "#/definitions/v2/ConnectorMetadata" + }, + "type": "array" + }, + "missingAppIds": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "apps", + "missingAppIds" + ], + "title": "AppsReadResponse", + "type": "object" + }, + "AskForApproval": { + "oneOf": [ + { + "enum": [ + "untrusted", + "on-request", + "never" + ], + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "granular": { + "properties": { + "mcp_elicitations": { + "type": "boolean" + }, + "request_permissions": { + "default": false, + "type": "boolean" + }, + "rules": { + "type": "boolean" + }, + "sandbox_approval": { + "type": "boolean" + }, + "skill_approval": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "mcp_elicitations", + "rules", + "sandbox_approval" + ], + "type": "object" + } + }, + "required": [ + "granular" + ], + "title": "GranularAskForApproval", + "type": "object" + } + ] + }, + "AsyncUserInputQuestion": { + "additionalProperties": false, + "properties": { + "options": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "title": { + "type": "string" + } + }, + "required": [ + "title" + ], + "type": "object" + }, + "AuthMode": { + "description": "Authentication mode for OpenAI-backed providers.", + "oneOf": [ + { + "description": "OpenAI API key provided by the caller and stored by Codex.", + "enum": [ + "apikey" + ], + "type": "string" + }, + { + "description": "ChatGPT OAuth managed by Codex (tokens persisted and refreshed by Codex).", + "enum": [ + "chatgpt" + ], + "type": "string" + }, + { + "description": "[UNSTABLE] FOR OPENAI INTERNAL USE ONLY - DO NOT USE.\n\nChatGPT auth tokens are supplied by an external host app and are only stored in memory. Token refresh must be handled by the external host app.", + "enum": [ + "chatgptAuthTokens" + ], + "type": "string" + }, + { + "description": "Backend auth supplied as request headers.", + "enum": [ + "headers" + ], + "type": "string" + }, + { + "description": "Programmatic Codex auth backed by a registered Agent Identity.", + "enum": [ + "agentIdentity" + ], + "type": "string" + }, + { + "description": "Programmatic Codex auth backed by a personal access token.", + "enum": [ + "personalAccessToken" + ], + "type": "string" + }, + { + "description": "Amazon Bedrock bearer token managed by Codex.", + "enum": [ + "bedrockApiKey" + ], + "type": "string" + }, + { + "description": "Amazon Bedrock AWS access keys managed by Codex.", + "enum": [ + "bedrockAccessKeys" + ], + "type": "string" + } + ] + }, + "AuthRecoveryNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "message": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "message", + "provider", + "threadId", + "turnId" + ], + "title": "AuthRecoveryNotification", + "type": "object" + }, + "AutoCompactTokenLimitScope": { + "description": "Selects which part of the active context is charged against `model_auto_compact_token_limit`.", + "oneOf": [ + { + "description": "Count the full active context against the limit.", + "enum": [ + "total" + ], + "type": "string" + }, + { + "description": "Count sampled output and later growth after the carried window prefix.", + "enum": [ + "body_after_prefix" + ], + "type": "string" + } + ] + }, + "AutoReviewDecisionSource": { + "description": "[UNSTABLE] Source that produced a terminal approval auto-review decision.", + "enum": [ + "agent" + ], + "type": "string" + }, + "AutoReviewRequirements": { + "properties": { + "ignoreRules": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "requiredOnModels": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "BrowserUseAccessApprovalLifetime": { + "enum": [ + "turn", + "thread" + ], + "type": "string" + }, + "BrowserUseConfig": { + "properties": { + "allow_history_access": { + "type": [ + "boolean", + "null" + ] + }, + "default_origin_policy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/BrowserUseOriginPolicyConfig" + }, + { + "type": "null" + } + ] + }, + "origins": { + "additionalProperties": { + "$ref": "#/definitions/v2/BrowserUseOriginPolicyConfig" + }, + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "BrowserUseOriginPolicy": { + "properties": { + "access": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "accessApprovalLifetime": { + "anyOf": [ + { + "$ref": "#/definitions/v2/BrowserUseAccessApprovalLifetime" + }, + { + "type": "null" + } + ] + }, + "autoReview": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "downloads": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "fullCdpAccess": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "persistentApproval": { + "type": [ + "boolean", + "null" + ] + }, + "uploads": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "BrowserUseOriginPolicyConfig": { + "properties": { + "access": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "downloads": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "full_cdp_access": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "uploads": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "BrowserUseRequirements": { + "properties": { + "allowGlobalPersistentApproval": { + "type": [ + "boolean", + "null" + ] + }, + "allowHistoryAccess": { + "type": [ + "boolean", + "null" + ] + }, + "allowWebmcp": { + "type": [ + "boolean", + "null" + ] + }, + "defaultOriginPolicy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/BrowserUseOriginPolicy" + }, + { + "type": "null" + } + ] + }, + "disableAutoReview": { + "type": [ + "boolean", + "null" + ] + }, + "origins": { + "additionalProperties": { + "$ref": "#/definitions/v2/BrowserUseOriginPolicy" + }, + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "ByteRange": { + "properties": { + "end": { + "format": "uint", + "minimum": 0.0, + "type": "integer" + }, + "start": { + "format": "uint", + "minimum": 0.0, + "type": "integer" + } + }, + "required": [ + "end", + "start" + ], + "type": "object" + }, + "CancelLoginAccountParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "loginId": { + "type": "string" + } + }, + "required": [ + "loginId" + ], + "title": "CancelLoginAccountParams", + "type": "object" + }, + "CancelLoginAccountResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "status": { + "$ref": "#/definitions/v2/CancelLoginAccountStatus" + } + }, + "required": [ + "status" + ], + "title": "CancelLoginAccountResponse", + "type": "object" + }, + "CancelLoginAccountStatus": { + "enum": [ + "canceled", + "notFound" + ], + "type": "string" + }, + "CapabilityRootLocation": { + "description": "Location used to resolve a selected capability root.", + "oneOf": [ + { + "description": "A path owned by an execution environment.", + "properties": { + "environmentId": { + "type": "string" + }, + "path": { + "description": "Absolute path for the root in the selected environment.", + "type": "string" + }, + "type": { + "enum": [ + "environment" + ], + "title": "EnvironmentCapabilityRootLocationType", + "type": "string" + } + }, + "required": [ + "environmentId", + "path", + "type" + ], + "title": "EnvironmentCapabilityRootLocation", + "type": "object" + } + ] + }, + "CliAuthCredentialsStoreMode": { + "enum": [ + "file", + "keyring", + "auto", + "ephemeral" + ], + "type": "string" + }, + "CodexErrorInfo": { + "description": "This translation layer make sure that we expose codex error code in camel case.\n\nWhen an upstream HTTP status is available (for example, from the Responses API or a provider), it is forwarded in `httpStatusCode` on the relevant `codexErrorInfo` variant.", + "oneOf": [ + { + "enum": [ + "contextWindowExceeded", + "sessionBudgetExceeded", + "usageLimitExceeded", + "rateLimitExceeded", + "flexUnavailable", + "serverOverloaded", + "cyberPolicy", + "misalignmentPolicyViolation", + "internalServerError", + "unauthorized", + "badRequest", + "threadRollbackFailed", + "sandboxError", + "other" + ], + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "httpConnectionFailed": { + "properties": { + "httpStatusCode": { + "format": "uint16", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" + } + }, + "required": [ + "httpConnectionFailed" + ], + "title": "HttpConnectionFailedCodexErrorInfo", + "type": "object" + }, + { + "additionalProperties": false, + "description": "Failed to connect to the response SSE stream.", + "properties": { + "responseStreamConnectionFailed": { + "properties": { + "httpStatusCode": { + "format": "uint16", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" + } + }, + "required": [ + "responseStreamConnectionFailed" + ], + "title": "ResponseStreamConnectionFailedCodexErrorInfo", + "type": "object" + }, + { + "additionalProperties": false, + "description": "The response SSE stream disconnected in the middle of a turn before completion.", + "properties": { + "responseStreamDisconnected": { + "properties": { + "httpStatusCode": { + "format": "uint16", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" + } + }, + "required": [ + "responseStreamDisconnected" + ], + "title": "ResponseStreamDisconnectedCodexErrorInfo", + "type": "object" + }, + { + "additionalProperties": false, + "description": "Reached the retry limit for responses.", + "properties": { + "responseTooManyFailedAttempts": { + "properties": { + "httpStatusCode": { + "format": "uint16", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" + } + }, + "required": [ + "responseTooManyFailedAttempts" + ], + "title": "ResponseTooManyFailedAttemptsCodexErrorInfo", + "type": "object" + }, + { + "additionalProperties": false, + "description": "Returned when `turn/start` or `turn/steer` is submitted while the current active turn cannot accept same-turn steering, for example `/review` or manual `/compact`.", + "properties": { + "activeTurnNotSteerable": { + "properties": { + "turnKind": { + "$ref": "#/definitions/v2/NonSteerableTurnKind" + } + }, + "required": [ + "turnKind" + ], + "type": "object" + } + }, + "required": [ + "activeTurnNotSteerable" + ], + "title": "ActiveTurnNotSteerableCodexErrorInfo", + "type": "object" + } + ] + }, + "CodexResponseHandoffMode": { + "enum": [ + "thinking", + "commentary", + "bemTags" + ], + "type": "string" + }, + "CollabAgentState": { + "properties": { + "message": { + "type": [ + "string", + "null" + ] + }, + "status": { + "$ref": "#/definitions/v2/CollabAgentStatus" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "CollabAgentStatus": { + "enum": [ + "pendingInit", + "running", + "interrupted", + "completed", + "errored", + "shutdown", + "notFound" + ], + "type": "string" + }, + "CollabAgentTool": { + "enum": [ + "spawnAgent", + "sendInput", + "resumeAgent", + "wait", + "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents" + ], + "type": "string" + }, + "CollabAgentToolCallStatus": { + "enum": [ + "inProgress", + "completed", + "failed", + "interrupted" + ], + "type": "string" + }, + "CollaborationMode": { + "description": "Collaboration mode for a Codex session.", + "properties": { + "mode": { + "$ref": "#/definitions/v2/ModeKind" + }, + "settings": { + "$ref": "#/definitions/v2/Settings" + } + }, + "required": [ + "mode", + "settings" + ], + "type": "object" + }, + "CollaborationModeMask": { + "description": "EXPERIMENTAL - collaboration mode preset metadata for clients.", + "properties": { + "mode": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ModeKind" + }, + { + "type": "null" + } + ] + }, + "model": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "reasoning_effort": { + "anyOf": [ + { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ] + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "CommandAction": { + "oneOf": [ + { + "properties": { + "command": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": { + "enum": [ + "read" + ], + "title": "ReadCommandActionType", + "type": "string" + } + }, + "required": [ + "command", + "name", + "path", + "type" + ], + "title": "ReadCommandAction", + "type": "object" + }, + { + "properties": { + "command": { + "type": "string" + }, + "path": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "listFiles" + ], + "title": "ListFilesCommandActionType", + "type": "string" + } + }, + "required": [ + "command", + "type" + ], + "title": "ListFilesCommandAction", + "type": "object" + }, + { + "properties": { + "command": { + "type": "string" + }, + "path": { + "type": [ + "string", + "null" + ] + }, + "query": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "search" + ], + "title": "SearchCommandActionType", + "type": "string" + } + }, + "required": [ + "command", + "type" + ], + "title": "SearchCommandAction", + "type": "object" + }, + { + "properties": { + "command": { + "type": "string" + }, + "type": { + "enum": [ + "unknown" + ], + "title": "UnknownCommandActionType", + "type": "string" + } + }, + "required": [ + "command", + "type" + ], + "title": "UnknownCommandAction", + "type": "object" + } + ] + }, + "CommandExecOutputDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Base64-encoded output chunk emitted for a streaming `command/exec` request.\n\nThese notifications are connection-scoped. If the originating connection closes, the server terminates the process.", + "properties": { + "capReached": { + "description": "`true` on the final streamed chunk for a stream when `outputBytesCap` truncated later output on that stream.", + "type": "boolean" + }, + "deltaBase64": { + "description": "Base64-encoded output bytes.", + "type": "string" + }, + "processId": { + "description": "Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + "type": "string" + }, + "stream": { + "allOf": [ + { + "$ref": "#/definitions/v2/CommandExecOutputStream" + } + ], + "description": "Output stream for this chunk." + } + }, + "required": [ + "capReached", + "deltaBase64", + "processId", + "stream" + ], + "title": "CommandExecOutputDeltaNotification", + "type": "object" + }, + "CommandExecOutputStream": { + "description": "Stream label for `command/exec/outputDelta` notifications.", + "oneOf": [ + { + "description": "stdout stream. PTY mode multiplexes terminal output here.", + "enum": [ + "stdout" + ], + "type": "string" + }, + { + "description": "stderr stream.", + "enum": [ + "stderr" + ], + "type": "string" + } + ] + }, + "CommandExecParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted.", + "properties": { + "command": { + "description": "Command argv vector. Empty arrays are rejected.", + "items": { + "type": "string" + }, + "type": "array" + }, + "cwd": { + "description": "Optional working directory. Defaults to the server cwd.", + "type": [ + "string", + "null" + ] + }, + "disableOutputCap": { + "description": "Disable stdout/stderr capture truncation for this request.\n\nCannot be combined with `outputBytesCap`.", + "type": "boolean" + }, + "disableTimeout": { + "description": "Disable the timeout entirely for this request.\n\nCannot be combined with `timeoutMs`.", + "type": "boolean" + }, + "env": { + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "description": "Optional environment overrides merged into the server-computed environment.\n\nMatching names override inherited values. Set a key to `null` to unset an inherited variable.", + "type": [ + "object", + "null" + ] + }, + "outputBytesCap": { + "description": "Optional per-stream stdout/stderr capture cap in bytes.\n\nWhen omitted, the server default applies. Cannot be combined with `disableOutputCap`.", + "format": "uint", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "processId": { + "description": "Optional client-supplied, connection-scoped process id.\n\nRequired for `tty`, `streamStdin`, `streamStdoutStderr`, and follow-up `command/exec/write`, `command/exec/resize`, and `command/exec/terminate` calls. When omitted, buffered execution gets an internal id that is not exposed to the client.", + "type": [ + "string", + "null" + ] + }, + "sandboxPolicy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SandboxPolicy" + }, + { + "type": "null" + } + ], + "description": "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted. Cannot be combined with `permissionProfile`." + }, + "size": { + "anyOf": [ + { + "$ref": "#/definitions/v2/CommandExecTerminalSize" + }, + { + "type": "null" + } + ], + "description": "Optional initial PTY size in character cells. Only valid when `tty` is true." + }, + "streamStdin": { + "description": "Allow follow-up `command/exec/write` requests to write stdin bytes.\n\nRequires a client-supplied `processId`.", + "type": "boolean" + }, + "streamStdoutStderr": { + "description": "Stream stdout/stderr via `command/exec/outputDelta` notifications.\n\nStreamed bytes are not duplicated into the final response and require a client-supplied `processId`.", + "type": "boolean" + }, + "timeoutMs": { + "description": "Optional timeout in milliseconds.\n\nWhen omitted, the server default applies. Cannot be combined with `disableTimeout`.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "tty": { + "description": "Enable PTY mode.\n\nThis implies `streamStdin` and `streamStdoutStderr`.", + "type": "boolean" + } + }, + "required": [ + "command" + ], + "title": "CommandExecParams", + "type": "object" + }, + "CommandExecResizeParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Resize a running PTY-backed `command/exec` session.", + "properties": { + "processId": { + "description": "Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + "type": "string" + }, + "size": { + "allOf": [ + { + "$ref": "#/definitions/v2/CommandExecTerminalSize" + } + ], + "description": "New PTY size in character cells." + } + }, + "required": [ + "processId", + "size" + ], + "title": "CommandExecResizeParams", + "type": "object" + }, + "CommandExecResizeResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Empty success response for `command/exec/resize`.", + "title": "CommandExecResizeResponse", + "type": "object" + }, + "CommandExecResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Final buffered result for `command/exec`.", + "properties": { + "exitCode": { + "description": "Process exit code.", + "format": "int32", + "type": "integer" + }, + "stderr": { + "description": "Buffered stderr capture.\n\nEmpty when stderr was streamed via `command/exec/outputDelta`.", + "type": "string" + }, + "stdout": { + "description": "Buffered stdout capture.\n\nEmpty when stdout was streamed via `command/exec/outputDelta`.", + "type": "string" + } + }, + "required": [ + "exitCode", + "stderr", + "stdout" + ], + "title": "CommandExecResponse", + "type": "object" + }, + "CommandExecTerminalSize": { + "description": "PTY size in character cells for `command/exec` PTY sessions.", + "properties": { + "cols": { + "description": "Terminal width in character cells.", + "format": "uint16", + "minimum": 0.0, + "type": "integer" + }, + "rows": { + "description": "Terminal height in character cells.", + "format": "uint16", + "minimum": 0.0, + "type": "integer" + } + }, + "required": [ + "cols", + "rows" + ], + "type": "object" + }, + "CommandExecTerminateParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Terminate a running `command/exec` session.", + "properties": { + "processId": { + "description": "Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + "type": "string" + } + }, + "required": [ + "processId" + ], + "title": "CommandExecTerminateParams", + "type": "object" + }, + "CommandExecTerminateResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Empty success response for `command/exec/terminate`.", + "title": "CommandExecTerminateResponse", + "type": "object" + }, + "CommandExecWriteParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Write stdin bytes to a running `command/exec` session, close stdin, or both.", + "properties": { + "closeStdin": { + "description": "Close stdin after writing `deltaBase64`, if present.", + "type": "boolean" + }, + "deltaBase64": { + "description": "Optional base64-encoded stdin bytes to write.", + "type": [ + "string", + "null" + ] + }, + "processId": { + "description": "Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + "type": "string" + } + }, + "required": [ + "processId" + ], + "title": "CommandExecWriteParams", + "type": "object" + }, + "CommandExecWriteResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Empty success response for `command/exec/write`.", + "title": "CommandExecWriteResponse", + "type": "object" + }, + "CommandExecutionOutputDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "delta": { + "type": "string" + }, + "itemId": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "delta", + "itemId", + "threadId", + "turnId" + ], + "title": "CommandExecutionOutputDeltaNotification", + "type": "object" + }, + "CommandExecutionSource": { + "enum": [ + "agent", + "userShell", + "unifiedExecStartup", + "unifiedExecInteraction" + ], + "type": "string" + }, + "CommandExecutionStatus": { + "enum": [ + "inProgress", + "completed", + "failed", + "declined" + ], + "type": "string" + }, + "CommandMigration": { + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "ComputerUseConfig": { + "properties": { + "default_app_access": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "macos": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ComputerUseMacosConfig" + }, + { + "type": "null" + } + ] + }, + "windows": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ComputerUseWindowsConfig" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "ComputerUseMacosConfig": { + "properties": { + "bundle_ids": { + "additionalProperties": { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "ComputerUseMacosRequirements": { + "properties": { + "bundleIds": { + "additionalProperties": { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "ComputerUseRequirements": { + "properties": { + "allowLockedComputerUse": { + "type": [ + "boolean", + "null" + ] + }, + "allowPersistentApproval": { + "type": [ + "boolean", + "null" + ] + }, + "defaultAppAccess": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + { + "type": "null" + } + ] + }, + "macos": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ComputerUseMacosRequirements" + }, + { + "type": "null" + } + ] + }, + "windows": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ComputerUseWindowsRequirements" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "ComputerUseWindowsConfig": { + "properties": { + "aumids": { + "additionalProperties": { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + "type": [ + "object", + "null" + ] + }, + "exes": { + "items": { + "$ref": "#/definitions/v2/ComputerUseWindowsExeConfig" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "ComputerUseWindowsExeConfig": { + "properties": { + "access": { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + "binary_name": { + "type": [ + "string", + "null" + ] + }, + "product_name": { + "type": "string" + }, + "publisher_name": { + "type": "string" + } + }, + "required": [ + "access", + "product_name", + "publisher_name" + ], + "type": "object" + }, + "ComputerUseWindowsExeRequirement": { + "properties": { + "access": { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + "binaryName": { + "type": [ + "string", + "null" + ] + }, + "productName": { + "type": "string" + }, + "publisherName": { + "type": "string" + } + }, + "required": [ + "access", + "productName", + "publisherName" + ], + "type": "object" + }, + "ComputerUseWindowsRequirements": { + "properties": { + "aumids": { + "additionalProperties": { + "$ref": "#/definitions/v2/AllowDenyRequirement" + }, + "type": [ + "object", + "null" + ] + }, + "exes": { + "items": { + "$ref": "#/definitions/v2/ComputerUseWindowsExeRequirement" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "Config": { + "additionalProperties": true, + "properties": { + "analytics": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AnalyticsConfig" + }, + { + "type": "null" + } + ] + }, + "approval_policy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AskForApproval" + }, + { + "type": "null" + } + ] + }, + "approvals_reviewer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + { + "type": "null" + } + ], + "description": "[UNSTABLE] Optional default for where approval requests are routed for review." + }, + "browser_use": { + "anyOf": [ + { + "$ref": "#/definitions/v2/BrowserUseConfig" + }, + { + "type": "null" + } + ] + }, + "compact_prompt": { + "type": [ + "string", + "null" + ] + }, + "computer_use": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ComputerUseConfig" + }, + { + "type": "null" + } + ] + }, + "desktop": { + "additionalProperties": true, + "type": [ + "object", + "null" + ] + }, + "developer_instructions": { + "type": [ + "string", + "null" + ] + }, + "forced_chatgpt_workspace_id": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ForcedChatgptWorkspaceIds" + }, + { + "type": "null" + } + ] + }, + "forced_login_method": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ForcedLoginMethod" + }, + { + "type": "null" + } + ] + }, + "instructions": { + "type": [ + "string", + "null" + ] + }, + "model": { + "type": [ + "string", + "null" + ] + }, + "model_auto_compact_token_limit": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "model_auto_compact_token_limit_scope": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AutoCompactTokenLimitScope" + }, + { + "type": "null" + } + ] + }, + "model_context_window": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "model_provider": { + "type": [ + "string", + "null" + ] + }, + "model_reasoning_effort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ] + }, + "model_reasoning_summary": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningSummary" + }, + { + "type": "null" + } + ] + }, + "model_verbosity": { + "anyOf": [ + { + "$ref": "#/definitions/v2/Verbosity" + }, + { + "type": "null" + } + ] + }, + "review_model": { + "type": [ + "string", + "null" + ] + }, + "sandbox_mode": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SandboxMode" + }, + { + "type": "null" + } + ] + }, + "sandbox_workspace_write": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SandboxWorkspaceWrite" + }, + { + "type": "null" + } + ] + }, + "service_tier": { + "type": [ + "string", + "null" + ] + }, + "tools": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ToolsV2" + }, + { + "type": "null" + } + ] + }, + "web_search": { + "anyOf": [ + { + "$ref": "#/definitions/v2/WebSearchMode" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "ConfigBatchWriteParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "edits": { + "items": { + "$ref": "#/definitions/v2/ConfigEdit" + }, + "type": "array" + }, + "expectedVersion": { + "type": [ + "string", + "null" + ] + }, + "filePath": { + "description": "Path to the config file to write; defaults to the user's `config.toml` when omitted.", + "type": [ + "string", + "null" + ] + }, + "reloadUserConfig": { + "description": "When true, hot-reload updated runtime settings into loaded threads after writing. Session-static model, reasoning-effort, Plan-mode reasoning-effort, and service-tier defaults are not reloaded. The deprecated personality setting is also not reloaded.", + "type": "boolean" + } + }, + "required": [ + "edits" + ], + "title": "ConfigBatchWriteParams", + "type": "object" + }, + "ConfigEdit": { + "properties": { + "keyPath": { + "type": "string" + }, + "mergeStrategy": { + "$ref": "#/definitions/v2/MergeStrategy" + }, + "value": true + }, + "required": [ + "keyPath", + "mergeStrategy", + "value" + ], + "type": "object" + }, + "ConfigLayer": { + "properties": { + "config": true, + "disabledReason": { + "type": [ + "string", + "null" + ] + }, + "name": { + "$ref": "#/definitions/v2/ConfigLayerSource" + }, + "version": { + "type": "string" + } + }, + "required": [ + "config", + "name", + "version" + ], + "type": "object" + }, + "ConfigLayerMetadata": { + "properties": { + "name": { + "$ref": "#/definitions/v2/ConfigLayerSource" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "ConfigLayerSource": { + "oneOf": [ + { + "description": "Default configuration supplied with the installed Codex package.", + "properties": { + "file": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Path to the packaged default configuration file." + }, + "type": { + "enum": [ + "packagedDefaults" + ], + "title": "PackagedDefaultsConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "file", + "type" + ], + "title": "PackagedDefaultsConfigLayerSource", + "type": "object" + }, + { + "description": "Managed preferences layer delivered by MDM (macOS only).", + "properties": { + "domain": { + "type": "string" + }, + "key": { + "type": "string" + }, + "type": { + "enum": [ + "mdm" + ], + "title": "MdmConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "domain", + "key", + "type" + ], + "title": "MdmConfigLayerSource", + "type": "object" + }, + { + "description": "Managed config layer from a file (usually `managed_config.toml`).", + "properties": { + "file": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "This is the path to the system config.toml file, though it is not guaranteed to exist." + }, + "type": { + "enum": [ + "system" + ], + "title": "SystemConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "file", + "type" + ], + "title": "SystemConfigLayerSource", + "type": "object" + }, + { + "description": "Enterprise-managed config layer delivered by the cloud config bundle.", + "properties": { + "id": { + "description": "Stable identifier for the delivered layer.", + "type": "string" + }, + "name": { + "description": "Admin-facing name for the delivered layer. This is surfaced in diagnostics so users know which cloud layer needs administrator attention.", + "type": "string" + }, + "type": { + "enum": [ + "enterpriseManaged" + ], + "title": "EnterpriseManagedConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "id", + "name", + "type" + ], + "title": "EnterpriseManagedConfigLayerSource", + "type": "object" + }, + { + "description": "User config layer from $CODEX_HOME/config.toml. This layer is special in that it is expected to be: - writable by the user - generally outside the workspace directory", + "properties": { + "file": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "This is the path to the user's config.toml file, though it is not guaranteed to exist." + }, + "profile": { + "description": "Name of the selected profile-v2 config layered on top of the base user config, when this layer represents one.", + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "user" + ], + "title": "UserConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "file", + "type" + ], + "title": "UserConfigLayerSource", + "type": "object" + }, + { + "description": "Path to a .codex/ folder within a project. There could be multiple of these between `cwd` and the project/repo root.", + "properties": { + "dotCodexFolder": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": { + "enum": [ + "project" + ], + "title": "ProjectConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "dotCodexFolder", + "type" + ], + "title": "ProjectConfigLayerSource", + "type": "object" + }, + { + "description": "Session-layer overrides supplied via `-c`/`--config`.", + "properties": { + "type": { + "enum": [ + "sessionFlags" + ], + "title": "SessionFlagsConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "SessionFlagsConfigLayerSource", + "type": "object" + }, + { + "description": "`managed_config.toml` was designed to be a config that was loaded as the last layer on top of everything else. This scheme did not quite work out as intended, but we keep this variant as a \"best effort\" while we phase out `managed_config.toml` in favor of `requirements.toml`.", + "properties": { + "file": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": { + "enum": [ + "legacyManagedConfigTomlFromFile" + ], + "title": "LegacyManagedConfigTomlFromFileConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "file", + "type" + ], + "title": "LegacyManagedConfigTomlFromFileConfigLayerSource", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "legacyManagedConfigTomlFromMdm" + ], + "title": "LegacyManagedConfigTomlFromMdmConfigLayerSourceType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "LegacyManagedConfigTomlFromMdmConfigLayerSource", + "type": "object" + } + ] + }, + "ConfigReadParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cwd": { + "description": "Optional working directory to resolve project config layers. If specified, return the effective config as seen from that directory (i.e., including any project layers between `cwd` and the project/repo root).", + "type": [ + "string", + "null" + ] + }, + "includeLayers": { + "type": "boolean" + } + }, + "title": "ConfigReadParams", + "type": "object" + }, + "ConfigReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "config": { + "$ref": "#/definitions/v2/Config" + }, + "layers": { + "items": { + "$ref": "#/definitions/v2/ConfigLayer" + }, + "type": [ + "array", + "null" + ] + }, + "origins": { + "additionalProperties": { + "$ref": "#/definitions/v2/ConfigLayerMetadata" + }, + "type": "object" + } + }, + "required": [ + "config", + "origins" + ], + "title": "ConfigReadResponse", + "type": "object" + }, + "ConfigRequirements": { + "properties": { + "additionalDeveloperInstructions": { + "type": [ + "string", + "null" + ] + }, + "allowAppshots": { + "type": [ + "boolean", + "null" + ] + }, + "allowBrowserAndComputerUse": { + "type": [ + "boolean", + "null" + ] + }, + "allowLoginShell": { + "type": [ + "boolean", + "null" + ] + }, + "allowManagedHooksOnly": { + "type": [ + "boolean", + "null" + ] + }, + "allowRemoteControl": { + "type": [ + "boolean", + "null" + ] + }, + "allowedApprovalPolicies": { + "items": { + "$ref": "#/definitions/v2/AskForApproval" + }, + "type": [ + "array", + "null" + ] + }, + "allowedLoginMethods": { + "description": "Effective login methods after managed, forced-login, and workspace restrictions. An empty list permits no login method. Older servers may omit this field.", + "items": { + "$ref": "#/definitions/v2/ForcedLoginMethod" + }, + "type": [ + "array", + "null" + ] + }, + "allowedPermissionProfiles": { + "additionalProperties": { + "type": "boolean" + }, + "type": [ + "object", + "null" + ] + }, + "allowedSandboxModes": { + "items": { + "$ref": "#/definitions/v2/SandboxMode" + }, + "type": [ + "array", + "null" + ] + }, + "allowedWebSearchModes": { + "items": { + "$ref": "#/definitions/v2/WebSearchMode" + }, + "type": [ + "array", + "null" + ] + }, + "allowedWindowsSandboxImplementations": { + "items": { + "$ref": "#/definitions/v2/WindowsSandboxImplementation" + }, + "type": [ + "array", + "null" + ] + }, + "autoReview": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AutoReviewRequirements" + }, + { + "type": "null" + } + ] + }, + "browserUse": { + "anyOf": [ + { + "$ref": "#/definitions/v2/BrowserUseRequirements" + }, + { + "type": "null" + } + ] + }, + "chatgptBaseUrl": { + "type": [ + "string", + "null" + ] + }, + "checkForUpdateOnStartup": { + "type": [ + "boolean", + "null" + ] + }, + "cliAuthCredentialsStore": { + "anyOf": [ + { + "$ref": "#/definitions/v2/CliAuthCredentialsStoreMode" + }, + { + "type": "null" + } + ] + }, + "computerUse": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ComputerUseRequirements" + }, + { + "type": "null" + } + ] + }, + "defaultPermissions": { + "type": [ + "string", + "null" + ] + }, + "enforceResidency": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ResidencyRequirement" + }, + { + "type": "null" + } + ] + }, + "featureRequirements": { + "additionalProperties": { + "type": "boolean" + }, + "type": [ + "object", + "null" + ] + }, + "feedback": { + "anyOf": [ + { + "$ref": "#/definitions/v2/FeedbackRequirements" + }, + { + "type": "null" + } + ] + }, + "inAppBrowser": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InAppBrowserRequirements" + }, + { + "type": "null" + } + ] + }, + "logDir": { + "type": [ + "string", + "null" + ] + }, + "modelCatalogJson": { + "type": [ + "string", + "null" + ] + }, + "modelProvider": { + "description": "Exact provider selection required by managed policy.", + "type": [ + "string", + "null" + ] + }, + "modelProviders": { + "additionalProperties": true, + "description": "Complete required provider definitions, using config.toml field names.", + "type": [ + "object", + "null" + ] + }, + "models": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ModelsRequirements" + }, + { + "type": "null" + } + ] + }, + "sqliteHome": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "ConfigRequirementsReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "requirements": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ConfigRequirements" + }, + { + "type": "null" + } + ], + "description": "Null if no requirements are configured (e.g. no requirements.toml/MDM entries)." + } + }, + "title": "ConfigRequirementsReadResponse", + "type": "object" + }, + "ConfigValueWriteParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "expectedVersion": { + "type": [ + "string", + "null" + ] + }, + "filePath": { + "description": "Path to the config file to write; defaults to the user's `config.toml` when omitted.", + "type": [ + "string", + "null" + ] + }, + "keyPath": { + "type": "string" + }, + "mergeStrategy": { + "$ref": "#/definitions/v2/MergeStrategy" + }, + "value": true + }, + "required": [ + "keyPath", + "mergeStrategy", + "value" + ], + "title": "ConfigValueWriteParams", + "type": "object" + }, + "ConfigWarningNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "details": { + "description": "Optional extra guidance or error details.", + "type": [ + "string", + "null" + ] + }, + "path": { + "description": "Optional path to the config file that triggered the warning.", + "type": [ + "string", + "null" + ] + }, + "range": { + "anyOf": [ + { + "$ref": "#/definitions/v2/TextRange" + }, + { + "type": "null" + } + ], + "description": "Optional range for the error location inside the config file." + }, + "summary": { + "description": "Concise summary of the warning.", + "type": "string" + } + }, + "required": [ + "summary" + ], + "title": "ConfigWarningNotification", + "type": "object" + }, + "ConfigWriteResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "filePath": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Canonical path to the config file that was written." + }, + "overriddenMetadata": { + "anyOf": [ + { + "$ref": "#/definitions/v2/OverriddenMetadata" + }, + { + "type": "null" + } + ] + }, + "status": { + "$ref": "#/definitions/v2/WriteStatus" + }, + "version": { + "type": "string" + } + }, + "required": [ + "filePath", + "status", + "version" + ], + "title": "ConfigWriteResponse", + "type": "object" + }, + "ConfigurationReasoning": { + "description": "Reasoning settings interpreted by the backend for the routed model.", + "properties": { + "effort": { + "$ref": "#/definitions/v2/ReasoningEffort" + } + }, + "required": [ + "effort" + ], + "type": "object" + }, + "ConfiguredHookHandler": { + "oneOf": [ + { + "properties": { + "additionalContextLimit": { + "description": "Approximate token threshold for spilling this hook's `additionalContext` to disk. `null` uses 2,500 tokens; `0` disables spilling for this hook. The threshold is evaluated against the original context; a spilled preview also includes recovery metadata.", + "format": "uint", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "async": { + "type": "boolean" + }, + "command": { + "type": "string" + }, + "commandWindows": { + "type": [ + "string", + "null" + ] + }, + "statusMessage": { + "type": [ + "string", + "null" + ] + }, + "timeoutSec": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "type": { + "enum": [ + "command" + ], + "title": "CommandConfiguredHookHandlerType", + "type": "string" + } + }, + "required": [ + "async", + "command", + "type" + ], + "title": "CommandConfiguredHookHandler", + "type": "object" + }, + { + "properties": { + "input": { + "additionalProperties": true, + "type": "object" + }, + "server": { + "type": "string" + }, + "statusMessage": { + "type": [ + "string", + "null" + ] + }, + "timeoutSec": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "tool": { + "type": "string" + }, + "type": { + "enum": [ + "mcp_tool" + ], + "title": "McpToolConfiguredHookHandlerType", + "type": "string" + } + }, + "required": [ + "input", + "server", + "tool", + "type" + ], + "title": "McpToolConfiguredHookHandler", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "prompt" + ], + "title": "PromptConfiguredHookHandlerType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "PromptConfiguredHookHandler", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "agent" + ], + "title": "AgentConfiguredHookHandlerType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "AgentConfiguredHookHandler", + "type": "object" + } + ] + }, + "ConfiguredHookMatcherGroup": { + "properties": { + "hooks": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookHandler" + }, + "type": "array" + }, + "matcher": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "hooks" + ], + "type": "object" + }, + "ConnectorMetadata": { + "description": "EXPERIMENTAL - metadata returned by app/read.", + "properties": { + "description": { + "type": [ + "string", + "null" + ] + }, + "distributionChannel": { + "type": [ + "string", + "null" + ] + }, + "iconUrl": { + "type": [ + "string", + "null" + ] + }, + "iconUrlDark": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": "string" + }, + "installUrl": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "pluginDisplayNames": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "toolSummaries": { + "items": { + "$ref": "#/definitions/v2/AppToolSummary" + }, + "type": [ + "array", + "null" + ] + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + }, + "ConsumeAccountRateLimitResetCreditOutcome": { + "oneOf": [ + { + "description": "A reset credit was consumed and the eligible rate-limit windows were reset.", + "enum": [ + "reset" + ], + "type": "string" + }, + { + "description": "No current rate-limit window is eligible for a reset.", + "enum": [ + "nothingToReset" + ], + "type": "string" + }, + { + "description": "The account has no earned reset credits available.", + "enum": [ + "noCredit" + ], + "type": "string" + }, + { + "description": "The same idempotency key already completed a reset successfully.", + "enum": [ + "alreadyRedeemed" + ], + "type": "string" + } + ] + }, + "ConsumeAccountRateLimitResetCreditParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "creditId": { + "description": "Opaque reset-credit identifier to redeem. When omitted, the backend selects the next available credit.", + "type": [ + "string", + "null" + ] + }, + "idempotencyKey": { + "description": "Identifies one logical reset attempt. A UUID is recommended; reuse the same value when retrying that attempt.", + "type": "string" + } + }, + "required": [ + "idempotencyKey" + ], + "title": "ConsumeAccountRateLimitResetCreditParams", + "type": "object" + }, + "ConsumeAccountRateLimitResetCreditResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "outcome": { + "$ref": "#/definitions/v2/ConsumeAccountRateLimitResetCreditOutcome" + } + }, + "required": [ + "outcome" + ], + "title": "ConsumeAccountRateLimitResetCreditResponse", + "type": "object" + }, + "ContentItem": { + "oneOf": [ + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "enum": [ + "input_text" + ], + "title": "InputTextContentItemType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "InputTextContentItem", + "type": "object" + }, + { + "anyOf": [ + { + "properties": { + "image_url": { + "type": "string" + } + }, + "required": [ + "image_url" + ], + "title": "ImageUrlContentItem", + "type": "object" + }, + { + "properties": { + "file_id": { + "type": "string" + } + }, + "required": [ + "file_id" + ], + "title": "FileIdContentItem", + "type": "object" + } + ], + "properties": { + "detail": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ImageDetail" + }, + { + "type": "null" + } + ] + }, + "type": { + "enum": [ + "input_image" + ], + "title": "InputImageContentItemType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "InputImageContentItem", + "type": "object" + }, + { + "properties": { + "audio_url": { + "type": "string" + }, + "type": { + "enum": [ + "input_audio" + ], + "title": "InputAudioContentItemType", + "type": "string" + } + }, + "required": [ + "audio_url", + "type" + ], + "title": "InputAudioContentItem", + "type": "object" + }, + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "enum": [ + "output_text" + ], + "title": "OutputTextContentItemType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "OutputTextContentItem", + "type": "object" + } + ] + }, + "ContextCompactedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Deprecated: Use `ContextCompaction` item type instead.", + "properties": { + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "threadId", + "turnId" + ], + "title": "ContextCompactedNotification", + "type": "object" + }, + "ConversationTextRole": { + "enum": [ + "user", + "developer", + "assistant" + ], + "type": "string" + }, + "CreditsSnapshot": { + "properties": { + "balance": { + "type": [ + "string", + "null" + ] + }, + "hasCredits": { + "type": "boolean" + }, + "unlimited": { + "type": "boolean" + } + }, + "required": [ + "hasCredits", + "unlimited" + ], + "type": "object" + }, + "CyberAccessProgram": { + "description": "Requested cyber treatment for a ChatGPT-authenticated Codex turn. Authorization and model-tier restrictions remain server-owned.", + "enum": [ + "standard", + "daybreakBlue", + "daybreakRed" + ], + "type": "string" + }, + "DeprecationNoticeNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "details": { + "description": "Optional extra guidance, such as migration steps or rationale.", + "type": [ + "string", + "null" + ] + }, + "summary": { + "description": "Concise summary of what is deprecated.", + "type": "string" + } + }, + "required": [ + "summary" + ], + "title": "DeprecationNoticeNotification", + "type": "object" + }, + "DesktopOnboardingEntrypoint": { + "enum": [ + "life_sciences" + ], + "type": "string" + }, + "DynamicToolCallOutputContentItem": { + "oneOf": [ + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "enum": [ + "inputText" + ], + "title": "InputTextDynamicToolCallOutputContentItemType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "InputTextDynamicToolCallOutputContentItem", + "type": "object" + }, + { + "properties": { + "imageUrl": { + "type": "string" + }, + "type": { + "enum": [ + "inputImage" + ], + "title": "InputImageDynamicToolCallOutputContentItemType", + "type": "string" + } + }, + "required": [ + "imageUrl", + "type" + ], + "title": "InputImageDynamicToolCallOutputContentItem", + "type": "object" + }, + { + "properties": { + "audioUrl": { + "type": "string" + }, + "type": { + "enum": [ + "inputAudio" + ], + "title": "InputAudioDynamicToolCallOutputContentItemType", + "type": "string" + } + }, + "required": [ + "audioUrl", + "type" + ], + "title": "InputAudioDynamicToolCallOutputContentItem", + "type": "object" + } + ] + }, + "DynamicToolCallStatus": { + "enum": [ + "inProgress", + "completed", + "failed" + ], + "type": "string" + }, + "DynamicToolNamespaceTool": { + "oneOf": [ + { + "properties": { + "deferLoading": { + "type": "boolean" + }, + "description": { + "type": "string" + }, + "inputSchema": true, + "name": { + "type": "string" + }, + "type": { + "enum": [ + "function" + ], + "title": "FunctionDynamicToolNamespaceToolType", + "type": "string" + } + }, + "required": [ + "description", + "inputSchema", + "name", + "type" + ], + "title": "FunctionDynamicToolNamespaceTool", + "type": "object" + } + ] + }, + "DynamicToolSpec": { + "oneOf": [ + { + "properties": { + "deferLoading": { + "type": "boolean" + }, + "description": { + "type": "string" + }, + "inputSchema": true, + "name": { + "type": "string" + }, + "type": { + "enum": [ + "function" + ], + "title": "FunctionDynamicToolSpecType", + "type": "string" + } + }, + "required": [ + "description", + "inputSchema", + "name", + "type" + ], + "title": "FunctionDynamicToolSpec", + "type": "object" + }, + { + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tools": { + "items": { + "$ref": "#/definitions/v2/DynamicToolNamespaceTool" + }, + "type": "array" + }, + "type": { + "enum": [ + "namespace" + ], + "title": "NamespaceDynamicToolSpecType", + "type": "string" + } + }, + "required": [ + "description", + "name", + "tools", + "type" + ], + "title": "NamespaceDynamicToolSpec", + "type": "object" + } + ] + }, + "EnvironmentConnectionNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "environmentId": { + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "environmentId", + "threadId" + ], + "title": "EnvironmentConnectionNotification", + "type": "object" + }, + "ErrorNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "error": { + "$ref": "#/definitions/v2/TurnError" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + }, + "willRetry": { + "type": "boolean" + } + }, + "required": [ + "error", + "threadId", + "turnId", + "willRetry" + ], + "title": "ErrorNotification", + "type": "object" + }, + "ExperimentalFeature": { + "properties": { + "announcement": { + "description": "Announcement copy shown to users when the feature is introduced. Null when this feature is not in beta.", + "type": [ + "string", + "null" + ] + }, + "defaultEnabled": { + "description": "Whether this feature is enabled by default.", + "type": "boolean" + }, + "description": { + "description": "Short summary describing what the feature does. Null when this feature is not in beta.", + "type": [ + "string", + "null" + ] + }, + "displayName": { + "description": "User-facing display name shown in the experimental features UI. Null when this feature is not in beta.", + "type": [ + "string", + "null" + ] + }, + "enabled": { + "description": "Whether this feature is currently enabled in the loaded config.", + "type": "boolean" + }, + "name": { + "description": "Stable key used in config.toml and CLI flag toggles.", + "type": "string" + }, + "stage": { + "allOf": [ + { + "$ref": "#/definitions/v2/ExperimentalFeatureStage" + } + ], + "description": "Lifecycle stage of this feature flag." + } + }, + "required": [ + "defaultEnabled", + "enabled", + "name", + "stage" + ], + "type": "object" + }, + "ExperimentalFeatureEnablementSetParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "enablement": { + "additionalProperties": { + "type": "boolean" + }, + "description": "Process-wide runtime feature enablement keyed by canonical feature name.\n\nOnly named features are updated. Omitted features are left unchanged. Send an empty map for a no-op.", + "type": "object" + } + }, + "required": [ + "enablement" + ], + "title": "ExperimentalFeatureEnablementSetParams", + "type": "object" + }, + "ExperimentalFeatureEnablementSetResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "enablement": { + "additionalProperties": { + "type": "boolean" + }, + "description": "Feature enablement entries updated by this request.", + "type": "object" + } + }, + "required": [ + "enablement" + ], + "title": "ExperimentalFeatureEnablementSetResponse", + "type": "object" + }, + "ExperimentalFeatureListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cursor": { + "description": "Opaque pagination cursor returned by a previous call.", + "type": [ + "string", + "null" + ] + }, + "limit": { + "description": "Optional page size; defaults to a reasonable server-side value.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "threadId": { + "description": "Optional loaded thread id. Pass this when showing feature state for an existing thread so enablement is computed from that thread's refreshed config, including project-local config for the thread's cwd.", + "type": [ + "string", + "null" + ] + } + }, + "title": "ExperimentalFeatureListParams", + "type": "object" + }, + "ExperimentalFeatureListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/ExperimentalFeature" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item. If None, there are no more items to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ExperimentalFeatureListResponse", + "type": "object" + }, + "ExperimentalFeatureStage": { + "oneOf": [ + { + "description": "Feature is available for user testing and feedback.", + "enum": [ + "beta" + ], + "type": "string" + }, + { + "description": "Feature is still being built and not ready for broad use.", + "enum": [ + "underDevelopment" + ], + "type": "string" + }, + { + "description": "Feature is production-ready.", + "enum": [ + "stable" + ], + "type": "string" + }, + { + "description": "Feature is deprecated and should be avoided.", + "enum": [ + "deprecated" + ], + "type": "string" + }, + { + "description": "Feature flag is retained only for backwards compatibility.", + "enum": [ + "removed" + ], + "type": "string" + } + ] + }, + "ExternalAgentConfigDetectParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cwds": { + "description": "Zero or more working directories to include for repo-scoped detection.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "includeHome": { + "description": "If true, include detection under the user's home directory.", + "type": "boolean" + }, + "maxSessionAgeDays": { + "description": "Maximum age in days for detected sessions. Missing values use the default limit.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "maxSessions": { + "description": "Maximum number of sessions to detect. Missing values use the default limit.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "migrationSource": { + "description": "Optional migration-source selector. Missing or unrecognized values use the default source.", + "type": [ + "string", + "null" + ] + }, + "source": { + "description": "Deprecated field retained for compatibility. This field is ignored; use `migrationSource` to select the migration source.", + "type": [ + "string", + "null" + ] + } + }, + "title": "ExternalAgentConfigDetectParams", + "type": "object" + }, + "ExternalAgentConfigDetectResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "connectors": { + "default": [], + "items": { + "$ref": "#/definitions/v2/ExternalAgentDetectedConnectorCandidate" + }, + "type": "array" + }, + "items": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigMigrationItem" + }, + "type": "array" + } + }, + "required": [ + "items" + ], + "title": "ExternalAgentConfigDetectResponse", + "type": "object" + }, + "ExternalAgentConfigImportCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "importId": { + "type": "string" + }, + "itemTypeResults": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportTypeResult" + }, + "type": "array" + } + }, + "required": [ + "importId", + "itemTypeResults" + ], + "title": "ExternalAgentConfigImportCompletedNotification", + "type": "object" + }, + "ExternalAgentConfigImportHistoriesReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "connectors": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentImportedConnectorCandidate" + }, + "type": "array" + }, + "data": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportHistory" + }, + "type": "array" + } + }, + "required": [ + "connectors", + "data" + ], + "title": "ExternalAgentConfigImportHistoriesReadResponse", + "type": "object" + }, + "ExternalAgentConfigImportHistory": { + "properties": { + "completedAtMs": { + "format": "int64", + "type": "integer" + }, + "failures": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportItemTypeFailure" + }, + "type": "array" + }, + "importId": { + "type": "string" + }, + "providerId": { + "type": [ + "string", + "null" + ] + }, + "successes": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportItemTypeSuccess" + }, + "type": "array" + } + }, + "required": [ + "completedAtMs", + "failures", + "importId", + "successes" + ], + "type": "object" + }, + "ExternalAgentConfigImportHistoryRecordParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "itemTypeResults": { + "description": "Completed results grouped by imported item type.", + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportHistoryRecordTypeResultParams" + }, + "type": "array" + }, + "providerId": { + "description": "Opaque provider identifier for the externally completed import.", + "type": "string" + } + }, + "required": [ + "itemTypeResults", + "providerId" + ], + "title": "ExternalAgentConfigImportHistoryRecordParams", + "type": "object" + }, + "ExternalAgentConfigImportHistoryRecordResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "importId": { + "type": "string" + } + }, + "required": [ + "importId" + ], + "title": "ExternalAgentConfigImportHistoryRecordResponse", + "type": "object" + }, + "ExternalAgentConfigImportHistoryRecordSuccessParams": { + "properties": { + "cwd": { + "type": [ + "string", + "null" + ] + }, + "itemType": { + "$ref": "#/definitions/v2/ExternalAgentConfigMigrationItemType" + }, + "source": { + "type": [ + "string", + "null" + ] + }, + "target": { + "type": [ + "string", + "null" + ] + }, + "title": { + "default": null, + "description": "Original title for an imported session, when available.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "itemType" + ], + "type": "object" + }, + "ExternalAgentConfigImportHistoryRecordTypeResultParams": { + "properties": { + "failures": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportItemTypeFailure" + }, + "type": "array" + }, + "itemType": { + "$ref": "#/definitions/v2/ExternalAgentConfigMigrationItemType" + }, + "successes": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportHistoryRecordSuccessParams" + }, + "type": "array" + } + }, + "required": [ + "failures", + "itemType", + "successes" + ], + "type": "object" + }, + "ExternalAgentConfigImportItemTypeFailure": { + "properties": { + "cwd": { + "type": [ + "string", + "null" + ] + }, + "errorType": { + "type": [ + "string", + "null" + ] + }, + "failureStage": { + "type": "string" + }, + "itemType": { + "$ref": "#/definitions/v2/ExternalAgentConfigMigrationItemType" + }, + "message": { + "type": "string" + }, + "source": { + "type": [ + "string", + "null" + ] + }, + "subErrorType": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "failureStage", + "itemType", + "message" + ], + "type": "object" + }, + "ExternalAgentConfigImportItemTypeSuccess": { + "properties": { + "cwd": { + "type": [ + "string", + "null" + ] + }, + "itemType": { + "$ref": "#/definitions/v2/ExternalAgentConfigMigrationItemType" + }, + "source": { + "type": [ + "string", + "null" + ] + }, + "target": { + "type": [ + "string", + "null" + ] + }, + "title": { + "default": null, + "description": "Original title for an imported session; null for other item types.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "itemType" + ], + "type": "object" + }, + "ExternalAgentConfigImportParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "migrationItems": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigMigrationItem" + }, + "type": "array" + }, + "migrationSource": { + "description": "Migration-source selector used to produce the migration items. Pass the same value to detection and import; missing or unrecognized values use the default source.", + "type": [ + "string", + "null" + ] + }, + "providerId": { + "description": "Opaque provider identifier supplied by the caller for analytics attribution and import history display. This does not select the migration source.", + "type": [ + "string", + "null" + ] + }, + "source": { + "description": "Optional identifier for the product that initiated the import.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "migrationItems" + ], + "title": "ExternalAgentConfigImportParams", + "type": "object" + }, + "ExternalAgentConfigImportProgressNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "importId": { + "type": "string" + }, + "itemTypeResults": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportTypeResult" + }, + "type": "array" + } + }, + "required": [ + "importId", + "itemTypeResults" + ], + "title": "ExternalAgentConfigImportProgressNotification", + "type": "object" + }, + "ExternalAgentConfigImportResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "importId": { + "type": "string" + } + }, + "required": [ + "importId" + ], + "title": "ExternalAgentConfigImportResponse", + "type": "object" + }, + "ExternalAgentConfigImportTypeResult": { + "properties": { + "failures": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportItemTypeFailure" + }, + "type": "array" + }, + "itemType": { + "$ref": "#/definitions/v2/ExternalAgentConfigMigrationItemType" + }, + "successes": { + "items": { + "$ref": "#/definitions/v2/ExternalAgentConfigImportItemTypeSuccess" + }, + "type": "array" + } + }, + "required": [ + "failures", + "itemType", + "successes" + ], + "type": "object" + }, + "ExternalAgentConfigMigrationItem": { + "properties": { + "cwd": { + "description": "Null or empty means home-scoped migration; non-empty means repo-scoped migration.", + "type": [ + "string", + "null" + ] + }, + "description": { + "type": "string" + }, + "details": { + "anyOf": [ + { + "$ref": "#/definitions/v2/MigrationDetails" + }, + { + "type": "null" + } + ] + }, + "itemType": { + "$ref": "#/definitions/v2/ExternalAgentConfigMigrationItemType" + } + }, + "required": [ + "description", + "itemType" + ], + "type": "object" + }, + "ExternalAgentConfigMigrationItemType": { + "enum": [ + "AGENTS_MD", + "CONFIG", + "SKILLS", + "PLUGINS", + "MCP_SERVER_CONFIG", + "SUBAGENTS", + "HOOKS", + "COMMANDS", + "MEMORY", + "SESSIONS" + ], + "type": "string" + }, + "ExternalAgentDetectedConnectorCandidate": { + "properties": { + "name": { + "type": "string" + }, + "sessionCount": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "source": { + "$ref": "#/definitions/v2/ExternalAgentDetectedConnectorSource" + } + }, + "required": [ + "name", + "sessionCount", + "source" + ], + "type": "object" + }, + "ExternalAgentDetectedConnectorSource": { + "enum": [ + "remoteMcpServersConfig", + "sessionToolUse" + ], + "type": "string" + }, + "ExternalAgentImportedConnectorCandidate": { + "properties": { + "name": { + "type": "string" + }, + "sessionCount": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "source": { + "$ref": "#/definitions/v2/ExternalAgentImportedConnectorSource" + } + }, + "required": [ + "name", + "sessionCount", + "source" + ], + "type": "object" + }, + "ExternalAgentImportedConnectorSource": { + "enum": [ + "remoteMcpServersConfig" + ], + "type": "string" + }, + "FeedbackRequirements": { + "properties": { + "enabled": { + "type": [ + "boolean", + "null" + ] + } + }, + "type": "object" + }, + "FeedbackUploadParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "classification": { + "type": "string" + }, + "extraLogFiles": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "includeLogs": { + "type": "boolean" + }, + "reason": { + "type": [ + "string", + "null" + ] + }, + "tags": { + "additionalProperties": { + "type": "string" + }, + "type": [ + "object", + "null" + ] + }, + "threadId": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "classification" + ], + "title": "FeedbackUploadParams", + "type": "object" + }, + "FeedbackUploadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "promptHash": { + "default": null, + "description": "Whitespace-normalized SHA-256 of the session base instructions, matching the uploaded `prompt_hash` tag. Does not include later developer messages. Null when the reported rollout has no prompt metadata.", + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "FeedbackUploadResponse", + "type": "object" + }, + "FileChangeOutputDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Deprecated legacy notification for `apply_patch` textual output.\n\nThe server no longer emits this notification.", + "properties": { + "delta": { + "type": "string" + }, + "itemId": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "delta", + "itemId", + "threadId", + "turnId" + ], + "title": "FileChangeOutputDeltaNotification", + "type": "object" + }, + "FileChangePatchUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "changes": { + "items": { + "$ref": "#/definitions/v2/FileUpdateChange" + }, + "type": "array" + }, + "itemId": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "changes", + "itemId", + "threadId", + "turnId" + ], + "title": "FileChangePatchUpdatedNotification", + "type": "object" + }, + "FileSystemAccessMode": { + "enum": [ + "read", + "write", + "deny" + ], + "type": "string" + }, + "FileSystemPath": { + "oneOf": [ + { + "properties": { + "path": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": { + "enum": [ + "path" + ], + "title": "PathFileSystemPathType", + "type": "string" + } + }, + "required": [ + "path", + "type" + ], + "title": "PathFileSystemPath", + "type": "object" + }, + { + "properties": { + "pattern": { + "type": "string" + }, + "type": { + "enum": [ + "glob_pattern" + ], + "title": "GlobPatternFileSystemPathType", + "type": "string" + } + }, + "required": [ + "pattern", + "type" + ], + "title": "GlobPatternFileSystemPath", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "special" + ], + "title": "SpecialFileSystemPathType", + "type": "string" + }, + "value": { + "$ref": "#/definitions/v2/FileSystemSpecialPath" + } + }, + "required": [ + "type", + "value" + ], + "title": "SpecialFileSystemPath", + "type": "object" + } + ] + }, + "FileSystemSandboxEntry": { + "properties": { + "access": { + "$ref": "#/definitions/v2/FileSystemAccessMode" + }, + "path": { + "$ref": "#/definitions/v2/FileSystemPath" + } + }, + "required": [ + "access", + "path" + ], + "type": "object" + }, + "FileSystemSpecialPath": { + "oneOf": [ + { + "properties": { + "kind": { + "enum": [ + "root" + ], + "type": "string" + } + }, + "required": [ + "kind" + ], + "title": "RootFileSystemSpecialPath", + "type": "object" + }, + { + "properties": { + "kind": { + "enum": [ + "minimal" + ], + "type": "string" + } + }, + "required": [ + "kind" + ], + "title": "MinimalFileSystemSpecialPath", + "type": "object" + }, + { + "properties": { + "kind": { + "enum": [ + "project_roots" + ], + "type": "string" + }, + "subpath": { + "anyOf": [ + { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "kind" + ], + "title": "KindFileSystemSpecialPath", + "type": "object" + }, + { + "properties": { + "kind": { + "enum": [ + "tmpdir" + ], + "type": "string" + } + }, + "required": [ + "kind" + ], + "title": "TmpdirFileSystemSpecialPath", + "type": "object" + }, + { + "properties": { + "kind": { + "enum": [ + "slash_tmp" + ], + "type": "string" + } + }, + "required": [ + "kind" + ], + "title": "SlashTmpFileSystemSpecialPath", + "type": "object" + }, + { + "properties": { + "kind": { + "enum": [ + "unknown" + ], + "type": "string" + }, + "path": { + "type": "string" + }, + "subpath": { + "anyOf": [ + { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "kind", + "path" + ], + "type": "object" + } + ] + }, + "FileUpdateChange": { + "properties": { + "diff": { + "type": "string" + }, + "kind": { + "$ref": "#/definitions/v2/PatchChangeKind" + }, + "path": { + "type": "string" + } + }, + "required": [ + "diff", + "kind", + "path" + ], + "type": "object" + }, + "ForcedChatgptWorkspaceIds": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "Backward-compatible API shape for ChatGPT workspace login restrictions." + }, + "ForcedLoginMethod": { + "enum": [ + "chatgpt", + "api" + ], + "type": "string" + }, + "FsChangedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Filesystem watch notification emitted for `fs/watch` subscribers.", + "properties": { + "changedPaths": { + "description": "File or directory paths associated with this event.", + "items": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": "array" + }, + "watchId": { + "description": "Watch identifier previously provided to `fs/watch`.", + "type": "string" + } + }, + "required": [ + "changedPaths", + "watchId" + ], + "title": "FsChangedNotification", + "type": "object" + }, + "FsCopyParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Copy a file or directory tree on the host filesystem.", + "properties": { + "destinationPath": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute destination path." + }, + "recursive": { + "description": "Required for directory copies; ignored for file copies.", + "type": "boolean" + }, + "sourcePath": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute source path." + } + }, + "required": [ + "destinationPath", + "sourcePath" + ], + "title": "FsCopyParams", + "type": "object" + }, + "FsCopyResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Successful response for `fs/copy`.", + "title": "FsCopyResponse", + "type": "object" + }, + "FsCreateDirectoryParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Create a directory on the host filesystem.", + "properties": { + "path": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute directory path to create." + }, + "recursive": { + "description": "Whether parent directories should also be created. Defaults to `true`.", + "type": [ + "boolean", + "null" + ] + } + }, + "required": [ + "path" + ], + "title": "FsCreateDirectoryParams", + "type": "object" + }, + "FsCreateDirectoryResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Successful response for `fs/createDirectory`.", + "title": "FsCreateDirectoryResponse", + "type": "object" + }, + "FsGetMetadataParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Request metadata for an absolute path.", + "properties": { + "path": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute path to inspect." + } + }, + "required": [ + "path" + ], + "title": "FsGetMetadataParams", + "type": "object" + }, + "FsGetMetadataResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Metadata returned by `fs/getMetadata`.", + "properties": { + "createdAtMs": { + "description": "File creation time in Unix milliseconds when available, otherwise `0`.", + "format": "int64", + "type": "integer" + }, + "isDirectory": { + "description": "Whether the path resolves to a directory.", + "type": "boolean" + }, + "isFile": { + "description": "Whether the path resolves to a regular file.", + "type": "boolean" + }, + "isSymlink": { + "description": "Whether the path itself is a symbolic link.", + "type": "boolean" + }, + "modifiedAtMs": { + "description": "File modification time in Unix milliseconds when available, otherwise `0`.", + "format": "int64", + "type": "integer" + } + }, + "required": [ + "createdAtMs", + "isDirectory", + "isFile", + "isSymlink", + "modifiedAtMs" + ], + "title": "FsGetMetadataResponse", + "type": "object" + }, + "FsReadDirectoryEntry": { + "description": "A directory entry returned by `fs/readDirectory`.", + "properties": { + "fileName": { + "description": "Direct child entry name only, not an absolute or relative path.", + "type": "string" + }, + "isDirectory": { + "description": "Whether this entry resolves to a directory.", + "type": "boolean" + }, + "isFile": { + "description": "Whether this entry resolves to a regular file.", + "type": "boolean" + } + }, + "required": [ + "fileName", + "isDirectory", + "isFile" + ], + "type": "object" + }, + "FsReadDirectoryParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "List direct child names for a directory.", + "properties": { + "path": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute directory path to read." + } + }, + "required": [ + "path" + ], + "title": "FsReadDirectoryParams", + "type": "object" + }, + "FsReadDirectoryResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Directory entries returned by `fs/readDirectory`.", + "properties": { + "entries": { + "description": "Direct child entries in the requested directory.", + "items": { + "$ref": "#/definitions/v2/FsReadDirectoryEntry" + }, + "type": "array" + } + }, + "required": [ + "entries" + ], + "title": "FsReadDirectoryResponse", + "type": "object" + }, + "FsReadFileParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Read a file from the host filesystem.", + "properties": { + "path": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute path to read." + } + }, + "required": [ + "path" + ], + "title": "FsReadFileParams", + "type": "object" + }, + "FsReadFileResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Base64-encoded file contents returned by `fs/readFile`.", + "properties": { + "dataBase64": { + "description": "File contents encoded as base64.", + "type": "string" + } + }, + "required": [ + "dataBase64" + ], + "title": "FsReadFileResponse", + "type": "object" + }, + "FsRemoveParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Remove a file or directory tree from the host filesystem.", + "properties": { + "force": { + "description": "Whether missing paths should be ignored. Defaults to `true`.", + "type": [ + "boolean", + "null" + ] + }, + "path": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute path to remove." + }, + "recursive": { + "description": "Whether directory removal should recurse. Defaults to `true`.", + "type": [ + "boolean", + "null" + ] + } + }, + "required": [ + "path" + ], + "title": "FsRemoveParams", + "type": "object" + }, + "FsRemoveResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Successful response for `fs/remove`.", + "title": "FsRemoveResponse", + "type": "object" + }, + "FsUnwatchParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Stop filesystem watch notifications for a prior `fs/watch`.", + "properties": { + "watchId": { + "description": "Watch identifier previously provided to `fs/watch`.", + "type": "string" + } + }, + "required": [ + "watchId" + ], + "title": "FsUnwatchParams", + "type": "object" + }, + "FsUnwatchResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Successful response for `fs/unwatch`.", + "title": "FsUnwatchResponse", + "type": "object" + }, + "FsWatchParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Start filesystem watch notifications for an absolute path.", + "properties": { + "path": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute file or directory path to watch." + }, + "watchId": { + "description": "Connection-scoped watch identifier used for `fs/unwatch` and `fs/changed`.", + "type": "string" + } + }, + "required": [ + "path", + "watchId" + ], + "title": "FsWatchParams", + "type": "object" + }, + "FsWatchResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Successful response for `fs/watch`.", + "properties": { + "path": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Canonicalized path associated with the watch." + } + }, + "required": [ + "path" + ], + "title": "FsWatchResponse", + "type": "object" + }, + "FsWriteFileParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Write a file on the host filesystem.", + "properties": { + "dataBase64": { + "description": "File contents encoded as base64.", + "type": "string" + }, + "path": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Absolute path to write." + } + }, + "required": [ + "dataBase64", + "path" + ], + "title": "FsWriteFileParams", + "type": "object" + }, + "FsWriteFileResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Successful response for `fs/writeFile`.", + "title": "FsWriteFileResponse", + "type": "object" + }, + "FunctionCallOutputBody": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "$ref": "#/definitions/v2/FunctionCallOutputContentItem" + }, + "type": "array" + } + ] + }, + "FunctionCallOutputContentItem": { + "description": "Responses API compatible content items that can be returned by a tool call. This is a subset of ContentItem with the types we support as function call outputs.", + "oneOf": [ + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "enum": [ + "input_text" + ], + "title": "InputTextFunctionCallOutputContentItemType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "InputTextFunctionCallOutputContentItem", + "type": "object" + }, + { + "anyOf": [ + { + "properties": { + "image_url": { + "type": "string" + } + }, + "required": [ + "image_url" + ], + "title": "ImageUrlFunctionCallOutputContentItem", + "type": "object" + }, + { + "properties": { + "file_id": { + "type": "string" + } + }, + "required": [ + "file_id" + ], + "title": "FileIdFunctionCallOutputContentItem", + "type": "object" + } + ], + "properties": { + "detail": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ImageDetail" + }, + { + "type": "null" + } + ] + }, + "type": { + "enum": [ + "input_image" + ], + "title": "InputImageFunctionCallOutputContentItemType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "InputImageFunctionCallOutputContentItem", + "type": "object" + }, + { + "properties": { + "audio_url": { + "type": "string" + }, + "type": { + "enum": [ + "input_audio" + ], + "title": "InputAudioFunctionCallOutputContentItemType", + "type": "string" + } + }, + "required": [ + "audio_url", + "type" + ], + "title": "InputAudioFunctionCallOutputContentItem", + "type": "object" + }, + { + "properties": { + "encrypted_content": { + "type": "string" + }, + "type": { + "enum": [ + "encrypted_content" + ], + "title": "EncryptedContentFunctionCallOutputContentItemType", + "type": "string" + } + }, + "required": [ + "encrypted_content", + "type" + ], + "title": "EncryptedContentFunctionCallOutputContentItem", + "type": "object" + } + ] + }, + "GatewayOAuthCancelResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GatewayOAuthCancelResponse", + "type": "object" + }, + "GatewayOAuthChangedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "authUrl": { + "description": "Authorization handoff, sent only to the connection that started login.", + "type": [ + "string", + "null" + ] + }, + "error": { + "type": [ + "string", + "null" + ] + }, + "providerId": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v2/GatewayOAuthStatus" + } + }, + "required": [ + "providerId", + "status" + ], + "title": "GatewayOAuthChangedNotification", + "type": "object" + }, + "GatewayOAuthLoginResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GatewayOAuthLoginResponse", + "type": "object" + }, + "GatewayOAuthReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Current effective gateway policy and credential readiness; never contains credentials.", + "properties": { + "error": { + "type": [ + "string", + "null" + ] + }, + "providerId": { + "type": "string" + }, + "providerName": { + "type": "string" + }, + "required": { + "description": "Whether the selected provider uses gateway OAuth, even when already signed in.", + "type": "boolean" + }, + "status": { + "anyOf": [ + { + "$ref": "#/definitions/v2/GatewayOAuthStatus" + }, + { + "type": "null" + } + ], + "description": "Null when the effective provider does not use gateway OAuth." + } + }, + "required": [ + "providerId", + "providerName", + "required" + ], + "title": "GatewayOAuthReadResponse", + "type": "object" + }, + "GatewayOAuthStatus": { + "enum": [ + "notReady", + "started", + "succeeded", + "failed" + ], + "type": "string" + }, + "GetAccountParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "refreshToken": { + "description": "When `true`, requests a proactive token refresh before returning.\n\nIn managed auth mode this triggers the normal refresh-token flow. In external auth mode this flag is ignored. Clients should refresh tokens themselves and call `account/login/start` with `chatgptAuthTokens`.", + "type": "boolean" + } + }, + "title": "GetAccountParams", + "type": "object" + }, + "GetAccountRateLimitsParams": { + "description": "Usage-read capabilities of the requesting client, never inferred from its experiment arm.", + "properties": { + "excludeResetCreditDetails": { + "description": "Skip the separate reset-credit detail lookup for background usage polls. The usage response still includes the available count; omitted/false preserves detailed reads.", + "type": "boolean" + }, + "supportsLunaReserve": { + "description": "The client supports automatic Luna Reserve fallback. For eligible ChatGPT CLI users, allow the backend to record experiment exposure after ordinary usage is blocked.", + "type": "boolean" + } + }, + "type": "object" + }, + "GetAccountRateLimitsResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "accountId": { + "description": "Account associated with this usage snapshot, when supplied by the backend.", + "type": [ + "string", + "null" + ] + }, + "ordinaryUsageAllowed": { + "description": "Backend permission for ordinary included usage, validated against the active account. Null means unavailable; clients must not infer recovery from percentages or reset times.", + "type": [ + "boolean", + "null" + ] + }, + "rateLimitResetCredits": { + "anyOf": [ + { + "$ref": "#/definitions/v2/RateLimitResetCreditsSummary" + }, + { + "type": "null" + } + ] + }, + "rateLimitUpsell": { + "description": "Optional backend-owned banner from the same usage read. Its nested keys retain the backend's snake_case contract; an absent banner leaves the client's existing UI unchanged." + }, + "rateLimits": { + "allOf": [ + { + "$ref": "#/definitions/v2/RateLimitSnapshot" + } + ], + "description": "Backward-compatible single-bucket view; mirrors the historical payload." + }, + "rateLimitsByLimitId": { + "additionalProperties": { + "$ref": "#/definitions/v2/RateLimitSnapshot" + }, + "description": "Multi-bucket view keyed by metered `limit_id` (for example, `codex`).", + "type": [ + "object", + "null" + ] + } + }, + "required": [ + "rateLimits" + ], + "title": "GetAccountRateLimitsResponse", + "type": "object" + }, + "GetAccountResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "account": { + "anyOf": [ + { + "$ref": "#/definitions/v2/Account" + }, + { + "type": "null" + } + ] + }, + "requiresOpenaiAuth": { + "type": "boolean" + } + }, + "required": [ + "requiresOpenaiAuth" + ], + "title": "GetAccountResponse", + "type": "object" + }, + "GetAccountTokenUsageParams": { + "properties": { + "threadId": { + "description": "When present, read estimated usage for this thread instead of account-wide token activity.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "GetAccountTokenUsageResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "dailyUsageBuckets": { + "items": { + "$ref": "#/definitions/v2/AccountTokenUsageDailyBucket" + }, + "type": [ + "array", + "null" + ] + }, + "summary": { + "$ref": "#/definitions/v2/AccountTokenUsageSummary" + }, + "threadUsage": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadUsage" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Estimated usage when a thread was requested and its billing route is available." + } + }, + "required": [ + "summary" + ], + "title": "GetAccountTokenUsageResponse", + "type": "object" + }, + "GetWorkspaceMessagesResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "featureEnabled": { + "description": "Whether the workspace-message backend route is available for this client.", + "type": "boolean" + }, + "messages": { + "description": "Active workspace messages returned by the backend.", + "items": { + "$ref": "#/definitions/v2/WorkspaceMessage" + }, + "type": "array" + } + }, + "required": [ + "featureEnabled", + "messages" + ], + "title": "GetWorkspaceMessagesResponse", + "type": "object" + }, + "GitInfo": { + "properties": { + "branch": { + "type": [ + "string", + "null" + ] + }, + "originUrl": { + "type": [ + "string", + "null" + ] + }, + "sha": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "GuardianApprovalReview": { + "description": "[UNSTABLE] Temporary approval auto-review payload used by `item/autoApprovalReview/*` notifications. This shape is expected to change soon.", + "properties": { + "rationale": { + "type": [ + "string", + "null" + ] + }, + "riskLevel": { + "anyOf": [ + { + "$ref": "#/definitions/v2/GuardianRiskLevel" + }, + { + "type": "null" + } + ] + }, + "status": { + "$ref": "#/definitions/v2/GuardianApprovalReviewStatus" + }, + "userAuthorization": { + "anyOf": [ + { + "$ref": "#/definitions/v2/GuardianUserAuthorization" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "status" + ], + "type": "object" + }, + "GuardianApprovalReviewAction": { + "oneOf": [ + { + "properties": { + "command": { + "type": "string" + }, + "cwd": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "source": { + "$ref": "#/definitions/v2/GuardianCommandSource" + }, + "type": { + "enum": [ + "command" + ], + "title": "CommandGuardianApprovalReviewActionType", + "type": "string" + } + }, + "required": [ + "command", + "cwd", + "source", + "type" + ], + "title": "CommandGuardianApprovalReviewAction", + "type": "object" + }, + { + "properties": { + "argv": { + "items": { + "type": "string" + }, + "type": "array" + }, + "cwd": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "program": { + "type": "string" + }, + "source": { + "$ref": "#/definitions/v2/GuardianCommandSource" + }, + "type": { + "enum": [ + "execve" + ], + "title": "ExecveGuardianApprovalReviewActionType", + "type": "string" + } + }, + "required": [ + "argv", + "cwd", + "program", + "source", + "type" + ], + "title": "ExecveGuardianApprovalReviewAction", + "type": "object" + }, + { + "description": "A child approval for input to an existing command execution item.", + "properties": { + "approvalId": { + "type": "string" + }, + "cwd": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "processId": { + "type": "string" + }, + "stdin": { + "type": "string" + }, + "type": { + "enum": [ + "writeStdin" + ], + "title": "WriteStdinGuardianApprovalReviewActionType", + "type": "string" + } + }, + "required": [ + "approvalId", + "cwd", + "processId", + "stdin", + "type" + ], + "title": "WriteStdinGuardianApprovalReviewAction", + "type": "object" + }, + { + "properties": { + "cwd": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "files": { + "items": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": "array" + }, + "type": { + "enum": [ + "applyPatch" + ], + "title": "ApplyPatchGuardianApprovalReviewActionType", + "type": "string" + } + }, + "required": [ + "cwd", + "files", + "type" + ], + "title": "ApplyPatchGuardianApprovalReviewAction", + "type": "object" + }, + { + "properties": { + "host": { + "type": "string" + }, + "port": { + "format": "uint16", + "minimum": 0.0, + "type": "integer" + }, + "protocol": { + "$ref": "#/definitions/v2/NetworkApprovalProtocol" + }, + "target": { + "type": "string" + }, + "type": { + "enum": [ + "networkAccess" + ], + "title": "NetworkAccessGuardianApprovalReviewActionType", + "type": "string" + } + }, + "required": [ + "host", + "port", + "protocol", + "target", + "type" + ], + "title": "NetworkAccessGuardianApprovalReviewAction", + "type": "object" + }, + { + "properties": { + "connectorId": { + "type": [ + "string", + "null" + ] + }, + "connectorName": { + "type": [ + "string", + "null" + ] + }, + "server": { + "type": "string" + }, + "toolName": { + "type": "string" + }, + "toolTitle": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "mcpToolCall" + ], + "title": "McpToolCallGuardianApprovalReviewActionType", + "type": "string" + } + }, + "required": [ + "server", + "toolName", + "type" + ], + "title": "McpToolCallGuardianApprovalReviewAction", + "type": "object" + }, + { + "properties": { + "permissions": { + "$ref": "#/definitions/v2/RequestPermissionProfile" + }, + "reason": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "requestPermissions" + ], + "title": "RequestPermissionsGuardianApprovalReviewActionType", + "type": "string" + } + }, + "required": [ + "permissions", + "type" + ], + "title": "RequestPermissionsGuardianApprovalReviewAction", + "type": "object" + } + ] + }, + "GuardianApprovalReviewStatus": { + "description": "[UNSTABLE] Lifecycle state for an approval auto-review.", + "enum": [ + "inProgress", + "approved", + "denied", + "timedOut", + "aborted" + ], + "type": "string" + }, + "GuardianCommandSource": { + "enum": [ + "shell", + "unifiedExec" + ], + "type": "string" + }, + "GuardianRiskLevel": { + "description": "[UNSTABLE] Risk level assigned by approval auto-review.", + "enum": [ + "low", + "medium", + "high", + "critical" + ], + "type": "string" + }, + "GuardianUserAuthorization": { + "description": "[UNSTABLE] Authorization level assigned by approval auto-review.", + "enum": [ + "unknown", + "low", + "medium", + "high" + ], + "type": "string" + }, + "GuardianWarningNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "message": { + "description": "Concise guardian warning message for the user.", + "type": "string" + }, + "threadId": { + "description": "Thread target for the guardian warning.", + "type": "string" + } + }, + "required": [ + "message", + "threadId" + ], + "title": "GuardianWarningNotification", + "type": "object" + }, + "HookCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "run": { + "$ref": "#/definitions/v2/HookRunSummary" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "run", + "threadId" + ], + "title": "HookCompletedNotification", + "type": "object" + }, + "HookErrorInfo": { + "properties": { + "message": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "message", + "path" + ], + "type": "object" + }, + "HookEventName": { + "enum": [ + "preToolUse", + "permissionRequest", + "postToolUse", + "preCompact", + "postCompact", + "sessionStart", + "sessionEnd", + "userPromptSubmit", + "subagentStart", + "subagentStop", + "stop", + "interrupt" + ], + "type": "string" + }, + "HookExecutionMode": { + "enum": [ + "sync", + "async" + ], + "type": "string" + }, + "HookHandlerType": { + "enum": [ + "command", + "mcpTool", + "prompt", + "agent" + ], + "type": "string" + }, + "HookMetadata": { + "oneOf": [ + { + "properties": { + "async": { + "default": false, + "type": "boolean" + }, + "command": { + "type": "string" + }, + "handlerType": { + "enum": [ + "command" + ], + "type": "string" + } + }, + "required": [ + "command", + "handlerType" + ], + "type": "object" + }, + { + "properties": { + "handlerType": { + "enum": [ + "mcpTool" + ], + "type": "string" + }, + "server": { + "type": "string" + }, + "tool": { + "type": "string" + } + }, + "required": [ + "handlerType", + "server", + "tool" + ], + "type": "object" + }, + { + "properties": { + "handlerType": { + "enum": [ + "prompt" + ], + "type": "string" + } + }, + "required": [ + "handlerType" + ], + "title": "PromptHookMetadata", + "type": "object" + }, + { + "properties": { + "handlerType": { + "enum": [ + "agent" + ], + "type": "string" + } + }, + "required": [ + "handlerType" + ], + "title": "AgentHookMetadata", + "type": "object" + } + ], + "properties": { + "additionalContextLimit": { + "description": "Configured `additionalContext` spill threshold. `null` uses 2,500 tokens; `0` disables spilling.", + "format": "uint", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "currentHash": { + "type": "string" + }, + "displayOrder": { + "format": "int64", + "type": "integer" + }, + "enabled": { + "type": "boolean" + }, + "eventName": { + "$ref": "#/definitions/v2/HookEventName" + }, + "isManaged": { + "type": "boolean" + }, + "key": { + "type": "string" + }, + "matcher": { + "type": [ + "string", + "null" + ] + }, + "pluginId": { + "type": [ + "string", + "null" + ] + }, + "source": { + "$ref": "#/definitions/v2/HookSource" + }, + "sourcePath": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "statusMessage": { + "type": [ + "string", + "null" + ] + }, + "timeoutSec": { + "format": "uint64", + "minimum": 0.0, + "type": "integer" + }, + "trustStatus": { + "$ref": "#/definitions/v2/HookTrustStatus" + } + }, + "required": [ + "currentHash", + "displayOrder", + "enabled", + "eventName", + "isManaged", + "key", + "source", + "sourcePath", + "timeoutSec", + "trustStatus" + ], + "type": "object" + }, + "HookMigration": { + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "HookOutputEntry": { + "properties": { + "kind": { + "$ref": "#/definitions/v2/HookOutputEntryKind" + }, + "text": { + "type": "string" + } + }, + "required": [ + "kind", + "text" + ], + "type": "object" + }, + "HookOutputEntryKind": { + "enum": [ + "warning", + "stop", + "feedback", + "context", + "error" + ], + "type": "string" + }, + "HookPromptFragment": { + "properties": { + "hookRunId": { + "type": "string" + }, + "text": { + "type": "string" + } + }, + "required": [ + "hookRunId", + "text" + ], + "type": "object" + }, + "HookRunStatus": { + "enum": [ + "running", + "completed", + "failed", + "blocked", + "stopped" + ], + "type": "string" + }, + "HookRunSummary": { + "properties": { + "completedAt": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "displayOrder": { + "format": "int64", + "type": "integer" + }, + "durationMs": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "entries": { + "items": { + "$ref": "#/definitions/v2/HookOutputEntry" + }, + "type": "array" + }, + "eventName": { + "$ref": "#/definitions/v2/HookEventName" + }, + "executionMode": { + "$ref": "#/definitions/v2/HookExecutionMode" + }, + "handlerType": { + "$ref": "#/definitions/v2/HookHandlerType" + }, + "id": { + "type": "string" + }, + "scope": { + "$ref": "#/definitions/v2/HookScope" + }, + "source": { + "allOf": [ + { + "$ref": "#/definitions/v2/HookSource" + } + ], + "default": "unknown" + }, + "sourcePath": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "startedAt": { + "format": "int64", + "type": "integer" + }, + "status": { + "$ref": "#/definitions/v2/HookRunStatus" + }, + "statusMessage": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "displayOrder", + "entries", + "eventName", + "executionMode", + "handlerType", + "id", + "scope", + "sourcePath", + "startedAt", + "status" + ], + "type": "object" + }, + "HookScope": { + "enum": [ + "thread", + "turn" + ], + "type": "string" + }, + "HookSource": { + "enum": [ + "system", + "user", + "project", + "mdm", + "sessionFlags", + "plugin", + "cloudRequirements", + "cloudManagedConfig", + "legacyManagedConfigFile", + "legacyManagedConfigMdm", + "unknown" + ], + "type": "string" + }, + "HookStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "run": { + "$ref": "#/definitions/v2/HookRunSummary" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "run", + "threadId" + ], + "title": "HookStartedNotification", + "type": "object" + }, + "HookTrustStatus": { + "enum": [ + "managed", + "untrusted", + "trusted", + "modified" + ], + "type": "string" + }, + "HooksListEntry": { + "properties": { + "cwd": { + "type": "string" + }, + "errors": { + "items": { + "$ref": "#/definitions/v2/HookErrorInfo" + }, + "type": "array" + }, + "hooks": { + "items": { + "$ref": "#/definitions/v2/HookMetadata" + }, + "type": "array" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "cwd", + "errors", + "hooks", + "warnings" + ], + "type": "object" + }, + "HooksListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cwds": { + "description": "When empty, defaults to the current session working directory.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "title": "HooksListParams", + "type": "object" + }, + "HooksListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/HooksListEntry" + }, + "type": "array" + } + }, + "required": [ + "data" + ], + "title": "HooksListResponse", + "type": "object" + }, + "ImageDetail": { + "enum": [ + "auto", + "low", + "high", + "original" + ], + "type": "string" + }, + "ImageGenerationFailure": { + "oneOf": [ + { + "properties": { + "limitId": { + "type": "string" + }, + "resetsAt": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "type": { + "enum": [ + "usageLimitExceeded" + ], + "title": "UsageLimitExceededImageGenerationFailureType", + "type": "string" + } + }, + "required": [ + "limitId", + "type" + ], + "title": "UsageLimitExceededImageGenerationFailure", + "type": "object" + } + ] + }, + "InAppBrowserRequirements": { + "properties": { + "allowExternalBrowserSettingsImport": { + "type": [ + "boolean", + "null" + ] + } + }, + "type": "object" + }, + "InputModality": { + "description": "Canonical user-input modality tags advertised by a model.", + "oneOf": [ + { + "description": "Plain text turns and tool payloads.", + "enum": [ + "text" + ], + "type": "string" + }, + { + "description": "Image attachments included in user turns.", + "enum": [ + "image" + ], + "type": "string" + }, + { + "description": "Audio attachments included in user turns.", + "enum": [ + "audio" + ], + "type": "string" + } + ] + }, + "InstalledApp": { + "description": "Installed connector runtime state.", + "properties": { + "callable": { + "description": "Whether the connector is enabled and has a non-synthetic, model-visible tool allowed by effective MCP and app/tool policy in the committed runtime snapshot.", + "type": "boolean" + }, + "enabled": { + "description": "Effective enabled state after applying global, workspace, local, and managed configuration at read time.", + "type": "boolean" + }, + "id": { + "type": "string" + }, + "runtimeName": { + "description": "Best-effort name carried by the runtime tool catalog. Canonical app metadata remains owned by `app/read`.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "callable", + "enabled", + "id" + ], + "type": "object" + }, + "InternalChatMessageMetadataPassthrough": { + "description": "Internal Responses API passthrough metadata copied into underlying chat messages.\n\nResponses API strongly types this payload. Do not modify it without first getting API approval and making the corresponding Responses API change.", + "properties": { + "turn_id": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "ItemCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "completedAtMs": { + "description": "Unix timestamp (in milliseconds) when this item lifecycle completed.", + "format": "int64", + "type": "integer" + }, + "item": { + "$ref": "#/definitions/v2/ThreadItem" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "completedAtMs", + "item", + "threadId", + "turnId" + ], + "title": "ItemCompletedNotification", + "type": "object" + }, + "ItemGuardianApprovalReviewCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for approval auto-review. This shape is expected to change soon.", + "properties": { + "action": { + "$ref": "#/definitions/v2/GuardianApprovalReviewAction" + }, + "completedAtMs": { + "description": "Unix timestamp (in milliseconds) when this review completed.", + "format": "int64", + "type": "integer" + }, + "decisionSource": { + "$ref": "#/definitions/v2/AutoReviewDecisionSource" + }, + "review": { + "$ref": "#/definitions/v2/GuardianApprovalReview" + }, + "reviewId": { + "description": "Stable identifier for this review.", + "type": "string" + }, + "startedAtMs": { + "description": "Unix timestamp (in milliseconds) when this review started.", + "format": "int64", + "type": "integer" + }, + "targetItemId": { + "description": "Identifier for the reviewed item or tool call when one exists.\n\nIn most cases, one review maps to one target item. The exceptions are - execve reviews, where a single command may contain multiple execve calls to review (only possible when using the shell_zsh_fork feature) - stdin reviews, which refer to the existing parent command item and have a separate approval ID in the action payload - network policy reviews, where there is no target item\n\nA network call is triggered by a CommandExecution item, so having a target_item_id set to the CommandExecution item would be misleading because the review is about the network call, not the command execution. Therefore, target_item_id is set to None for network policy reviews.", + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "action", + "completedAtMs", + "decisionSource", + "review", + "reviewId", + "startedAtMs", + "threadId", + "turnId" + ], + "title": "ItemGuardianApprovalReviewCompletedNotification", + "type": "object" + }, + "ItemGuardianApprovalReviewStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "[UNSTABLE] Temporary notification payload for approval auto-review. This shape is expected to change soon.", + "properties": { + "action": { + "$ref": "#/definitions/v2/GuardianApprovalReviewAction" + }, + "review": { + "$ref": "#/definitions/v2/GuardianApprovalReview" + }, + "reviewId": { + "description": "Stable identifier for this review.", + "type": "string" + }, + "startedAtMs": { + "description": "Unix timestamp (in milliseconds) when this review started.", + "format": "int64", + "type": "integer" + }, + "targetItemId": { + "description": "Identifier for the reviewed item or tool call when one exists.\n\nIn most cases, one review maps to one target item. The exceptions are - execve reviews, where a single command may contain multiple execve calls to review (only possible when using the shell_zsh_fork feature) - stdin reviews, which refer to the existing parent command item and have a separate approval ID in the action payload - network policy reviews, where there is no target item\n\nA network call is triggered by a CommandExecution item, so having a target_item_id set to the CommandExecution item would be misleading because the review is about the network call, not the command execution. Therefore, target_item_id is set to None for network policy reviews.", + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "action", + "review", + "reviewId", + "startedAtMs", + "threadId", + "turnId" + ], + "title": "ItemGuardianApprovalReviewStartedNotification", + "type": "object" + }, + "ItemStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "item": { + "$ref": "#/definitions/v2/ThreadItem" + }, + "startedAtMs": { + "description": "Unix timestamp (in milliseconds) when this item lifecycle started.", + "format": "int64", + "type": "integer" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "item", + "startedAtMs", + "threadId", + "turnId" + ], + "title": "ItemStartedNotification", + "type": "object" + }, + "LegacyAppPathString": { + "type": "string" + }, + "ListMcpServerStatusParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cursor": { + "description": "Opaque pagination cursor returned by a previous call.", + "type": [ + "string", + "null" + ] + }, + "detail": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpServerStatusDetail" + }, + { + "type": "null" + } + ], + "description": "Controls how much MCP inventory data to fetch for each server. Defaults to `Full` when omitted." + }, + "limit": { + "description": "Optional page size; defaults to a server-defined value.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "threadId": { + "type": [ + "string", + "null" + ] + } + }, + "title": "ListMcpServerStatusParams", + "type": "object" + }, + "ListMcpServerStatusResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/McpServerStatus" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item. If None, there are no more items to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ListMcpServerStatusResponse", + "type": "object" + }, + "LocalShellAction": { + "oneOf": [ + { + "properties": { + "command": { + "items": { + "type": "string" + }, + "type": "array" + }, + "env": { + "additionalProperties": { + "type": "string" + }, + "type": [ + "object", + "null" + ] + }, + "timeout_ms": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "type": { + "enum": [ + "exec" + ], + "title": "ExecLocalShellActionType", + "type": "string" + }, + "user": { + "type": [ + "string", + "null" + ] + }, + "working_directory": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "command", + "type" + ], + "title": "ExecLocalShellAction", + "type": "object" + } + ] + }, + "LocalShellStatus": { + "enum": [ + "completed", + "in_progress", + "incomplete" + ], + "type": "string" + }, + "LoginAccountParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "oneOf": [ + { + "properties": { + "apiKey": { + "type": "string" + }, + "type": { + "enum": [ + "apiKey" + ], + "title": "ApiKeyv2::LoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "apiKey", + "type" + ], + "title": "ApiKeyv2::LoginAccountParams", + "type": "object" + }, + { + "properties": { + "appBrand": { + "anyOf": [ + { + "$ref": "#/definitions/v2/LoginAppBrand" + }, + { + "type": "null" + } + ], + "default": null + }, + "codexStreamlinedLogin": { + "type": "boolean" + }, + "type": { + "enum": [ + "chatgpt" + ], + "title": "Chatgptv2::LoginAccountParamsType", + "type": "string" + }, + "useHostedLoginSuccessPage": { + "type": "boolean" + } + }, + "required": [ + "type" + ], + "title": "Chatgptv2::LoginAccountParams", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "chatgptDeviceCode" + ], + "title": "ChatgptDeviceCodev2::LoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "ChatgptDeviceCodev2::LoginAccountParams", + "type": "object" + }, + { + "description": "[UNSTABLE] FOR OPENAI INTERNAL USE ONLY - DO NOT USE. The access token must contain the same scopes that Codex-managed ChatGPT auth tokens have.", + "properties": { + "accessToken": { + "description": "Access token (JWT) supplied by the client. This token is used for backend API requests and email extraction.", + "type": "string" + }, + "chatgptAccountId": { + "description": "Workspace/account identifier supplied by the client.", + "type": "string" + }, + "chatgptPlanType": { + "description": "Optional plan type supplied by the client.\n\nWhen `null`, Codex attempts to derive the plan type from access-token claims. If unavailable, the plan defaults to `unknown`.", + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "chatgptAuthTokens" + ], + "title": "ChatgptAuthTokensv2::LoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "accessToken", + "chatgptAccountId", + "type" + ], + "title": "ChatgptAuthTokensv2::LoginAccountParams", + "type": "object" + }, + { + "description": "[UNSTABLE] Managed Amazon Bedrock login is experimental.", + "properties": { + "apiKey": { + "type": "string" + }, + "region": { + "type": "string" + }, + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockv2::LoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "apiKey", + "region", + "type" + ], + "title": "AmazonBedrockv2::LoginAccountParams", + "type": "object" + }, + { + "description": "[UNSTABLE] Managed Amazon Bedrock AWS access key login is experimental.", + "properties": { + "accessKeyId": { + "type": "string" + }, + "region": { + "type": "string" + }, + "secretAccessKey": { + "type": "string" + }, + "sessionToken": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "amazonBedrockAccessKeys" + ], + "title": "AmazonBedrockAccessKeysv2::LoginAccountParamsType", + "type": "string" + } + }, + "required": [ + "accessKeyId", + "region", + "secretAccessKey", + "type" + ], + "title": "AmazonBedrockAccessKeysv2::LoginAccountParams", + "type": "object" + } + ], + "title": "LoginAccountParams" + }, + "LoginAccountResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "oneOf": [ + { + "properties": { + "type": { + "enum": [ + "apiKey" + ], + "title": "ApiKeyv2::LoginAccountResponseType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "ApiKeyv2::LoginAccountResponse", + "type": "object" + }, + { + "properties": { + "authUrl": { + "description": "URL the client should open in a browser to initiate the OAuth flow.", + "type": "string" + }, + "loginId": { + "type": "string" + }, + "type": { + "enum": [ + "chatgpt" + ], + "title": "Chatgptv2::LoginAccountResponseType", + "type": "string" + } + }, + "required": [ + "authUrl", + "loginId", + "type" + ], + "title": "Chatgptv2::LoginAccountResponse", + "type": "object" + }, + { + "properties": { + "loginId": { + "type": "string" + }, + "type": { + "enum": [ + "chatgptDeviceCode" + ], + "title": "ChatgptDeviceCodev2::LoginAccountResponseType", + "type": "string" + }, + "userCode": { + "description": "One-time code the user must enter after signing in.", + "type": "string" + }, + "verificationUrl": { + "description": "URL the client should open in a browser to complete device code authorization.", + "type": "string" + } + }, + "required": [ + "loginId", + "type", + "userCode", + "verificationUrl" + ], + "title": "ChatgptDeviceCodev2::LoginAccountResponse", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "chatgptAuthTokens" + ], + "title": "ChatgptAuthTokensv2::LoginAccountResponseType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "ChatgptAuthTokensv2::LoginAccountResponse", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "amazonBedrock" + ], + "title": "AmazonBedrockv2::LoginAccountResponseType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "AmazonBedrockv2::LoginAccountResponse", + "type": "object" + } + ], + "title": "LoginAccountResponse" + }, + "LoginAppBrand": { + "enum": [ + "codex", + "chatgpt" + ], + "type": "string" + }, + "LogoutAccountResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "LogoutAccountResponse", + "type": "object" + }, + "ManagedHooksRequirements": { + "properties": { + "Interrupt": { + "default": [], + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "PermissionRequest": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "PostCompact": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "PostToolUse": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "PreCompact": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "PreToolUse": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "SessionEnd": { + "default": [], + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "SessionStart": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "Stop": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "SubagentStart": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "SubagentStop": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "UserPromptSubmit": { + "items": { + "$ref": "#/definitions/v2/ConfiguredHookMatcherGroup" + }, + "type": "array" + }, + "managedDir": { + "type": [ + "string", + "null" + ] + }, + "windowsManagedDir": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "PermissionRequest", + "PostCompact", + "PostToolUse", + "PreCompact", + "PreToolUse", + "SessionStart", + "Stop", + "SubagentStart", + "SubagentStop", + "UserPromptSubmit" + ], + "type": "object" + }, + "MarketplaceAddParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "refName": { + "type": [ + "string", + "null" + ] + }, + "source": { + "type": "string" + }, + "sparsePaths": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + } + }, + "required": [ + "source" + ], + "title": "MarketplaceAddParams", + "type": "object" + }, + "MarketplaceAddResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "alreadyAdded": { + "type": "boolean" + }, + "installedRoot": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "marketplaceName": { + "type": "string" + } + }, + "required": [ + "alreadyAdded", + "installedRoot", + "marketplaceName" + ], + "title": "MarketplaceAddResponse", + "type": "object" + }, + "MarketplaceInterface": { + "properties": { + "displayName": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "MarketplaceLoadErrorInfo": { + "properties": { + "marketplacePath": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "message": { + "type": "string" + } + }, + "required": [ + "marketplacePath", + "message" + ], + "type": "object" + }, + "MarketplaceRemoveParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "marketplaceName": { + "type": "string" + } + }, + "required": [ + "marketplaceName" + ], + "title": "MarketplaceRemoveParams", + "type": "object" + }, + "MarketplaceRemoveResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "installedRoot": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "marketplaceName": { + "type": "string" + } + }, + "required": [ + "marketplaceName" + ], + "title": "MarketplaceRemoveResponse", + "type": "object" + }, + "MarketplaceUpgradeErrorInfo": { + "properties": { + "marketplaceName": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "marketplaceName", + "message" + ], + "type": "object" + }, + "MarketplaceUpgradeParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "marketplaceName": { + "type": [ + "string", + "null" + ] + } + }, + "title": "MarketplaceUpgradeParams", + "type": "object" + }, + "MarketplaceUpgradeResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "errors": { + "items": { + "$ref": "#/definitions/v2/MarketplaceUpgradeErrorInfo" + }, + "type": "array" + }, + "selectedMarketplaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "upgradedRoots": { + "items": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": "array" + } + }, + "required": [ + "errors", + "selectedMarketplaces", + "upgradedRoots" + ], + "title": "MarketplaceUpgradeResponse", + "type": "object" + }, + "McpAppDisplayMode": { + "enum": [ + "inline", + "fullscreen" + ], + "type": "string" + }, + "McpAppUi": { + "description": "UI resource and display preference for model invocations, captured from the tool descriptor.", + "properties": { + "preferredModelDisplayMode": { + "$ref": "#/definitions/v2/McpAppDisplayMode" + }, + "resourceUri": { + "type": "string" + } + }, + "required": [ + "preferredModelDisplayMode", + "resourceUri" + ], + "type": "object" + }, + "McpAuthStatus": { + "enum": [ + "unknown", + "unsupported", + "notLoggedIn", + "bearerToken", + "oAuth" + ], + "type": "string" + }, + "McpResourceReadParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "connectorId": { + "type": [ + "string", + "null" + ] + }, + "originCallId": { + "description": "Originating MCP tool call used to select the resource's app.", + "type": [ + "string", + "null" + ] + }, + "server": { + "type": "string" + }, + "target": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpResourceReadTarget" + }, + { + "type": "null" + } + ], + "description": "Explicit hosted app/account. Omit to retain legacy resource discovery." + }, + "threadId": { + "type": [ + "string", + "null" + ] + }, + "uri": { + "type": "string" + } + }, + "required": [ + "server", + "uri" + ], + "title": "McpResourceReadParams", + "type": "object" + }, + "McpResourceReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "contents": { + "items": { + "$ref": "#/definitions/v2/ResourceContent" + }, + "type": "array" + }, + "originCallId": { + "description": "Originating call when the server applied app-specific resource scoping.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "contents" + ], + "title": "McpResourceReadResponse", + "type": "object" + }, + "McpResourceReadTarget": { + "properties": { + "connectorId": { + "type": "string" + }, + "linkId": { + "description": "Null explicitly requests no-auth access, subject to the app's resource policy.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "connectorId", + "linkId" + ], + "type": "object" + }, + "McpServerConnectionStatus": { + "enum": [ + "notStarted", + "starting", + "connected", + "authenticationRequired", + "failed", + "cancelled", + "disabled" + ], + "type": "string" + }, + "McpServerEventNotification": { + "properties": { + "method": { + "type": "string" + }, + "params": true + }, + "required": [ + "method", + "params" + ], + "type": "object" + }, + "McpServerEventStreamNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "notification": { + "$ref": "#/definitions/v2/McpServerEventNotification" + }, + "subscriptionId": { + "type": "string" + } + }, + "required": [ + "notification", + "subscriptionId" + ], + "title": "McpServerEventStreamNotification", + "type": "object" + }, + "McpServerInfo": { + "description": "Presentation metadata advertised by an initialized MCP server.", + "properties": { + "description": { + "type": [ + "string", + "null" + ] + }, + "icons": { + "items": true, + "type": [ + "array", + "null" + ] + }, + "name": { + "type": "string" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "version": { + "type": "string" + }, + "websiteUrl": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + }, + "McpServerMigration": { + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "McpServerOauthClientRegistration": { + "enum": [ + "auto", + "cimd", + "dcr" + ], + "type": "string" + }, + "McpServerOauthLoginCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "error": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "success": { + "type": "boolean" + }, + "threadId": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "name", + "success" + ], + "title": "McpServerOauthLoginCompletedNotification", + "type": "object" + }, + "McpServerOauthLoginParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "clientRegistration": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpServerOauthClientRegistration" + }, + { + "type": "null" + } + ], + "description": "Registration strategy for this login only; omission selects automatic discovery." + }, + "name": { + "type": "string" + }, + "scopes": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "threadId": { + "type": [ + "string", + "null" + ] + }, + "timeoutSecs": { + "format": "int64", + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "name" + ], + "title": "McpServerOauthLoginParams", + "type": "object" + }, + "McpServerOauthLoginResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "authorizationUrl": { + "type": "string" + } + }, + "required": [ + "authorizationUrl" + ], + "title": "McpServerOauthLoginResponse", + "type": "object" + }, + "McpServerRefreshResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "McpServerRefreshResponse", + "type": "object" + }, + "McpServerStartupFailureReason": { + "enum": [ + "reauthenticationRequired" + ], + "type": "string" + }, + "McpServerStartupState": { + "enum": [ + "starting", + "ready", + "failed", + "cancelled" + ], + "type": "string" + }, + "McpServerStatus": { + "properties": { + "authStatus": { + "$ref": "#/definitions/v2/McpAuthStatus" + }, + "httpOrigin": { + "description": "HTTP origin of the effective configured endpoint, including plugin servers. Excludes credentials, path, query, and fragment; null for non-HTTP transports.", + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "pluginId": { + "type": [ + "string", + "null" + ] + }, + "resourceTemplates": { + "items": { + "$ref": "#/definitions/v2/ResourceTemplate" + }, + "type": "array" + }, + "resources": { + "items": { + "$ref": "#/definitions/v2/Resource" + }, + "type": "array" + }, + "runtimeStatus": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpServerConnectionStatus" + }, + { + "type": "null" + } + ], + "description": "Current thread-runtime connection state; null when unavailable or the configuration changed." + }, + "serverCapabilities": { + "description": "Capabilities advertised by the initialized MCP server; null when unavailable." + }, + "serverInfo": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpServerInfo" + }, + { + "type": "null" + } + ] + }, + "tools": { + "additionalProperties": { + "$ref": "#/definitions/v2/Tool" + }, + "type": "object" + }, + "toolsError": { + "description": "Tool discovery failed and no catalog was returned. Null when a catalog is returned, including cached or empty catalogs.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "authStatus", + "name", + "resourceTemplates", + "resources", + "tools" + ], + "type": "object" + }, + "McpServerStatusDetail": { + "enum": [ + "full", + "toolsAndAuthOnly" + ], + "type": "string" + }, + "McpServerStatusUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "error": { + "type": [ + "string", + "null" + ] + }, + "failureReason": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpServerStartupFailureReason" + }, + { + "type": "null" + } + ] + }, + "name": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v2/McpServerStartupState" + }, + "threadId": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "name", + "status" + ], + "title": "McpServerStatusUpdatedNotification", + "type": "object" + }, + "McpServerToolCallParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "_meta": true, + "arguments": true, + "server": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "tool": { + "type": "string" + } + }, + "required": [ + "server", + "threadId", + "tool" + ], + "title": "McpServerToolCallParams", + "type": "object" + }, + "McpServerToolCallResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "_meta": true, + "content": { + "items": true, + "type": "array" + }, + "isError": { + "type": [ + "boolean", + "null" + ] + }, + "structuredContent": true + }, + "required": [ + "content" + ], + "title": "McpServerToolCallResponse", + "type": "object" + }, + "McpToolCallAppContext": { + "properties": { + "actionName": { + "type": [ + "string", + "null" + ] + }, + "appName": { + "type": [ + "string", + "null" + ] + }, + "connectorId": { + "type": "string" + }, + "linkId": { + "type": [ + "string", + "null" + ] + }, + "resourceUri": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "connectorId" + ], + "type": "object" + }, + "McpToolCallError": { + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "McpToolCallProgressNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "itemId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "message", + "threadId", + "turnId" + ], + "title": "McpToolCallProgressNotification", + "type": "object" + }, + "McpToolCallResult": { + "properties": { + "_meta": true, + "content": { + "items": true, + "type": "array" + }, + "structuredContent": true + }, + "required": [ + "content" + ], + "type": "object" + }, + "McpToolCallStatus": { + "enum": [ + "inProgress", + "completed", + "failed" + ], + "type": "string" + }, + "MemoryCitation": { + "properties": { + "entries": { + "items": { + "$ref": "#/definitions/v2/MemoryCitationEntry" + }, + "type": "array" + }, + "threadIds": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "entries", + "threadIds" + ], + "type": "object" + }, + "MemoryCitationEntry": { + "properties": { + "lineEnd": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "lineStart": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "note": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "lineEnd", + "lineStart", + "note", + "path" + ], + "type": "object" + }, + "MergeStrategy": { + "enum": [ + "replace", + "upsert" + ], + "type": "string" + }, + "MessagePhase": { + "description": "Classifies an assistant message as interim commentary or final answer text.\n\nProviders do not emit this consistently, so callers must treat `None` as \"phase unknown\" and keep compatibility behavior for legacy models.", + "oneOf": [ + { + "description": "Mid-turn assistant text (for example preamble/progress narration).\n\nAdditional tool calls or assistant output may follow before turn completion.", + "enum": [ + "commentary" + ], + "type": "string" + }, + { + "description": "The assistant's terminal answer text for the current turn.", + "enum": [ + "final_answer" + ], + "type": "string" + } + ] + }, + "MigrationDetails": { + "properties": { + "commands": { + "default": [], + "items": { + "$ref": "#/definitions/v2/CommandMigration" + }, + "type": "array" + }, + "hooks": { + "default": [], + "items": { + "$ref": "#/definitions/v2/HookMigration" + }, + "type": "array" + }, + "mcpServers": { + "default": [], + "items": { + "$ref": "#/definitions/v2/McpServerMigration" + }, + "type": "array" + }, + "memory": { + "items": { + "type": "string" + }, + "type": "array" + }, + "plugins": { + "default": [], + "items": { + "$ref": "#/definitions/v2/PluginsMigration" + }, + "type": "array" + }, + "sessions": { + "default": [], + "items": { + "$ref": "#/definitions/v2/SessionMigration" + }, + "type": "array" + }, + "skills": { + "default": [], + "items": { + "$ref": "#/definitions/v2/SkillMigration" + }, + "type": "array" + }, + "subagents": { + "default": [], + "items": { + "$ref": "#/definitions/v2/SubagentMigration" + }, + "type": "array" + } + }, + "type": "object" + }, + "MisalignmentErrorDetails": { + "properties": { + "detailedExplanation": { + "description": "A substantive localized explanation is required before offering continuation.", + "type": [ + "string", + "null" + ] + }, + "errorType": { + "description": "Open-ended classification; clients must accept categories added by Responses.", + "type": [ + "string", + "null" + ] + }, + "steer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/MisalignmentSteer" + }, + { + "type": "null" + } + ], + "description": "Instruction to submit as the next turn's user input if continuation is confirmed." + } + }, + "type": "object" + }, + "MisalignmentSteer": { + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "ModeKind": { + "description": "Initial collaboration mode to use when the TUI starts.", + "enum": [ + "plan", + "default" + ], + "type": "string" + }, + "Model": { + "properties": { + "additionalSpeedTiers": { + "default": [], + "description": "Deprecated: use `serviceTiers` instead.", + "items": { + "type": "string" + }, + "type": "array" + }, + "availabilityNux": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ModelAvailabilityNux" + }, + { + "type": "null" + } + ] + }, + "availableAccessPrograms": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ModelAccessPrograms" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Null when the catalog does not provide access-program metadata." + }, + "defaultReasoningEffort": { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + "defaultServiceTier": { + "default": null, + "description": "Catalog default service tier id for this model, when one is configured.", + "type": [ + "string", + "null" + ] + }, + "description": { + "type": "string" + }, + "displayName": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "inputModalities": { + "default": [ + "text", + "image" + ], + "items": { + "$ref": "#/definitions/v2/InputModality" + }, + "type": "array" + }, + "isDefault": { + "type": "boolean" + }, + "model": { + "type": "string" + }, + "modelSpecialty": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "multiAgentVersion": { + "anyOf": [ + { + "$ref": "#/definitions/v2/MultiAgentVersion" + }, + { + "type": "null" + } + ], + "description": "Multi-agent runtime declared by this model, when available." + }, + "serviceTiers": { + "default": [], + "items": { + "$ref": "#/definitions/v2/ModelServiceTier" + }, + "type": "array" + }, + "supportedReasoningEfforts": { + "items": { + "$ref": "#/definitions/v2/ReasoningEffortOption" + }, + "type": "array" + }, + "supportsPersonality": { + "default": false, + "description": "@deprecated Always false; models no longer support personality selection.", + "type": "boolean" + }, + "upgrade": { + "type": [ + "string", + "null" + ] + }, + "upgradeInfo": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ModelUpgradeInfo" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "defaultReasoningEffort", + "description", + "displayName", + "hidden", + "id", + "isDefault", + "model", + "supportedReasoningEfforts" + ], + "type": "object" + }, + "ModelAccessPrograms": { + "description": "Caller-specific explicit access programs advertised by model discovery.", + "properties": { + "cyber": { + "description": "Accepted explicit selections.", + "items": { + "$ref": "#/definitions/v2/CyberAccessProgram" + }, + "type": "array" + } + }, + "required": [ + "cyber" + ], + "type": "object" + }, + "ModelAvailabilityNux": { + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "ModelListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cursor": { + "description": "Opaque pagination cursor returned by a previous call.", + "type": [ + "string", + "null" + ] + }, + "includeHidden": { + "description": "When true, include models that are hidden from the default picker list.", + "type": [ + "boolean", + "null" + ] + }, + "limit": { + "description": "Optional page size; defaults to a reasonable server-side value.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "title": "ModelListParams", + "type": "object" + }, + "ModelListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/Model" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item. If None, there are no more items to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ModelListResponse", + "type": "object" + }, + "ModelProviderCapabilitiesReadParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ModelProviderCapabilitiesReadParams", + "type": "object" + }, + "ModelProviderCapabilitiesReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "imageGeneration": { + "type": "boolean" + }, + "namespaceTools": { + "type": "boolean" + }, + "webSearch": { + "type": "boolean" + } + }, + "required": [ + "imageGeneration", + "namespaceTools", + "webSearch" + ], + "title": "ModelProviderCapabilitiesReadResponse", + "type": "object" + }, + "ModelRerouteReason": { + "enum": [ + "highRiskCyberActivity" + ], + "type": "string" + }, + "ModelReroutedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "fromModel": { + "type": "string" + }, + "reason": { + "$ref": "#/definitions/v2/ModelRerouteReason" + }, + "threadId": { + "type": "string" + }, + "toModel": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "fromModel", + "reason", + "threadId", + "toModel", + "turnId" + ], + "title": "ModelReroutedNotification", + "type": "object" + }, + "ModelSafetyBufferingUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "fasterModel": { + "type": [ + "string", + "null" + ] + }, + "model": { + "type": "string" + }, + "reasons": { + "items": { + "type": "string" + }, + "type": "array" + }, + "showBufferingUi": { + "type": "boolean" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + }, + "useCases": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "model", + "reasons", + "showBufferingUi", + "threadId", + "turnId", + "useCases" + ], + "title": "ModelSafetyBufferingUpdatedNotification", + "type": "object" + }, + "ModelServiceTier": { + "properties": { + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "description", + "id", + "name" + ], + "type": "object" + }, + "ModelUpgradeInfo": { + "properties": { + "migrationMarkdown": { + "type": [ + "string", + "null" + ] + }, + "model": { + "type": "string" + }, + "modelLink": { + "type": [ + "string", + "null" + ] + }, + "retirementAt": { + "description": "Informational Unix timestamp for this upgrade's scheduled retirement, if known.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "upgradeCopy": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "model" + ], + "type": "object" + }, + "ModelVerification": { + "enum": [ + "trustedAccessForCyber" + ], + "type": "string" + }, + "ModelVerificationNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + }, + "verifications": { + "items": { + "$ref": "#/definitions/v2/ModelVerification" + }, + "type": "array" + } + }, + "required": [ + "threadId", + "turnId", + "verifications" + ], + "title": "ModelVerificationNotification", + "type": "object" + }, + "ModelsRequirements": { + "properties": { + "newThread": { + "anyOf": [ + { + "$ref": "#/definitions/v2/NewThreadModelDefaults" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "MultiAgentMode": { + "description": "Controls the effective multi-agent delegation instructions for a turn. `custom` means the configured mode hint defines the policy instead of a built-in policy.", + "oneOf": [ + { + "enum": [ + "explicitRequestOnly", + "proactive" + ], + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "custom": { + "type": "string" + } + }, + "required": [ + "custom" + ], + "title": "CustomMultiAgentMode", + "type": "object" + } + ] + }, + "MultiAgentVersion": { + "description": "Multi-agent runtime supported by a model.", + "enum": [ + "disabled", + "v1", + "v2" + ], + "type": "string" + }, + "NetworkAccess": { + "enum": [ + "restricted", + "enabled" + ], + "type": "string" + }, + "NetworkApprovalProtocol": { + "enum": [ + "http", + "https", + "socks5Tcp", + "socks5Udp" + ], + "type": "string" + }, + "NetworkDomainPermission": { + "enum": [ + "allow", + "deny" + ], + "type": "string" + }, + "NetworkRequirements": { + "properties": { + "allowLocalBinding": { + "type": [ + "boolean", + "null" + ] + }, + "allowUnixSockets": { + "description": "Legacy compatibility view derived from `unix_sockets`.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "allowUpstreamProxy": { + "type": [ + "boolean", + "null" + ] + }, + "allowedDomains": { + "description": "Legacy compatibility view derived from `domains`.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "dangerouslyAllowAllUnixSockets": { + "type": [ + "boolean", + "null" + ] + }, + "dangerouslyAllowNonLoopbackProxy": { + "type": [ + "boolean", + "null" + ] + }, + "deniedDomains": { + "description": "Legacy compatibility view derived from `domains`.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "domains": { + "additionalProperties": { + "$ref": "#/definitions/v2/NetworkDomainPermission" + }, + "description": "Canonical network permission map for `experimental_network`.", + "type": [ + "object", + "null" + ] + }, + "enabled": { + "type": [ + "boolean", + "null" + ] + }, + "httpPort": { + "format": "uint16", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "managedAllowedDomainsOnly": { + "description": "When true, only managed allowlist entries are respected while managed network enforcement is active.", + "type": [ + "boolean", + "null" + ] + }, + "socksPort": { + "format": "uint16", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "unixSockets": { + "additionalProperties": { + "$ref": "#/definitions/v2/NetworkUnixSocketPermission" + }, + "description": "Canonical unix socket permission map for `experimental_network`.", + "type": [ + "object", + "null" + ] + } + }, + "type": "object" + }, + "NetworkUnixSocketPermission": { + "enum": [ + "allow", + "deny" + ], + "type": "string" + }, + "NewThreadModelDefaults": { + "properties": { + "model": { + "type": [ + "string", + "null" + ] + }, + "modelReasoningEffort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ] + }, + "serviceTier": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "NonSteerableTurnKind": { + "enum": [ + "review", + "compact" + ], + "type": "string" + }, + "NullableGetAccountRateLimitsParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + { + "$ref": "#/definitions/v2/GetAccountRateLimitsParams" + }, + { + "type": "null" + } + ], + "title": "Nullable_GetAccountRateLimitsParams" + }, + "NullableGetAccountTokenUsageParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "anyOf": [ + { + "$ref": "#/definitions/v2/GetAccountTokenUsageParams" + }, + { + "type": "null" + } + ], + "title": "Nullable_GetAccountTokenUsageParams" + }, + "OverriddenMetadata": { + "properties": { + "effectiveValue": true, + "message": { + "type": "string" + }, + "overridingLayer": { + "$ref": "#/definitions/v2/ConfigLayerMetadata" + } + }, + "required": [ + "effectiveValue", + "message", + "overridingLayer" + ], + "type": "object" + }, + "PatchApplyStatus": { + "enum": [ + "inProgress", + "completed", + "failed", + "declined" + ], + "type": "string" + }, + "PatchChangeKind": { + "oneOf": [ + { + "properties": { + "type": { + "enum": [ + "add" + ], + "title": "AddPatchChangeKindType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "AddPatchChangeKind", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "delete" + ], + "title": "DeletePatchChangeKindType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "DeletePatchChangeKind", + "type": "object" + }, + { + "properties": { + "move_path": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "update" + ], + "title": "UpdatePatchChangeKindType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "UpdatePatchChangeKind", + "type": "object" + } + ] + }, + "PathUri": { + "type": "string" + }, + "PermissionProfileListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cursor": { + "description": "Opaque pagination cursor returned by a previous call.", + "type": [ + "string", + "null" + ] + }, + "cwd": { + "description": "Optional working directory to resolve project config layers.", + "type": [ + "string", + "null" + ] + }, + "limit": { + "description": "Optional page size; defaults to the full result set.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "title": "PermissionProfileListParams", + "type": "object" + }, + "PermissionProfileListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/PermissionProfileSummary" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item. If None, there are no more items to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "PermissionProfileListResponse", + "type": "object" + }, + "PermissionProfileSummary": { + "properties": { + "allowed": { + "description": "Whether the effective requirements allow selecting this profile.", + "type": "boolean" + }, + "description": { + "description": "Optional user-facing description for display in clients.", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Available permission profile identifier.", + "type": "string" + } + }, + "required": [ + "allowed", + "id" + ], + "type": "object" + }, + "Personality": { + "description": "Deprecated: `friendly` and `pragmatic` no longer select a style.", + "enum": [ + "none", + "friendly", + "pragmatic" + ], + "type": "string" + }, + "PlanDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - proposed plan streaming deltas for plan items. Clients should not assume concatenated deltas match the completed plan item content.", + "properties": { + "delta": { + "type": "string" + }, + "itemId": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "delta", + "itemId", + "threadId", + "turnId" + ], + "title": "PlanDeltaNotification", + "type": "object" + }, + "PlanType": { + "enum": [ + "free", + "go", + "plus", + "pro", + "prolite", + "promax", + "team", + "self_serve_business_prolite", + "self_serve_business_usage_based", + "business", + "ent26", + "enterprise_cbp_automation", + "enterprise_cbp_usage_based", + "enterprise", + "edu", + "edu_plus", + "edu_pro", + "unknown" + ], + "type": "string" + }, + "PluginAuthPolicy": { + "enum": [ + "ON_INSTALL", + "ON_USE" + ], + "type": "string" + }, + "PluginAvailability": { + "oneOf": [ + { + "enum": [ + "DISABLED_BY_ADMIN" + ], + "type": "string" + }, + { + "description": "Plugin-service currently sends `\"ENABLED\"` for available remote plugins. Codex app-server exposes `\"AVAILABLE\"` in its API; the alias keeps decoding compatible with that upstream response.", + "enum": [ + "AVAILABLE" + ], + "type": "string" + } + ] + }, + "PluginDetail": { + "properties": { + "appTemplates": { + "items": { + "$ref": "#/definitions/v2/AppTemplateSummary" + }, + "type": "array" + }, + "apps": { + "items": { + "$ref": "#/definitions/v2/AppSummary" + }, + "type": "array" + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "hooks": { + "items": { + "$ref": "#/definitions/v2/PluginHookSummary" + }, + "type": "array" + }, + "marketplaceName": { + "type": "string" + }, + "marketplacePath": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "mcpServers": { + "items": { + "type": "string" + }, + "type": "array" + }, + "onboardingSkill": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SkillSummary" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The declared onboarding skill, when the plugin and visible skill are enabled." + }, + "scheduledTasks": { + "items": { + "$ref": "#/definitions/v2/ScheduledTaskSummary" + }, + "type": [ + "array", + "null" + ] + }, + "shareUrl": { + "type": [ + "string", + "null" + ] + }, + "skills": { + "items": { + "$ref": "#/definitions/v2/SkillSummary" + }, + "type": "array" + }, + "summary": { + "$ref": "#/definitions/v2/PluginSummary" + } + }, + "required": [ + "appTemplates", + "apps", + "hooks", + "marketplaceName", + "mcpServers", + "skills", + "summary" + ], + "type": "object" + }, + "PluginDisabledReason": { + "enum": [ + "disabled_by_admin", + "plan_not_eligible", + "required_app_unavailable", + "unknown" + ], + "type": "string" + }, + "PluginHookSummary": { + "properties": { + "eventName": { + "$ref": "#/definitions/v2/HookEventName" + }, + "key": { + "type": "string" + } + }, + "required": [ + "eventName", + "key" + ], + "type": "object" + }, + "PluginInstallParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "installAttemptId": { + "description": "Client-generated identifier used to correlate one installation attempt.", + "type": [ + "string", + "null" + ] + }, + "marketplacePath": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "pluginName": { + "type": "string" + }, + "remoteMarketplaceName": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "pluginName" + ], + "title": "PluginInstallParams", + "type": "object" + }, + "PluginInstallPolicy": { + "enum": [ + "NOT_AVAILABLE", + "AVAILABLE", + "INSTALLED_BY_DEFAULT" + ], + "type": "string" + }, + "PluginInstallPolicySource": { + "enum": [ + "WORKSPACE_SETTING", + "IMPLICIT_CANONICAL_APP" + ], + "type": "string" + }, + "PluginInstallResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "appsNeedingAuth": { + "items": { + "$ref": "#/definitions/v2/AppSummary" + }, + "type": "array" + }, + "authPolicy": { + "$ref": "#/definitions/v2/PluginAuthPolicy" + } + }, + "required": [ + "appsNeedingAuth", + "authPolicy" + ], + "title": "PluginInstallResponse", + "type": "object" + }, + "PluginInstalledParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cwds": { + "description": "Optional working directories used to discover repo marketplaces.", + "items": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": [ + "array", + "null" + ] + }, + "installSuggestionPluginNames": { + "description": "Additional uninstalled plugin names that should be returned when present locally. This is used by mention surfaces that intentionally expose install entrypoints.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + } + }, + "title": "PluginInstalledParams", + "type": "object" + }, + "PluginInstalledResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "marketplaceLoadErrors": { + "default": [], + "items": { + "$ref": "#/definitions/v2/MarketplaceLoadErrorInfo" + }, + "type": "array" + }, + "marketplaces": { + "items": { + "$ref": "#/definitions/v2/PluginMarketplaceEntry" + }, + "type": "array" + } + }, + "required": [ + "marketplaces" + ], + "title": "PluginInstalledResponse", + "type": "object" + }, + "PluginInterface": { + "properties": { + "brandColor": { + "type": [ + "string", + "null" + ] + }, + "capabilities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "category": { + "type": [ + "string", + "null" + ] + }, + "composerIcon": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ], + "description": "Local composer icon path, resolved from the installed plugin package." + }, + "composerIconUrl": { + "description": "Remote composer icon URL from the plugin catalog.", + "type": [ + "string", + "null" + ] + }, + "defaultPrompt": { + "description": "Starter prompts for the plugin. Capped at 3 entries with a maximum of 128 characters per entry.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "developerName": { + "type": [ + "string", + "null" + ] + }, + "displayName": { + "type": [ + "string", + "null" + ] + }, + "logo": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ], + "description": "Local logo path, resolved from the installed plugin package." + }, + "logoDark": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ], + "description": "Local dark-mode logo path, resolved from the installed plugin package." + }, + "logoUrl": { + "description": "Remote logo URL from the plugin catalog.", + "type": [ + "string", + "null" + ] + }, + "logoUrlDark": { + "description": "Remote dark-mode logo URL from the plugin catalog.", + "type": [ + "string", + "null" + ] + }, + "longDescription": { + "type": [ + "string", + "null" + ] + }, + "privacyPolicyUrl": { + "type": [ + "string", + "null" + ] + }, + "screenshotUrls": { + "description": "Remote screenshot URLs from the plugin catalog.", + "items": { + "type": "string" + }, + "type": "array" + }, + "screenshots": { + "description": "Local screenshot paths, resolved from the installed plugin package.", + "items": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": "array" + }, + "shortDescription": { + "type": [ + "string", + "null" + ] + }, + "termsOfServiceUrl": { + "type": [ + "string", + "null" + ] + }, + "websiteUrl": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "capabilities", + "screenshotUrls", + "screenshots" + ], + "type": "object" + }, + "PluginListMarketplaceKind": { + "enum": [ + "local", + "vertical", + "workspace-directory", + "shared-with-me", + "created-by-me-remote" + ], + "type": "string" + }, + "PluginListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cwds": { + "description": "Optional working directories used to discover repo marketplaces. When omitted, only home-scoped marketplaces and the official curated marketplace are considered.", + "items": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": [ + "array", + "null" + ] + }, + "forceRefetch": { + "description": "Whether the client requests a fresh remote plugin catalog fetch.", + "type": "boolean" + }, + "marketplaceKinds": { + "description": "Optional marketplace kind filter. When omitted, only local marketplaces are queried, plus the default remote catalog when enabled by feature flag.", + "items": { + "$ref": "#/definitions/v2/PluginListMarketplaceKind" + }, + "type": [ + "array", + "null" + ] + } + }, + "title": "PluginListParams", + "type": "object" + }, + "PluginListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "featuredPluginIds": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "marketplaceLoadErrors": { + "default": [], + "items": { + "$ref": "#/definitions/v2/MarketplaceLoadErrorInfo" + }, + "type": "array" + }, + "marketplaces": { + "items": { + "$ref": "#/definitions/v2/PluginMarketplaceEntry" + }, + "type": "array" + } + }, + "required": [ + "marketplaces" + ], + "title": "PluginListResponse", + "type": "object" + }, + "PluginMarketplaceEntry": { + "properties": { + "interface": { + "anyOf": [ + { + "$ref": "#/definitions/v2/MarketplaceInterface" + }, + { + "type": "null" + } + ] + }, + "name": { + "type": "string" + }, + "path": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ], + "description": "Local marketplace file path when the marketplace is backed by a local file. Remote-only catalog marketplaces do not have a local path." + }, + "plugins": { + "items": { + "$ref": "#/definitions/v2/PluginSummary" + }, + "type": "array" + } + }, + "required": [ + "name", + "plugins" + ], + "type": "object" + }, + "PluginReadParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "marketplacePath": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "pluginName": { + "type": "string" + }, + "remoteMarketplaceName": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "pluginName" + ], + "title": "PluginReadParams", + "type": "object" + }, + "PluginReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "plugin": { + "$ref": "#/definitions/v2/PluginDetail" + } + }, + "required": [ + "plugin" + ], + "title": "PluginReadResponse", + "type": "object" + }, + "PluginReconcileChangedPlugin": { + "description": "Runtime categories affected by this change, not just capabilities currently present. Flags describe declarations before runtime policy filtering. Updates OR the old and new bundle flags; enablement changes and cached reinstalls use the cached bundle; removals retain the old bundle's flags.", + "properties": { + "hasApps": { + "type": "boolean" + }, + "hasHooks": { + "type": "boolean" + }, + "hasMcps": { + "type": "boolean" + }, + "hasSkills": { + "description": "Whether either bundle declares skill roots; not a validated inventory of enabled skills.", + "type": "boolean" + }, + "id": { + "description": "Local plugin ID (`name@marketplace`), matching `PluginSummary.id`.", + "type": "string" + } + }, + "required": [ + "hasApps", + "hasHooks", + "hasMcps", + "hasSkills", + "id" + ], + "type": "object" + }, + "PluginReconcileParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "reason": { + "description": "Optional client-provided reason recorded with the reconciliation attempt.", + "type": [ + "string", + "null" + ] + } + }, + "title": "PluginReconcileParams", + "type": "object" + }, + "PluginReconcileResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Bundle and installed-state changes observed by this pass, not a runtime-readiness acknowledgement or a cumulative diff since the client's last request. Other metadata-only changes are not listed.", + "properties": { + "changedPlugins": { + "description": "Plugins affected by bundle changes, enablement changes, or removals. Installed-state changes compare against the previous cached snapshot, including cached reinstalls. Removal hints survive cache cleanup failures; unchanged plugins are omitted.", + "items": { + "$ref": "#/definitions/v2/PluginReconcileChangedPlugin" + }, + "type": "array" + }, + "failedMaterializationRemotePluginIds": { + "description": "Subset of failures for which the requested bundle could not be materialized. A previously cached version may still be available.", + "items": { + "type": "string" + }, + "type": "array" + }, + "failedRemotePluginIds": { + "description": "Backend remote plugin IDs whose bundle or identity update failed.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "changedPlugins", + "failedMaterializationRemotePluginIds", + "failedRemotePluginIds" + ], + "title": "PluginReconcileResponse", + "type": "object" + }, + "PluginSearchResult": { + "properties": { + "marketplaceName": { + "type": "string" + }, + "marketplacePath": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "plugin": { + "$ref": "#/definitions/v2/PluginSummary" + } + }, + "required": [ + "marketplaceName", + "plugin" + ], + "type": "object" + }, + "PluginSearchScope": { + "enum": [ + "global", + "workspace", + "personal" + ], + "type": "string" + }, + "PluginShareCheckoutParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "remotePluginId": { + "type": "string" + } + }, + "required": [ + "remotePluginId" + ], + "title": "PluginShareCheckoutParams", + "type": "object" + }, + "PluginShareCheckoutResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "marketplaceName": { + "type": "string" + }, + "marketplacePath": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "pluginId": { + "type": "string" + }, + "pluginName": { + "type": "string" + }, + "pluginPath": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "remotePluginId": { + "type": "string" + }, + "remoteVersion": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "marketplaceName", + "marketplacePath", + "pluginId", + "pluginName", + "pluginPath", + "remotePluginId" + ], + "title": "PluginShareCheckoutResponse", + "type": "object" + }, + "PluginShareContext": { + "properties": { + "canPublishToWorkspace": { + "default": null, + "type": [ + "boolean", + "null" + ] + }, + "creatorAccountUserId": { + "type": [ + "string", + "null" + ] + }, + "creatorName": { + "type": [ + "string", + "null" + ] + }, + "discoverability": { + "anyOf": [ + { + "$ref": "#/definitions/v2/PluginShareDiscoverability" + }, + { + "type": "null" + } + ] + }, + "remotePluginId": { + "type": "string" + }, + "remoteVersion": { + "default": null, + "description": "Version of the remote shared plugin release when available.", + "type": [ + "string", + "null" + ] + }, + "sharePrincipals": { + "items": { + "$ref": "#/definitions/v2/PluginSharePrincipal" + }, + "type": [ + "array", + "null" + ] + }, + "shareUrl": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "remotePluginId" + ], + "type": "object" + }, + "PluginShareDeleteParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "remotePluginId": { + "type": "string" + } + }, + "required": [ + "remotePluginId" + ], + "title": "PluginShareDeleteParams", + "type": "object" + }, + "PluginShareDeleteResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PluginShareDeleteResponse", + "type": "object" + }, + "PluginShareDiscoverability": { + "enum": [ + "LISTED", + "UNLISTED", + "PRIVATE" + ], + "type": "string" + }, + "PluginShareListItem": { + "properties": { + "localPluginPath": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "plugin": { + "$ref": "#/definitions/v2/PluginSummary" + } + }, + "required": [ + "plugin" + ], + "type": "object" + }, + "PluginShareListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PluginShareListParams", + "type": "object" + }, + "PluginShareListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/PluginShareListItem" + }, + "type": "array" + } + }, + "required": [ + "data" + ], + "title": "PluginShareListResponse", + "type": "object" + }, + "PluginSharePrincipal": { + "properties": { + "name": { + "type": "string" + }, + "principalId": { + "type": "string" + }, + "principalType": { + "$ref": "#/definitions/v2/PluginSharePrincipalType" + }, + "role": { + "$ref": "#/definitions/v2/PluginSharePrincipalRole" + } + }, + "required": [ + "name", + "principalId", + "principalType", + "role" + ], + "type": "object" + }, + "PluginSharePrincipalRole": { + "enum": [ + "reader", + "editor", + "owner" + ], + "type": "string" + }, + "PluginSharePrincipalType": { + "enum": [ + "user", + "group", + "workspace" + ], + "type": "string" + }, + "PluginShareSaveParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "discoverability": { + "anyOf": [ + { + "$ref": "#/definitions/v2/PluginShareDiscoverability" + }, + { + "type": "null" + } + ] + }, + "pluginPath": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "remotePluginId": { + "type": [ + "string", + "null" + ] + }, + "shareTargets": { + "items": { + "$ref": "#/definitions/v2/PluginShareTarget" + }, + "type": [ + "array", + "null" + ] + } + }, + "required": [ + "pluginPath" + ], + "title": "PluginShareSaveParams", + "type": "object" + }, + "PluginShareSaveResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "canPublishToWorkspace": { + "default": null, + "type": [ + "boolean", + "null" + ] + }, + "remotePluginId": { + "type": "string" + }, + "shareUrl": { + "type": "string" + } + }, + "required": [ + "remotePluginId", + "shareUrl" + ], + "title": "PluginShareSaveResponse", + "type": "object" + }, + "PluginShareTarget": { + "properties": { + "principalId": { + "type": "string" + }, + "principalType": { + "$ref": "#/definitions/v2/PluginSharePrincipalType" + }, + "role": { + "$ref": "#/definitions/v2/PluginShareTargetRole" + } + }, + "required": [ + "principalId", + "principalType", + "role" + ], + "type": "object" + }, + "PluginShareTargetRole": { + "enum": [ + "reader", + "editor" + ], + "type": "string" + }, + "PluginShareUpdateDiscoverability": { + "enum": [ + "UNLISTED", + "PRIVATE", + "LISTED" + ], + "type": "string" + }, + "PluginShareUpdateTargetsParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "discoverability": { + "$ref": "#/definitions/v2/PluginShareUpdateDiscoverability" + }, + "remotePluginId": { + "type": "string" + }, + "shareTargets": { + "items": { + "$ref": "#/definitions/v2/PluginShareTarget" + }, + "type": "array" + } + }, + "required": [ + "discoverability", + "remotePluginId", + "shareTargets" + ], + "title": "PluginShareUpdateTargetsParams", + "type": "object" + }, + "PluginShareUpdateTargetsResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "discoverability": { + "$ref": "#/definitions/v2/PluginShareDiscoverability" + }, + "principals": { + "items": { + "$ref": "#/definitions/v2/PluginSharePrincipal" + }, + "type": "array" + } + }, + "required": [ + "discoverability", + "principals" + ], + "title": "PluginShareUpdateTargetsResponse", + "type": "object" + }, + "PluginSkillReadParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "remoteMarketplaceName": { + "type": "string" + }, + "remotePluginId": { + "type": "string" + }, + "skillName": { + "type": "string" + } + }, + "required": [ + "remoteMarketplaceName", + "remotePluginId", + "skillName" + ], + "title": "PluginSkillReadParams", + "type": "object" + }, + "PluginSkillReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "contents": { + "type": [ + "string", + "null" + ] + } + }, + "title": "PluginSkillReadResponse", + "type": "object" + }, + "PluginSource": { + "oneOf": [ + { + "properties": { + "path": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": { + "enum": [ + "local" + ], + "title": "LocalPluginSourceType", + "type": "string" + } + }, + "required": [ + "path", + "type" + ], + "title": "LocalPluginSource", + "type": "object" + }, + { + "properties": { + "path": { + "type": [ + "string", + "null" + ] + }, + "refName": { + "type": [ + "string", + "null" + ] + }, + "sha": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "git" + ], + "title": "GitPluginSourceType", + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "type", + "url" + ], + "title": "GitPluginSource", + "type": "object" + }, + { + "properties": { + "package": { + "type": "string" + }, + "registry": { + "description": "Optional HTTPS registry URL. Authentication stays in the user's npm config.", + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "npm" + ], + "title": "NpmPluginSourceType", + "type": "string" + }, + "version": { + "description": "Optional npm version or version range.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "package", + "type" + ], + "title": "NpmPluginSource", + "type": "object" + }, + { + "description": "The plugin is available in the remote catalog. Download metadata is kept server-side and is not exposed through the app-server API.", + "properties": { + "type": { + "enum": [ + "remote" + ], + "title": "RemotePluginSourceType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "RemotePluginSource", + "type": "object" + } + ] + }, + "PluginSummary": { + "properties": { + "authPolicy": { + "$ref": "#/definitions/v2/PluginAuthPolicy" + }, + "availability": { + "allOf": [ + { + "$ref": "#/definitions/v2/PluginAvailability" + } + ], + "default": "AVAILABLE", + "description": "Availability state for installing and using the plugin." + }, + "disabledReason": { + "anyOf": [ + { + "$ref": "#/definitions/v2/PluginDisabledReason" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Why the remote plugin is unavailable, when provided by plugin-service." + }, + "eligiblePlanTypes": { + "default": null, + "description": "Raw plugin-service plan identifiers eligible to install the plugin.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "enabled": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "installPolicy": { + "$ref": "#/definitions/v2/PluginInstallPolicy" + }, + "installPolicySource": { + "anyOf": [ + { + "$ref": "#/definitions/v2/PluginInstallPolicySource" + }, + { + "type": "null" + } + ] + }, + "installed": { + "type": "boolean" + }, + "installedAt": { + "default": null, + "description": "Unix timestamp in seconds when the remote plugin was installed, when available.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "interface": { + "anyOf": [ + { + "$ref": "#/definitions/v2/PluginInterface" + }, + { + "type": "null" + } + ] + }, + "keywords": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "localVersion": { + "default": null, + "description": "Version of the locally materialized plugin package when available.", + "type": [ + "string", + "null" + ] + }, + "mustShowInstallationInterstitial": { + "default": null, + "type": [ + "boolean", + "null" + ] + }, + "name": { + "type": "string" + }, + "remotePluginId": { + "description": "Backend remote plugin identifier when available.", + "type": [ + "string", + "null" + ] + }, + "shareContext": { + "anyOf": [ + { + "$ref": "#/definitions/v2/PluginShareContext" + }, + { + "type": "null" + } + ], + "description": "Remote sharing context associated with this plugin when available." + }, + "source": { + "$ref": "#/definitions/v2/PluginSource" + }, + "version": { + "default": null, + "description": "Version advertised by the remote marketplace backend when available.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "authPolicy", + "enabled", + "id", + "installPolicy", + "installed", + "name", + "source" + ], + "type": "object" + }, + "PluginUninstallParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "pluginId": { + "type": "string" + } + }, + "required": [ + "pluginId" + ], + "title": "PluginUninstallParams", + "type": "object" + }, + "PluginUninstallResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PluginUninstallResponse", + "type": "object" + }, + "PluginsMigration": { + "properties": { + "marketplaceName": { + "type": "string" + }, + "pluginNames": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "marketplaceName", + "pluginNames" + ], + "type": "object" + }, + "ProcessExitedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Final process exit notification for `process/spawn`.", + "properties": { + "exitCode": { + "description": "Process exit code.", + "format": "int32", + "type": "integer" + }, + "processHandle": { + "description": "Client-supplied, connection-scoped `processHandle` from `process/spawn`.", + "type": "string" + }, + "stderr": { + "description": "Buffered stderr capture.\n\nEmpty when stderr was streamed via `process/outputDelta`.", + "type": "string" + }, + "stderrCapReached": { + "description": "Whether stderr reached `outputBytesCap`.\n\nIn streaming mode, stderr is empty and cap state is also reported on the final stderr `process/outputDelta` notification.", + "type": "boolean" + }, + "stdout": { + "description": "Buffered stdout capture.\n\nEmpty when stdout was streamed via `process/outputDelta`.", + "type": "string" + }, + "stdoutCapReached": { + "description": "Whether stdout reached `outputBytesCap`.\n\nIn streaming mode, stdout is empty and cap state is also reported on the final stdout `process/outputDelta` notification.", + "type": "boolean" + } + }, + "required": [ + "exitCode", + "processHandle", + "stderr", + "stderrCapReached", + "stdout", + "stdoutCapReached" + ], + "title": "ProcessExitedNotification", + "type": "object" + }, + "ProcessOutputDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Base64-encoded output chunk emitted for a streaming `process/spawn` request.", + "properties": { + "capReached": { + "description": "True on the final streamed chunk for this stream when output was truncated by `outputBytesCap`.", + "type": "boolean" + }, + "deltaBase64": { + "description": "Base64-encoded output bytes.", + "type": "string" + }, + "processHandle": { + "description": "Client-supplied, connection-scoped `processHandle` from `process/spawn`.", + "type": "string" + }, + "stream": { + "allOf": [ + { + "$ref": "#/definitions/v2/ProcessOutputStream" + } + ], + "description": "Output stream this chunk belongs to." + } + }, + "required": [ + "capReached", + "deltaBase64", + "processHandle", + "stream" + ], + "title": "ProcessOutputDeltaNotification", + "type": "object" + }, + "ProcessOutputStream": { + "description": "Stream label for `process/outputDelta` notifications.", + "oneOf": [ + { + "description": "stdout stream. PTY mode multiplexes terminal output here.", + "enum": [ + "stdout" + ], + "type": "string" + }, + { + "description": "stderr stream.", + "enum": [ + "stderr" + ], + "type": "string" + } + ] + }, + "ProcessTerminalSize": { + "description": "PTY size in character cells for `process/spawn` PTY sessions.", + "properties": { + "cols": { + "description": "Terminal width in character cells.", + "format": "uint16", + "minimum": 0.0, + "type": "integer" + }, + "rows": { + "description": "Terminal height in character cells.", + "format": "uint16", + "minimum": 0.0, + "type": "integer" + } + }, + "required": [ + "cols", + "rows" + ], + "type": "object" + }, + "Project": { + "properties": { + "createdAt": { + "format": "int64", + "type": "integer" + }, + "id": { + "type": "string" + }, + "metadata": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "name": { + "type": "string" + }, + "position": { + "format": "int64", + "type": "integer" + }, + "recencyAt": { + "description": "Newest non-archived member thread's recency, in Unix seconds; null when none exist.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "roots": { + "items": { + "$ref": "#/definitions/v2/ProjectRoot" + }, + "type": "array" + }, + "updatedAt": { + "format": "int64", + "type": "integer" + } + }, + "required": [ + "createdAt", + "id", + "metadata", + "name", + "position", + "roots", + "updatedAt" + ], + "type": "object" + }, + "ProjectChangeType": { + "enum": [ + "created", + "updated", + "deleted" + ], + "type": "string" + }, + "ProjectChangedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "changeType": { + "$ref": "#/definitions/v2/ProjectChangeType" + }, + "projectId": { + "type": "string" + } + }, + "required": [ + "changeType", + "projectId" + ], + "title": "ProjectChangedNotification", + "type": "object" + }, + "ProjectRoot": { + "properties": { + "path": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "ProjectSortKey": { + "enum": [ + "position", + "recencyAt" + ], + "type": "string" + }, + "QueuedSubmission": { + "properties": { + "clientUserMessageId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "input": { + "items": { + "$ref": "#/definitions/v2/UserInput" + }, + "type": "array" + } + }, + "required": [ + "clientUserMessageId", + "id", + "input" + ], + "type": "object" + }, + "RateLimitReachedType": { + "enum": [ + "rate_limit_reached", + "workspace_owner_credits_depleted", + "workspace_member_credits_depleted", + "workspace_owner_usage_limit_reached", + "workspace_member_usage_limit_reached" + ], + "type": "string" + }, + "RateLimitResetCredit": { + "properties": { + "description": { + "description": "Backend-provided display description for this credit, or `null` when unavailable.", + "type": [ + "string", + "null" + ] + }, + "expiresAt": { + "description": "Unix timestamp in seconds when the credit expires, or `null` if it does not expire.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "grantedAt": { + "description": "Unix timestamp in seconds when the credit was granted.", + "format": "int64", + "type": "integer" + }, + "id": { + "description": "Opaque backend identifier for this reset credit.", + "type": "string" + }, + "resetType": { + "$ref": "#/definitions/v2/RateLimitResetType" + }, + "status": { + "$ref": "#/definitions/v2/RateLimitResetCreditStatus" + }, + "title": { + "description": "Backend-provided display title for this credit, or `null` when unavailable.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "grantedAt", + "id", + "resetType", + "status" + ], + "type": "object" + }, + "RateLimitResetCreditStatus": { + "enum": [ + "available", + "redeeming", + "redeemed", + "unknown" + ], + "type": "string" + }, + "RateLimitResetCreditsSummary": { + "properties": { + "availableCount": { + "format": "int64", + "type": "integer" + }, + "credits": { + "description": "Detail rows for available reset credits, when the backend provides them.\n\n`null` means only `availableCount` is known, while an empty array means details were fetched and no available credits were returned. The backend may cap this list, so its length can be less than `availableCount`.", + "items": { + "$ref": "#/definitions/v2/RateLimitResetCredit" + }, + "type": [ + "array", + "null" + ] + } + }, + "required": [ + "availableCount" + ], + "type": "object" + }, + "RateLimitResetType": { + "enum": [ + "codexRateLimits", + "unknown" + ], + "type": "string" + }, + "RateLimitSnapshot": { + "properties": { + "credits": { + "anyOf": [ + { + "$ref": "#/definitions/v2/CreditsSnapshot" + }, + { + "type": "null" + } + ] + }, + "individualLimit": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SpendControlLimitSnapshot" + }, + { + "type": "null" + } + ] + }, + "limitId": { + "type": [ + "string", + "null" + ] + }, + "limitName": { + "type": [ + "string", + "null" + ] + }, + "normalModelSlug": { + "description": "Normal model whose display name and reasoning options describe this quota alias.", + "type": [ + "string", + "null" + ] + }, + "planType": { + "anyOf": [ + { + "$ref": "#/definitions/v2/PlanType" + }, + { + "type": "null" + } + ] + }, + "primary": { + "anyOf": [ + { + "$ref": "#/definitions/v2/RateLimitWindow" + }, + { + "type": "null" + } + ] + }, + "rateLimitReachedType": { + "anyOf": [ + { + "$ref": "#/definitions/v2/RateLimitReachedType" + }, + { + "type": "null" + } + ] + }, + "secondary": { + "anyOf": [ + { + "$ref": "#/definitions/v2/RateLimitWindow" + }, + { + "type": "null" + } + ] + }, + "spendControlReached": { + "description": "Backend-reported spend-control state. `None` is unavailable, not a sparse-update recovery.", + "type": [ + "boolean", + "null" + ] + } + }, + "type": "object" + }, + "RateLimitWindow": { + "properties": { + "resetsAt": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "usedPercent": { + "format": "int32", + "type": "integer" + }, + "windowDurationMins": { + "format": "int64", + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "usedPercent" + ], + "type": "object" + }, + "RawResponseCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Internal-only notification containing the exact usage from one upstream Responses API completion.", + "properties": { + "responseId": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + }, + "usage": { + "anyOf": [ + { + "$ref": "#/definitions/v2/TokenUsageBreakdown" + }, + { + "type": "null" + } + ] + }, + "usageMetadata": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ResponseUsageMetadata" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "responseId", + "threadId", + "turnId" + ], + "title": "RawResponseCompletedNotification", + "type": "object" + }, + "RawResponseItemCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "item": { + "$ref": "#/definitions/v2/ResponseItem" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "item", + "threadId", + "turnId" + ], + "title": "RawResponseItemCompletedNotification", + "type": "object" + }, + "RealtimeConversationVersion": { + "enum": [ + "v1", + "v2", + "v3" + ], + "type": "string" + }, + "RealtimeOutputModality": { + "enum": [ + "text", + "audio" + ], + "type": "string" + }, + "RealtimeVoice": { + "enum": [ + "alloy", + "arbor", + "ash", + "ballad", + "breeze", + "cedar", + "coral", + "cove", + "echo", + "ember", + "juniper", + "maple", + "marin", + "sage", + "shimmer", + "sol", + "spruce", + "vale", + "verse" + ], + "type": "string" + }, + "RealtimeVoicesList": { + "properties": { + "defaultV1": { + "$ref": "#/definitions/v2/RealtimeVoice" + }, + "defaultV2": { + "$ref": "#/definitions/v2/RealtimeVoice" + }, + "v1": { + "items": { + "$ref": "#/definitions/v2/RealtimeVoice" + }, + "type": "array" + }, + "v2": { + "items": { + "$ref": "#/definitions/v2/RealtimeVoice" + }, + "type": "array" + } + }, + "required": [ + "defaultV1", + "defaultV2", + "v1", + "v2" + ], + "type": "object" + }, + "ReasoningEffort": { + "description": "A non-empty reasoning effort value advertised by the model.", + "minLength": 1, + "type": "string" + }, + "ReasoningEffortOption": { + "properties": { + "description": { + "type": "string" + }, + "reasoningEffort": { + "$ref": "#/definitions/v2/ReasoningEffort" + } + }, + "required": [ + "description", + "reasoningEffort" + ], + "type": "object" + }, + "ReasoningItemContent": { + "oneOf": [ + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "enum": [ + "reasoning_text" + ], + "title": "ReasoningTextReasoningItemContentType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "ReasoningTextReasoningItemContent", + "type": "object" + }, + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "enum": [ + "text" + ], + "title": "TextReasoningItemContentType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "TextReasoningItemContent", + "type": "object" + } + ] + }, + "ReasoningItemReasoningSummary": { + "oneOf": [ + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "enum": [ + "summary_text" + ], + "title": "SummaryTextReasoningItemReasoningSummaryType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "SummaryTextReasoningItemReasoningSummary", + "type": "object" + } + ] + }, + "ReasoningSummary": { + "description": "A summary of the reasoning performed by the model. This can be useful for debugging and understanding the model's reasoning process. See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#reasoning-summaries", + "oneOf": [ + { + "enum": [ + "auto", + "concise", + "detailed" + ], + "type": "string" + }, + { + "description": "Option to disable reasoning summaries.", + "enum": [ + "none" + ], + "type": "string" + } + ] + }, + "ReasoningSummaryPartAddedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "itemId": { + "type": "string" + }, + "summaryIndex": { + "format": "int64", + "type": "integer" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "summaryIndex", + "threadId", + "turnId" + ], + "title": "ReasoningSummaryPartAddedNotification", + "type": "object" + }, + "ReasoningSummaryTextDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "delta": { + "type": "string" + }, + "itemId": { + "type": "string" + }, + "summaryIndex": { + "format": "int64", + "type": "integer" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "delta", + "itemId", + "summaryIndex", + "threadId", + "turnId" + ], + "title": "ReasoningSummaryTextDeltaNotification", + "type": "object" + }, + "ReasoningTextDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "contentIndex": { + "format": "int64", + "type": "integer" + }, + "delta": { + "type": "string" + }, + "itemId": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "contentIndex", + "delta", + "itemId", + "threadId", + "turnId" + ], + "title": "ReasoningTextDeltaNotification", + "type": "object" + }, + "RemoteControlConnectionStatus": { + "enum": [ + "disabled", + "connecting", + "connected", + "errored" + ], + "type": "string" + }, + "RemoteControlDisableParams": { + "properties": { + "ephemeral": { + "type": "boolean" + } + }, + "type": "object" + }, + "RemoteControlEnableParams": { + "properties": { + "ephemeral": { + "type": "boolean" + } + }, + "type": "object" + }, + "RemoteControlStatusChangedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Current remote-control connection status and remote identity exposed to clients.", + "properties": { + "environmentId": { + "type": [ + "string", + "null" + ] + }, + "installationId": { + "type": "string" + }, + "serverName": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v2/RemoteControlConnectionStatus" + } + }, + "required": [ + "installationId", + "serverName", + "status" + ], + "title": "RemoteControlStatusChangedNotification", + "type": "object" + }, + "RequestId": { + "anyOf": [ + { + "type": "string" + }, + { + "format": "int64", + "type": "integer" + } + ] + }, + "RequestPermissionProfile": { + "additionalProperties": false, + "properties": { + "fileSystem": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AdditionalFileSystemPermissions" + }, + { + "type": "null" + } + ] + }, + "network": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AdditionalNetworkPermissions" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "ResidencyRequirement": { + "enum": [ + "us" + ], + "type": "string" + }, + "Resource": { + "description": "A known resource that the server is capable of reading.", + "properties": { + "_meta": true, + "annotations": true, + "description": { + "type": [ + "string", + "null" + ] + }, + "icons": { + "items": true, + "type": [ + "array", + "null" + ] + }, + "mimeType": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "size": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "uri": { + "type": "string" + } + }, + "required": [ + "name", + "uri" + ], + "type": "object" + }, + "ResourceContent": { + "anyOf": [ + { + "properties": { + "_meta": true, + "mimeType": { + "type": [ + "string", + "null" + ] + }, + "text": { + "type": "string" + }, + "uri": { + "description": "The URI of this resource.", + "type": "string" + } + }, + "required": [ + "text", + "uri" + ], + "type": "object" + }, + { + "properties": { + "_meta": true, + "blob": { + "type": "string" + }, + "mimeType": { + "type": [ + "string", + "null" + ] + }, + "uri": { + "description": "The URI of this resource.", + "type": "string" + } + }, + "required": [ + "blob", + "uri" + ], + "type": "object" + } + ], + "description": "Contents returned when reading a resource from an MCP server." + }, + "ResourceTemplate": { + "description": "A template description for resources available on the server.", + "properties": { + "annotations": true, + "description": { + "type": [ + "string", + "null" + ] + }, + "mimeType": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "uriTemplate": { + "type": "string" + } + }, + "required": [ + "name", + "uriTemplate" + ], + "type": "object" + }, + "ResponseItem": { + "oneOf": [ + { + "properties": { + "content": { + "items": { + "$ref": "#/definitions/v2/ContentItem" + }, + "type": "array" + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "phase": { + "anyOf": [ + { + "$ref": "#/definitions/v2/MessagePhase" + }, + { + "type": "null" + } + ] + }, + "role": { + "type": "string" + }, + "type": { + "enum": [ + "message" + ], + "title": "MessageResponseItemType", + "type": "string" + } + }, + "required": [ + "content", + "role", + "type" + ], + "title": "MessageResponseItem", + "type": "object" + }, + { + "properties": { + "author": { + "type": "string" + }, + "content": { + "items": { + "$ref": "#/definitions/v2/AgentMessageInputContent" + }, + "type": "array" + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "recipient": { + "type": "string" + }, + "type": { + "enum": [ + "agent_message" + ], + "title": "AgentMessageResponseItemType", + "type": "string" + } + }, + "required": [ + "author", + "content", + "recipient", + "type" + ], + "title": "AgentMessageResponseItem", + "type": "object" + }, + { + "properties": { + "content": { + "default": null, + "items": { + "$ref": "#/definitions/v2/ReasoningItemContent" + }, + "type": [ + "array", + "null" + ] + }, + "encrypted_content": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "summary": { + "items": { + "$ref": "#/definitions/v2/ReasoningItemReasoningSummary" + }, + "type": "array" + }, + "type": { + "enum": [ + "reasoning" + ], + "title": "ReasoningResponseItemType", + "type": "string" + } + }, + "required": [ + "summary", + "type" + ], + "title": "ReasoningResponseItem", + "type": "object" + }, + { + "properties": { + "action": { + "$ref": "#/definitions/v2/LocalShellAction" + }, + "call_id": { + "description": "Set when using the Responses API.", + "type": [ + "string", + "null" + ] + }, + "id": { + "description": "Legacy id field retained for compatibility with older payloads.", + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "status": { + "$ref": "#/definitions/v2/LocalShellStatus" + }, + "type": { + "enum": [ + "local_shell_call" + ], + "title": "LocalShellCallResponseItemType", + "type": "string" + } + }, + "required": [ + "action", + "status", + "type" + ], + "title": "LocalShellCallResponseItem", + "type": "object" + }, + { + "properties": { + "arguments": { + "type": "string" + }, + "call_id": { + "type": "string" + }, + "encrypted_function_args": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "name": { + "type": "string" + }, + "namespace": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "function_call" + ], + "title": "FunctionCallResponseItemType", + "type": "string" + } + }, + "required": [ + "arguments", + "call_id", + "name", + "type" + ], + "title": "FunctionCallResponseItem", + "type": "object" + }, + { + "properties": { + "arguments": true, + "call_id": { + "type": [ + "string", + "null" + ] + }, + "execution": { + "type": "string" + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "status": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "tool_search_call" + ], + "title": "ToolSearchCallResponseItemType", + "type": "string" + } + }, + "required": [ + "arguments", + "execution", + "type" + ], + "title": "ToolSearchCallResponseItem", + "type": "object" + }, + { + "properties": { + "call_id": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "namespace": { + "type": [ + "string", + "null" + ] + }, + "output": { + "$ref": "#/definitions/v2/FunctionCallOutputBody" + }, + "type": { + "enum": [ + "function_call_output" + ], + "title": "FunctionCallOutputResponseItemType", + "type": "string" + } + }, + "required": [ + "output", + "type" + ], + "title": "FunctionCallOutputResponseItem", + "type": "object" + }, + { + "properties": { + "call_id": { + "type": "string" + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "input": { + "type": "string" + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "name": { + "type": "string" + }, + "namespace": { + "type": [ + "string", + "null" + ] + }, + "status": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "custom_tool_call" + ], + "title": "CustomToolCallResponseItemType", + "type": "string" + } + }, + "required": [ + "call_id", + "input", + "name", + "type" + ], + "title": "CustomToolCallResponseItem", + "type": "object" + }, + { + "properties": { + "call_id": { + "type": "string" + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "output": { + "$ref": "#/definitions/v2/FunctionCallOutputBody" + }, + "type": { + "enum": [ + "custom_tool_call_output" + ], + "title": "CustomToolCallOutputResponseItemType", + "type": "string" + } + }, + "required": [ + "call_id", + "output", + "type" + ], + "title": "CustomToolCallOutputResponseItem", + "type": "object" + }, + { + "properties": { + "call_id": { + "type": [ + "string", + "null" + ] + }, + "execution": { + "type": "string" + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "status": { + "type": "string" + }, + "tools": { + "items": true, + "type": "array" + }, + "type": { + "enum": [ + "tool_search_output" + ], + "title": "ToolSearchOutputResponseItemType", + "type": "string" + } + }, + "required": [ + "execution", + "status", + "tools", + "type" + ], + "title": "ToolSearchOutputResponseItem", + "type": "object" + }, + { + "properties": { + "action": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ResponsesApiWebSearchAction" + }, + { + "type": "null" + } + ] + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "status": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "web_search_call" + ], + "title": "WebSearchCallResponseItemType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "WebSearchCallResponseItem", + "type": "object" + }, + { + "properties": { + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "result": { + "type": "string" + }, + "revised_prompt": { + "type": [ + "string", + "null" + ] + }, + "status": { + "type": "string" + }, + "type": { + "enum": [ + "image_generation_call" + ], + "title": "ImageGenerationCallResponseItemType", + "type": "string" + } + }, + "required": [ + "result", + "status", + "type" + ], + "title": "ImageGenerationCallResponseItem", + "type": "object" + }, + { + "properties": { + "encrypted_content": { + "type": "string" + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "type": { + "enum": [ + "compaction" + ], + "title": "CompactionResponseItemType", + "type": "string" + } + }, + "required": [ + "encrypted_content", + "type" + ], + "title": "CompactionResponseItem", + "type": "object" + }, + { + "description": "A durable input control interpreted by the backend at its position in history.", + "properties": { + "reasoning": { + "$ref": "#/definitions/v2/ConfigurationReasoning" + }, + "type": { + "enum": [ + "configuration_update" + ], + "title": "ConfigurationUpdateResponseItemType", + "type": "string" + } + }, + "required": [ + "reasoning", + "type" + ], + "title": "ConfigurationUpdateResponseItem", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "compaction_trigger" + ], + "title": "CompactionTriggerResponseItemType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "CompactionTriggerResponseItem", + "type": "object" + }, + { + "properties": { + "encrypted_content": { + "type": [ + "string", + "null" + ] + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "internal_chat_message_metadata_passthrough": { + "anyOf": [ + { + "$ref": "#/definitions/v2/InternalChatMessageMetadataPassthrough" + }, + { + "type": "null" + } + ] + }, + "type": { + "enum": [ + "context_compaction" + ], + "title": "ContextCompactionResponseItemType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "ContextCompactionResponseItem", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "other" + ], + "title": "OtherResponseItemType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "OtherResponseItem", + "type": "object" + } + ] + }, + "ResponseUsageMetadata": { + "description": "Usage metadata reported for one upstream response.", + "properties": { + "amount": { + "type": [ + "string", + "null" + ] + }, + "metadata": true + }, + "type": "object" + }, + "ResponsesApiWebSearchAction": { + "oneOf": [ + { + "properties": { + "queries": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "query": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "search" + ], + "title": "SearchResponsesApiWebSearchActionType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "SearchResponsesApiWebSearchAction", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "open_page" + ], + "title": "OpenPageResponsesApiWebSearchActionType", + "type": "string" + }, + "url": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "type" + ], + "title": "OpenPageResponsesApiWebSearchAction", + "type": "object" + }, + { + "properties": { + "pattern": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "find_in_page" + ], + "title": "FindInPageResponsesApiWebSearchActionType", + "type": "string" + }, + "url": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "type" + ], + "title": "FindInPageResponsesApiWebSearchAction", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "other" + ], + "title": "OtherResponsesApiWebSearchActionType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "OtherResponsesApiWebSearchAction", + "type": "object" + } + ] + }, + "ReviewDelivery": { + "enum": [ + "inline", + "detached" + ], + "type": "string" + }, + "ReviewStartParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "delivery": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReviewDelivery" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Where to run the review: inline (default) on the current thread or detached on a new thread (returned in `reviewThreadId`). Detached delivery is deprecated and emits `deprecationNotice`. Use `thread/start` followed by an inline review for a separate review thread." + }, + "target": { + "$ref": "#/definitions/v2/ReviewTarget" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "target", + "threadId" + ], + "title": "ReviewStartParams", + "type": "object" + }, + "ReviewStartResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "reviewThreadId": { + "description": "Identifies the thread where the review runs.\n\nFor inline reviews, this is the original thread id. For detached reviews, this is the id of the new review thread.", + "type": "string" + }, + "turn": { + "$ref": "#/definitions/v2/Turn" + } + }, + "required": [ + "reviewThreadId", + "turn" + ], + "title": "ReviewStartResponse", + "type": "object" + }, + "ReviewTarget": { + "oneOf": [ + { + "description": "Review the working tree: staged, unstaged, and untracked files.", + "properties": { + "type": { + "enum": [ + "uncommittedChanges" + ], + "title": "UncommittedChangesReviewTargetType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "UncommittedChangesReviewTarget", + "type": "object" + }, + { + "description": "Review changes between the current branch and the given base branch.", + "properties": { + "branch": { + "type": "string" + }, + "type": { + "enum": [ + "baseBranch" + ], + "title": "BaseBranchReviewTargetType", + "type": "string" + } + }, + "required": [ + "branch", + "type" + ], + "title": "BaseBranchReviewTarget", + "type": "object" + }, + { + "description": "Review the changes introduced by a specific commit.", + "properties": { + "sha": { + "type": "string" + }, + "title": { + "description": "Optional human-readable label (e.g., commit subject) for UIs.", + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "commit" + ], + "title": "CommitReviewTargetType", + "type": "string" + } + }, + "required": [ + "sha", + "type" + ], + "title": "CommitReviewTarget", + "type": "object" + }, + { + "description": "Arbitrary instructions, equivalent to the old free-form prompt.", + "properties": { + "instructions": { + "type": "string" + }, + "type": { + "enum": [ + "custom" + ], + "title": "CustomReviewTargetType", + "type": "string" + } + }, + "required": [ + "instructions", + "type" + ], + "title": "CustomReviewTarget", + "type": "object" + } + ] + }, + "SandboxMode": { + "enum": [ + "read-only", + "workspace-write", + "danger-full-access" + ], + "type": "string" + }, + "SandboxPolicy": { + "oneOf": [ + { + "properties": { + "type": { + "enum": [ + "dangerFullAccess" + ], + "title": "DangerFullAccessSandboxPolicyType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "DangerFullAccessSandboxPolicy", + "type": "object" + }, + { + "properties": { + "networkAccess": { + "default": false, + "type": "boolean" + }, + "type": { + "enum": [ + "readOnly" + ], + "title": "ReadOnlySandboxPolicyType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "ReadOnlySandboxPolicy", + "type": "object" + }, + { + "properties": { + "networkAccess": { + "allOf": [ + { + "$ref": "#/definitions/v2/NetworkAccess" + } + ], + "default": "restricted" + }, + "type": { + "enum": [ + "externalSandbox" + ], + "title": "ExternalSandboxSandboxPolicyType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "ExternalSandboxSandboxPolicy", + "type": "object" + }, + { + "properties": { + "excludeSlashTmp": { + "default": false, + "type": "boolean" + }, + "excludeTmpdirEnvVar": { + "default": false, + "type": "boolean" + }, + "networkAccess": { + "default": false, + "type": "boolean" + }, + "type": { + "enum": [ + "workspaceWrite" + ], + "title": "WorkspaceWriteSandboxPolicyType", + "type": "string" + }, + "writableRoots": { + "default": [], + "items": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": "array" + } + }, + "required": [ + "type" + ], + "title": "WorkspaceWriteSandboxPolicy", + "type": "object" + } + ] + }, + "SandboxWorkspaceWrite": { + "properties": { + "exclude_slash_tmp": { + "default": false, + "type": "boolean" + }, + "exclude_tmpdir_env_var": { + "default": false, + "type": "boolean" + }, + "network_access": { + "default": false, + "type": "boolean" + }, + "writable_roots": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "ScheduledTaskSchedule": { + "oneOf": [ + { + "properties": { + "days": { + "items": { + "$ref": "#/definitions/v2/ScheduledTaskWeekday" + }, + "type": [ + "array", + "null" + ] + }, + "intervalHours": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "type": { + "enum": [ + "hourly" + ], + "title": "HourlyScheduledTaskScheduleType", + "type": "string" + } + }, + "required": [ + "intervalHours", + "type" + ], + "title": "HourlyScheduledTaskSchedule", + "type": "object" + }, + { + "properties": { + "time": { + "type": "string" + }, + "type": { + "enum": [ + "daily" + ], + "title": "DailyScheduledTaskScheduleType", + "type": "string" + } + }, + "required": [ + "time", + "type" + ], + "title": "DailyScheduledTaskSchedule", + "type": "object" + }, + { + "properties": { + "time": { + "type": "string" + }, + "type": { + "enum": [ + "weekdays" + ], + "title": "WeekdaysScheduledTaskScheduleType", + "type": "string" + } + }, + "required": [ + "time", + "type" + ], + "title": "WeekdaysScheduledTaskSchedule", + "type": "object" + }, + { + "properties": { + "days": { + "items": { + "$ref": "#/definitions/v2/ScheduledTaskWeekday" + }, + "type": "array" + }, + "time": { + "type": "string" + }, + "type": { + "enum": [ + "weekly" + ], + "title": "WeeklyScheduledTaskScheduleType", + "type": "string" + } + }, + "required": [ + "days", + "time", + "type" + ], + "title": "WeeklyScheduledTaskSchedule", + "type": "object" + } + ] + }, + "ScheduledTaskSummary": { + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prompt": { + "type": "string" + }, + "schedule": { + "$ref": "#/definitions/v2/ScheduledTaskSchedule" + } + }, + "required": [ + "key", + "name", + "prompt", + "schedule" + ], + "type": "object" + }, + "ScheduledTaskWeekday": { + "enum": [ + "MO", + "TU", + "WE", + "TH", + "FR", + "SA", + "SU" + ], + "type": "string" + }, + "SelectedCapabilityRoot": { + "description": "A user-selected root that can expose one or more runtime capabilities.", + "properties": { + "id": { + "description": "Stable identifier supplied by the capability selection platform.", + "type": "string" + }, + "location": { + "allOf": [ + { + "$ref": "#/definitions/v2/CapabilityRootLocation" + } + ], + "description": "Where the selected root can be resolved." + } + }, + "required": [ + "id", + "location" + ], + "type": "object" + }, + "SendAddCreditsNudgeEmailParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "creditType": { + "$ref": "#/definitions/v2/AddCreditsNudgeCreditType" + } + }, + "required": [ + "creditType" + ], + "title": "SendAddCreditsNudgeEmailParams", + "type": "object" + }, + "SendAddCreditsNudgeEmailResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "status": { + "$ref": "#/definitions/v2/AddCreditsNudgeEmailStatus" + } + }, + "required": [ + "status" + ], + "title": "SendAddCreditsNudgeEmailResponse", + "type": "object" + }, + "ServerDiagnosticsGauge": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "format": "uint64", + "minimum": 0.0, + "type": "integer" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "ServerDiagnosticsProcess": { + "properties": { + "id": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "physicalFootprintBytes": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "residentMemoryBytes": { + "format": "uint64", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "ServerRequestResolvedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "requestId": { + "$ref": "#/definitions/v2/RequestId" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "requestId", + "threadId" + ], + "title": "ServerRequestResolvedNotification", + "type": "object" + }, + "SessionMigration": { + "properties": { + "cwd": { + "type": "string" + }, + "path": { + "type": "string" + }, + "title": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "cwd", + "path" + ], + "type": "object" + }, + "SessionSource": { + "oneOf": [ + { + "enum": [ + "cli", + "vscode", + "exec", + "appServer", + "unknown" + ], + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "custom": { + "type": "string" + } + }, + "required": [ + "custom" + ], + "title": "CustomSessionSource", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "subAgent": { + "$ref": "#/definitions/v2/SubAgentSource" + } + }, + "required": [ + "subAgent" + ], + "title": "SubAgentSessionSource", + "type": "object" + } + ] + }, + "Settings": { + "description": "Settings for a collaboration mode.", + "properties": { + "developer_instructions": { + "type": [ + "string", + "null" + ] + }, + "model": { + "type": "string" + }, + "reasoning_effort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "model" + ], + "type": "object" + }, + "SkillDependencies": { + "properties": { + "tools": { + "items": { + "$ref": "#/definitions/v2/SkillToolDependency" + }, + "type": "array" + } + }, + "required": [ + "tools" + ], + "type": "object" + }, + "SkillErrorInfo": { + "properties": { + "message": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "required": [ + "message", + "path" + ], + "type": "object" + }, + "SkillInterface": { + "properties": { + "brandColor": { + "type": [ + "string", + "null" + ] + }, + "defaultPrompt": { + "type": [ + "string", + "null" + ] + }, + "displayName": { + "type": [ + "string", + "null" + ] + }, + "iconLarge": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "iconLargeUrl": { + "description": "Remote large icon URL from the plugin catalog.", + "type": [ + "string", + "null" + ] + }, + "iconSmall": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "iconSmallUrl": { + "description": "Remote small icon URL from the plugin catalog.", + "type": [ + "string", + "null" + ] + }, + "shortDescription": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "SkillMetadata": { + "properties": { + "dependencies": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SkillDependencies" + }, + { + "type": "null" + } + ] + }, + "description": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "interface": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SkillInterface" + }, + { + "type": "null" + } + ] + }, + "name": { + "type": "string" + }, + "path": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "pluginId": { + "description": "Owning plugin ID, matching `PluginSummary.id`, when known.", + "type": [ + "string", + "null" + ] + }, + "scope": { + "$ref": "#/definitions/v2/SkillScope" + }, + "shortDescription": { + "description": "Legacy short_description from SKILL.md. Prefer SKILL.json interface.short_description.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "description", + "enabled", + "name", + "path", + "scope" + ], + "type": "object" + }, + "SkillMigration": { + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "SkillScope": { + "enum": [ + "user", + "repo", + "system", + "admin" + ], + "type": "string" + }, + "SkillSummary": { + "properties": { + "description": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "interface": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SkillInterface" + }, + { + "type": "null" + } + ] + }, + "name": { + "type": "string" + }, + "path": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "shortDescription": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "description", + "enabled", + "name" + ], + "type": "object" + }, + "SkillToolDependency": { + "properties": { + "command": { + "type": [ + "string", + "null" + ] + }, + "description": { + "type": [ + "string", + "null" + ] + }, + "transport": { + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string" + }, + "url": { + "type": [ + "string", + "null" + ] + }, + "value": { + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "type": "object" + }, + "SkillsChangedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Notification emitted when watched local skill files change.\n\nTreat this as an invalidation signal and re-run `skills/list` with the client's current parameters when refreshed skill metadata is needed.", + "title": "SkillsChangedNotification", + "type": "object" + }, + "SkillsConfigWriteParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "enabled": { + "type": "boolean" + }, + "name": { + "description": "Name-based selector.", + "type": [ + "string", + "null" + ] + }, + "path": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ], + "description": "Path-based selector." + } + }, + "required": [ + "enabled" + ], + "title": "SkillsConfigWriteParams", + "type": "object" + }, + "SkillsConfigWriteResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "effectiveEnabled": { + "type": "boolean" + } + }, + "required": [ + "effectiveEnabled" + ], + "title": "SkillsConfigWriteResponse", + "type": "object" + }, + "SkillsExtraRootsSetParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "extraRoots": { + "items": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "type": "array" + } + }, + "required": [ + "extraRoots" + ], + "title": "SkillsExtraRootsSetParams", + "type": "object" + }, + "SkillsExtraRootsSetResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "SkillsExtraRootsSetResponse", + "type": "object" + }, + "SkillsListEntry": { + "properties": { + "cwd": { + "type": "string" + }, + "errors": { + "items": { + "$ref": "#/definitions/v2/SkillErrorInfo" + }, + "type": "array" + }, + "skills": { + "items": { + "$ref": "#/definitions/v2/SkillMetadata" + }, + "type": "array" + } + }, + "required": [ + "cwd", + "errors", + "skills" + ], + "type": "object" + }, + "SkillsListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cwds": { + "description": "When empty, defaults to the current session working directory.", + "items": { + "type": "string" + }, + "type": "array" + }, + "forceReload": { + "description": "When true, bypass the skills cache and re-scan skills from disk.", + "type": "boolean" + } + }, + "title": "SkillsListParams", + "type": "object" + }, + "SkillsListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/SkillsListEntry" + }, + "type": "array" + } + }, + "required": [ + "data" + ], + "title": "SkillsListResponse", + "type": "object" + }, + "SortDirection": { + "enum": [ + "asc", + "desc" + ], + "type": "string" + }, + "SpendControlLimitSnapshot": { + "properties": { + "limit": { + "type": "string" + }, + "remainingPercent": { + "format": "int32", + "type": "integer" + }, + "resetsAt": { + "format": "int64", + "type": "integer" + }, + "used": { + "type": "string" + } + }, + "required": [ + "limit", + "remainingPercent", + "resetsAt", + "used" + ], + "type": "object" + }, + "StrictReviewRequiredNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "startedAtMs": { + "description": "Unix timestamp (in milliseconds) when this review started.", + "format": "int64", + "type": "integer" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "startedAtMs", + "threadId", + "turnId" + ], + "title": "StrictReviewRequiredNotification", + "type": "object" + }, + "SubAgentActivityKind": { + "enum": [ + "started", + "interacted", + "interrupted", + "completed" + ], + "type": "string" + }, + "SubAgentSource": { + "oneOf": [ + { + "enum": [ + "review", + "compact", + "memory_consolidation" + ], + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "thread_spawn": { + "properties": { + "agent_nickname": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "agent_path": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AgentPath" + }, + { + "type": "null" + } + ], + "default": null + }, + "agent_role": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "depth": { + "format": "int32", + "type": "integer" + }, + "parent_thread_id": { + "$ref": "#/definitions/v2/ThreadId" + } + }, + "required": [ + "depth", + "parent_thread_id" + ], + "type": "object" + } + }, + "required": [ + "thread_spawn" + ], + "title": "ThreadSpawnSubAgentSource", + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "other": { + "type": "string" + } + }, + "required": [ + "other" + ], + "title": "OtherSubAgentSource", + "type": "object" + } + ] + }, + "SubagentMigration": { + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "TerminalInteractionNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "itemId": { + "type": "string" + }, + "processId": { + "type": "string" + }, + "stdin": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "itemId", + "processId", + "stdin", + "threadId", + "turnId" + ], + "title": "TerminalInteractionNotification", + "type": "object" + }, + "TextElement": { + "properties": { + "byteRange": { + "allOf": [ + { + "$ref": "#/definitions/v2/ByteRange" + } + ], + "description": "Byte range in the parent `text` buffer that this element occupies." + }, + "placeholder": { + "description": "Optional human-readable placeholder for the element, displayed in the UI.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "byteRange" + ], + "type": "object" + }, + "TextPosition": { + "properties": { + "column": { + "description": "1-based column number (in Unicode scalar values).", + "format": "uint", + "minimum": 0.0, + "type": "integer" + }, + "line": { + "description": "1-based line number.", + "format": "uint", + "minimum": 0.0, + "type": "integer" + } + }, + "required": [ + "column", + "line" + ], + "type": "object" + }, + "TextRange": { + "properties": { + "end": { + "$ref": "#/definitions/v2/TextPosition" + }, + "start": { + "$ref": "#/definitions/v2/TextPosition" + } + }, + "required": [ + "end", + "start" + ], + "type": "object" + }, + "Thread": { + "properties": { + "agentNickname": { + "description": "Optional random unique nickname assigned to an AgentControl-spawned sub-agent.", + "type": [ + "string", + "null" + ] + }, + "agentRole": { + "description": "Optional role (agent_role) assigned to an AgentControl-spawned sub-agent.", + "type": [ + "string", + "null" + ] + }, + "cliVersion": { + "description": "Version of the CLI that created the thread.", + "type": "string" + }, + "createdAt": { + "description": "Unix timestamp (in seconds) when the thread was created.", + "format": "int64", + "type": "integer" + }, + "cwd": { + "allOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + } + ], + "description": "Working directory captured for the thread." + }, + "ephemeral": { + "description": "Whether the thread is ephemeral and should not be materialized on disk.", + "type": "boolean" + }, + "forkedFromId": { + "description": "Source thread id when this thread was created by forking another thread.", + "type": [ + "string", + "null" + ] + }, + "gitInfo": { + "anyOf": [ + { + "$ref": "#/definitions/v2/GitInfo" + }, + { + "type": "null" + } + ], + "description": "Optional Git metadata captured when the thread was created." + }, + "historyMode": { + "allOf": [ + { + "$ref": "#/definitions/v2/ThreadHistoryMode" + } + ], + "default": "legacy", + "description": "Persisted thread history contract selected when this thread was created." + }, + "id": { + "description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.", + "type": "string" + }, + "model": { + "description": "Current configured model when loaded, otherwise the latest persisted model. Null when unavailable. This is not per-turn execution telemetry.", + "type": [ + "string", + "null" + ] + }, + "modelProvider": { + "description": "Model provider used for this thread (for example, 'openai').", + "type": "string" + }, + "name": { + "description": "Optional user-facing thread title.", + "type": [ + "string", + "null" + ] + }, + "originator": { + "description": "Originator recorded when the thread was created, independent of its current client or executor. Null when the recorded originator is unavailable.", + "type": [ + "string", + "null" + ] + }, + "parentThreadId": { + "description": "The ID of the parent thread. This will only be set if this thread is a subagent.", + "type": [ + "string", + "null" + ] + }, + "path": { + "description": "[UNSTABLE] Path to the thread on disk.", + "type": [ + "string", + "null" + ] + }, + "preview": { + "description": "Usually the first user message in the thread, if available.", + "type": "string" + }, + "projectId": { + "description": "Canonical project assignment owned by app-server, if any.", + "type": [ + "string", + "null" + ] + }, + "reasoningEffort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ], + "description": "Current configured reasoning effort when loaded, otherwise the latest persisted effort. Null when unset or unavailable. This is not per-turn execution telemetry." + }, + "recencyAt": { + "description": "Unix timestamp (in seconds) used for thread recency ordering.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "section": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadSection" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The independently persisted section selected for this thread, if any." + }, + "sectionEnteredAt": { + "default": null, + "description": "Unix timestamp in seconds when the thread entered its current section.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "sessionId": { + "description": "Session id shared by threads that belong to the same session tree.", + "type": "string" + }, + "source": { + "allOf": [ + { + "$ref": "#/definitions/v2/SessionSource" + } + ], + "description": "Origin of the thread (CLI, VSCode, codex exec, codex app-server, etc.)." + }, + "status": { + "allOf": [ + { + "$ref": "#/definitions/v2/ThreadStatus" + } + ], + "description": "Current runtime status for the thread." + }, + "threadSource": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadSource" + }, + { + "type": "null" + } + ], + "description": "Optional analytics source classification for this thread." + }, + "turns": { + "description": "Only populated on `thread/resume`, `thread/fork`, and `thread/read` (when `includeTurns` is true) responses. For all other responses and notifications returning a Thread, the turns field will be an empty list.", + "items": { + "$ref": "#/definitions/v2/Turn" + }, + "type": "array" + }, + "updatedAt": { + "description": "Unix timestamp (in seconds) when the thread was last updated.", + "format": "int64", + "type": "integer" + } + }, + "required": [ + "cliVersion", + "createdAt", + "cwd", + "ephemeral", + "id", + "modelProvider", + "preview", + "projectId", + "sessionId", + "source", + "status", + "turns", + "updatedAt" + ], + "type": "object" + }, + "ThreadActiveFlag": { + "enum": [ + "waitingOnApproval", + "waitingOnUserInput" + ], + "type": "string" + }, + "ThreadApproveGuardianDeniedActionParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "event": { + "description": "Serialized `codex_protocol::protocol::GuardianAssessmentEvent`." + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "event", + "threadId" + ], + "title": "ThreadApproveGuardianDeniedActionParams", + "type": "object" + }, + "ThreadApproveGuardianDeniedActionResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThreadApproveGuardianDeniedActionResponse", + "type": "object" + }, + "ThreadArchiveParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadArchiveParams", + "type": "object" + }, + "ThreadArchiveResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThreadArchiveResponse", + "type": "object" + }, + "ThreadArchivedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadArchivedNotification", + "type": "object" + }, + "ThreadAttachment": { + "description": "An independently persisted attachment associated with a thread.", + "properties": { + "attachmentType": { + "type": "string" + }, + "createdAt": { + "format": "int64", + "type": "integer" + }, + "id": { + "type": "string" + }, + "identityKey": { + "type": "string" + }, + "payload": true + }, + "required": [ + "attachmentType", + "createdAt", + "id", + "identityKey", + "payload" + ], + "type": "object" + }, + "ThreadAttachmentAddOutcome": { + "description": "Result of attempting to associate an attachment with a thread.", + "enum": [ + "created", + "existing" + ], + "type": "string" + }, + "ThreadAttachmentAddParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Parameters for creating or locating an attachment on its owning thread.", + "properties": { + "attachmentType": { + "type": "string" + }, + "identityKey": { + "type": "string" + }, + "payload": true, + "threadId": { + "type": "string" + } + }, + "required": [ + "attachmentType", + "identityKey", + "payload", + "threadId" + ], + "title": "ThreadAttachmentAddParams", + "type": "object" + }, + "ThreadAttachmentAddResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "The created or existing attachment.", + "properties": { + "attachment": { + "$ref": "#/definitions/v2/ThreadAttachment" + }, + "outcome": { + "$ref": "#/definitions/v2/ThreadAttachmentAddOutcome" + } + }, + "required": [ + "attachment", + "outcome" + ], + "title": "ThreadAttachmentAddResponse", + "type": "object" + }, + "ThreadAttachmentListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Parameters for listing attachments from one thread.", + "properties": { + "cursor": { + "type": [ + "string", + "null" + ] + }, + "limit": { + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadAttachmentListParams", + "type": "object" + }, + "ThreadAttachmentListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "One page of attachments associated with the requested thread.", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/ThreadAttachment" + }, + "type": "array" + }, + "nextCursor": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ThreadAttachmentListResponse", + "type": "object" + }, + "ThreadAttachmentOperation": { + "description": "The persisted attachment change represented by a notification.", + "enum": [ + "created", + "deleted" + ], + "type": "string" + }, + "ThreadAttachmentRemoveParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Parameters for deleting an attachment by its stable thread-local identity.", + "properties": { + "attachmentType": { + "type": "string" + }, + "identityKey": { + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "attachmentType", + "identityKey", + "threadId" + ], + "title": "ThreadAttachmentRemoveParams", + "type": "object" + }, + "ThreadAttachmentRemoveResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Successful deletion does not return additional attachment data.", + "title": "ThreadAttachmentRemoveResponse", + "type": "object" + }, + "ThreadAttachmentUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Notification published after a thread attachment is created or deleted.", + "properties": { + "attachmentId": { + "type": "string" + }, + "attachmentType": { + "type": "string" + }, + "identityKey": { + "type": "string" + }, + "operation": { + "$ref": "#/definitions/v2/ThreadAttachmentOperation" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "attachmentId", + "attachmentType", + "identityKey", + "operation", + "threadId" + ], + "title": "ThreadAttachmentUpdatedNotification", + "type": "object" + }, + "ThreadClosedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadClosedNotification", + "type": "object" + }, + "ThreadCompactStartParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadCompactStartParams", + "type": "object" + }, + "ThreadCompactStartResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThreadCompactStartResponse", + "type": "object" + }, + "ThreadDeleteParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadDeleteParams", + "type": "object" + }, + "ThreadDeleteResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThreadDeleteResponse", + "type": "object" + }, + "ThreadDeletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadDeletedNotification", + "type": "object" + }, + "ThreadEnvironment": { + "description": "An environment selected by a loaded thread, independent of connection status.", + "properties": { + "cwd": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "environmentId": { + "type": "string" + }, + "runtimeWorkspaceRoots": { + "items": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": "array" + } + }, + "required": [ + "cwd", + "environmentId", + "runtimeWorkspaceRoots" + ], + "type": "object" + }, + "ThreadExtra": { + "description": "Extra app-server data for a thread.", + "type": "object" + }, + "ThreadForkParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "There are two ways to fork a thread: 1. By thread_id: load the thread from disk by thread_id and fork it into a new thread. 2. By path: load the thread from disk by path and fork it into a new thread.\n\nIf using a non-empty path, the thread_id param will be ignored. Empty string path values are treated as absent.\n\nPrefer using thread_id whenever possible.", + "properties": { + "approvalPolicy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AskForApproval" + }, + { + "type": "null" + } + ] + }, + "approvalsReviewer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + { + "type": "null" + } + ], + "description": "Override where approval requests are routed for review on this thread and subsequent turns." + }, + "baseInstructions": { + "type": [ + "string", + "null" + ] + }, + "config": { + "additionalProperties": true, + "type": [ + "object", + "null" + ] + }, + "cwd": { + "type": [ + "string", + "null" + ] + }, + "developerInstructions": { + "type": [ + "string", + "null" + ] + }, + "ephemeral": { + "type": "boolean" + }, + "excludeTurns": { + "description": "When true, return only thread metadata and live fork state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after forking. Full-history hydration is deprecated for paginated threads; use this with `thread/turns/list` and `thread/items/list` instead.", + "type": "boolean" + }, + "lastTurnId": { + "description": "Optional last turn id to fork through, inclusive.\n\nWhen specified, turns after `last_turn_id` are omitted from the fork. The referenced turn cannot be in progress.", + "type": [ + "string", + "null" + ] + }, + "model": { + "description": "Configuration overrides for the forked thread, if any.", + "type": [ + "string", + "null" + ] + }, + "modelProvider": { + "type": [ + "string", + "null" + ] + }, + "sandbox": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SandboxMode" + }, + { + "type": "null" + } + ] + }, + "serviceTier": { + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + }, + "threadSource": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadSource" + }, + { + "type": "null" + } + ], + "description": "Optional client-supplied analytics source classification for this forked thread." + } + }, + "required": [ + "threadId" + ], + "title": "ThreadForkParams", + "type": "object" + }, + "ThreadForkResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "approvalPolicy": { + "$ref": "#/definitions/v2/AskForApproval" + }, + "approvalsReviewer": { + "allOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + } + ], + "description": "Reviewer currently used for approval requests on this thread." + }, + "cwd": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "disabledPluginIds": { + "default": [], + "description": "Saved list of disabled plugin IDs. Does not yet filter plugin capabilities.", + "items": { + "type": "string" + }, + "type": "array" + }, + "instructionSources": { + "default": [], + "description": "Environment-native paths to instruction source files currently loaded for this thread.", + "items": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": "array" + }, + "model": { + "type": "string" + }, + "modelProvider": { + "type": "string" + }, + "reasoningEffort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ] + }, + "sandbox": { + "allOf": [ + { + "$ref": "#/definitions/v2/SandboxPolicy" + } + ], + "description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance." + }, + "serviceTier": { + "type": [ + "string", + "null" + ] + }, + "thread": { + "$ref": "#/definitions/v2/Thread" + } + }, + "required": [ + "approvalPolicy", + "approvalsReviewer", + "cwd", + "model", + "modelProvider", + "sandbox", + "thread" + ], + "title": "ThreadForkResponse", + "type": "object" + }, + "ThreadGoal": { + "properties": { + "createdAt": { + "format": "int64", + "type": "integer" + }, + "objective": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v2/ThreadGoalStatus" + }, + "threadId": { + "type": "string" + }, + "timeUsedSeconds": { + "format": "int64", + "type": "integer" + }, + "tokenBudget": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "tokensUsed": { + "format": "int64", + "type": "integer" + }, + "updatedAt": { + "format": "int64", + "type": "integer" + } + }, + "required": [ + "createdAt", + "objective", + "status", + "threadId", + "timeUsedSeconds", + "tokensUsed", + "updatedAt" + ], + "type": "object" + }, + "ThreadGoalClearParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadGoalClearParams", + "type": "object" + }, + "ThreadGoalClearResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cleared": { + "type": "boolean" + } + }, + "required": [ + "cleared" + ], + "title": "ThreadGoalClearResponse", + "type": "object" + }, + "ThreadGoalClearedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadGoalClearedNotification", + "type": "object" + }, + "ThreadGoalGetParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadGoalGetParams", + "type": "object" + }, + "ThreadGoalGetResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "goal": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadGoal" + }, + { + "type": "null" + } + ] + } + }, + "title": "ThreadGoalGetResponse", + "type": "object" + }, + "ThreadGoalSetParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "objective": { + "type": [ + "string", + "null" + ] + }, + "status": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadGoalStatus" + }, + { + "type": "null" + } + ] + }, + "threadId": { + "type": "string" + }, + "tokenBudget": { + "format": "int64", + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "threadId" + ], + "title": "ThreadGoalSetParams", + "type": "object" + }, + "ThreadGoalSetResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "goal": { + "$ref": "#/definitions/v2/ThreadGoal" + } + }, + "required": [ + "goal" + ], + "title": "ThreadGoalSetResponse", + "type": "object" + }, + "ThreadGoalStatus": { + "enum": [ + "active", + "paused", + "blocked", + "usageLimited", + "budgetLimited", + "complete" + ], + "type": "string" + }, + "ThreadGoalUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "goal": { + "$ref": "#/definitions/v2/ThreadGoal" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "goal", + "threadId" + ], + "title": "ThreadGoalUpdatedNotification", + "type": "object" + }, + "ThreadHistoryMode": { + "enum": [ + "legacy", + "paginated" + ], + "type": "string" + }, + "ThreadId": { + "type": "string" + }, + "ThreadInjectItemsParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "items": { + "description": "Raw Responses API items to append to the thread's model-visible history.", + "items": true, + "type": "array" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "items", + "threadId" + ], + "title": "ThreadInjectItemsParams", + "type": "object" + }, + "ThreadInjectItemsResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThreadInjectItemsResponse", + "type": "object" + }, + "ThreadItem": { + "oneOf": [ + { + "properties": { + "clientId": { + "type": [ + "string", + "null" + ] + }, + "content": { + "items": { + "$ref": "#/definitions/v2/UserInput" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "userMessage" + ], + "title": "UserMessageThreadItemType", + "type": "string" + } + }, + "required": [ + "content", + "id", + "type" + ], + "title": "UserMessageThreadItem", + "type": "object" + }, + { + "properties": { + "fragments": { + "items": { + "$ref": "#/definitions/v2/HookPromptFragment" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "hookPrompt" + ], + "title": "HookPromptThreadItemType", + "type": "string" + } + }, + "required": [ + "fragments", + "id", + "type" + ], + "title": "HookPromptThreadItem", + "type": "object" + }, + { + "properties": { + "delivery": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AgentMessageDelivery" + }, + { + "type": "null" + } + ], + "default": null + }, + "id": { + "type": "string" + }, + "memoryCitation": { + "anyOf": [ + { + "$ref": "#/definitions/v2/MemoryCitation" + }, + { + "type": "null" + } + ], + "default": null + }, + "phase": { + "anyOf": [ + { + "$ref": "#/definitions/v2/MessagePhase" + }, + { + "type": "null" + } + ], + "default": null + }, + "questions": { + "default": null, + "items": { + "$ref": "#/definitions/v2/AsyncUserInputQuestion" + }, + "type": [ + "array", + "null" + ] + }, + "text": { + "type": "string" + }, + "type": { + "enum": [ + "agentMessage" + ], + "title": "AgentMessageThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "text", + "type" + ], + "title": "AgentMessageThreadItem", + "type": "object" + }, + { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": [ + "string", + "null" + ] + }, + "output": { + "$ref": "#/definitions/v2/FunctionCallOutputBody" + }, + "type": { + "enum": [ + "functionCallOutput" + ], + "title": "FunctionCallOutputThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "name", + "output", + "type" + ], + "title": "FunctionCallOutputThreadItem", + "type": "object" + }, + { + "description": "EXPERIMENTAL - proposed plan item content. The completed plan item is authoritative and may not match the concatenation of `PlanDelta` text.", + "properties": { + "id": { + "type": "string" + }, + "text": { + "type": "string" + }, + "type": { + "enum": [ + "plan" + ], + "title": "PlanThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "text", + "type" + ], + "title": "PlanThreadItem", + "type": "object" + }, + { + "properties": { + "content": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "summary": { + "default": [], + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "enum": [ + "reasoning" + ], + "title": "ReasoningThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "title": "ReasoningThreadItem", + "type": "object" + }, + { + "properties": { + "aggregatedOutput": { + "description": "The command's output, aggregated from stdout and stderr.", + "type": [ + "string", + "null" + ] + }, + "command": { + "description": "The command to be executed.", + "type": "string" + }, + "commandActions": { + "description": "A best-effort parsing of the command to understand the action(s) it will perform. This returns a list of CommandAction objects because a single shell command may be composed of many commands piped together.", + "items": { + "$ref": "#/definitions/v2/CommandAction" + }, + "type": "array" + }, + "cwd": { + "allOf": [ + { + "$ref": "#/definitions/v2/LegacyAppPathString" + } + ], + "description": "The command's working directory." + }, + "durationMs": { + "description": "The duration of the command execution in milliseconds.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "exitCode": { + "description": "The command's exit code.", + "format": "int32", + "type": [ + "integer", + "null" + ] + }, + "id": { + "type": "string" + }, + "pluginId": { + "default": null, + "description": "Trusted first-party plugin id when this command resolves to one plugin script.", + "type": [ + "string", + "null" + ] + }, + "processId": { + "description": "Identifier for the underlying PTY process (when available).", + "type": [ + "string", + "null" + ] + }, + "scriptPath": { + "default": null, + "description": "Safe plugin-relative path when this command resolves to one plugin script.", + "type": [ + "string", + "null" + ] + }, + "source": { + "allOf": [ + { + "$ref": "#/definitions/v2/CommandExecutionSource" + } + ], + "default": "agent" + }, + "status": { + "$ref": "#/definitions/v2/CommandExecutionStatus" + }, + "type": { + "enum": [ + "commandExecution" + ], + "title": "CommandExecutionThreadItemType", + "type": "string" + } + }, + "required": [ + "command", + "commandActions", + "cwd", + "id", + "status", + "type" + ], + "title": "CommandExecutionThreadItem", + "type": "object" + }, + { + "properties": { + "changes": { + "items": { + "$ref": "#/definitions/v2/FileUpdateChange" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v2/PatchApplyStatus" + }, + "type": { + "enum": [ + "fileChange" + ], + "title": "FileChangeThreadItemType", + "type": "string" + } + }, + "required": [ + "changes", + "id", + "status", + "type" + ], + "title": "FileChangeThreadItem", + "type": "object" + }, + { + "properties": { + "appContext": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpToolCallAppContext" + }, + { + "type": "null" + } + ] + }, + "arguments": true, + "durationMs": { + "description": "The duration of the MCP tool call in milliseconds.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "error": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpToolCallError" + }, + { + "type": "null" + } + ] + }, + "id": { + "type": "string" + }, + "mcpAppResourceUri": { + "description": "Legacy compatibility field; prefer `mcpAppUi.resourceUri` when available.", + "type": [ + "string", + "null" + ] + }, + "mcpAppUi": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpAppUi" + }, + { + "type": "null" + } + ], + "description": "Presentation captured from the invoked descriptor; absent in older history." + }, + "pluginId": { + "type": [ + "string", + "null" + ] + }, + "readOnlyHint": { + "type": [ + "boolean", + "null" + ] + }, + "result": { + "anyOf": [ + { + "$ref": "#/definitions/v2/McpToolCallResult" + }, + { + "type": "null" + } + ] + }, + "server": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/v2/McpToolCallStatus" + }, + "tool": { + "type": "string" + }, + "type": { + "enum": [ + "mcpToolCall" + ], + "title": "McpToolCallThreadItemType", + "type": "string" + } + }, + "required": [ + "arguments", + "id", + "server", + "status", + "tool", + "type" + ], + "title": "McpToolCallThreadItem", + "type": "object" + }, + { + "properties": { + "arguments": true, + "contentItems": { + "items": { + "$ref": "#/definitions/v2/DynamicToolCallOutputContentItem" + }, + "type": [ + "array", + "null" + ] + }, + "durationMs": { + "description": "The duration of the dynamic tool call in milliseconds.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "id": { + "type": "string" + }, + "namespace": { + "type": [ + "string", + "null" + ] + }, + "status": { + "$ref": "#/definitions/v2/DynamicToolCallStatus" + }, + "success": { + "type": [ + "boolean", + "null" + ] + }, + "tool": { + "type": "string" + }, + "type": { + "enum": [ + "dynamicToolCall" + ], + "title": "DynamicToolCallThreadItemType", + "type": "string" + } + }, + "required": [ + "arguments", + "id", + "status", + "tool", + "type" + ], + "title": "DynamicToolCallThreadItem", + "type": "object" + }, + { + "properties": { + "agentsStates": { + "additionalProperties": { + "$ref": "#/definitions/v2/CollabAgentState" + }, + "description": "Last known status of the target agents, when available.", + "type": "object" + }, + "id": { + "description": "Unique identifier for this collab tool call.", + "type": "string" + }, + "model": { + "description": "Model requested for the spawned agent, when applicable.", + "type": [ + "string", + "null" + ] + }, + "prompt": { + "description": "Prompt text sent as part of the collab tool call, when available.", + "type": [ + "string", + "null" + ] + }, + "reasoningEffort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ], + "description": "Reasoning effort requested for the spawned agent, when applicable." + }, + "receiverThreadIds": { + "description": "Thread ID of the receiving agent, when applicable. In case of spawn operation, this corresponds to the newly spawned agent.", + "items": { + "type": "string" + }, + "type": "array" + }, + "senderThreadId": { + "description": "Thread ID of the agent issuing the collab request.", + "type": "string" + }, + "status": { + "allOf": [ + { + "$ref": "#/definitions/v2/CollabAgentToolCallStatus" + } + ], + "description": "Current status of the collab tool call." + }, + "tool": { + "allOf": [ + { + "$ref": "#/definitions/v2/CollabAgentTool" + } + ], + "description": "Name of the collab tool that was invoked." + }, + "type": { + "enum": [ + "collabAgentToolCall" + ], + "title": "CollabAgentToolCallThreadItemType", + "type": "string" + } + }, + "required": [ + "agentsStates", + "id", + "receiverThreadIds", + "senderThreadId", + "status", + "tool", + "type" + ], + "title": "CollabAgentToolCallThreadItem", + "type": "object" + }, + { + "properties": { + "agentPath": { + "type": "string" + }, + "agentThreadId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "kind": { + "$ref": "#/definitions/v2/SubAgentActivityKind" + }, + "type": { + "enum": [ + "subAgentActivity" + ], + "title": "SubAgentActivityThreadItemType", + "type": "string" + } + }, + "required": [ + "agentPath", + "agentThreadId", + "id", + "kind", + "type" + ], + "title": "SubAgentActivityThreadItem", + "type": "object" + }, + { + "properties": { + "action": { + "anyOf": [ + { + "$ref": "#/definitions/v2/WebSearchAction" + }, + { + "type": "null" + } + ] + }, + "id": { + "type": "string" + }, + "query": { + "type": "string" + }, + "results": { + "default": null, + "description": "Structured search results returned out-of-band by standalone web search.\n\nThese stay as opaque JSON at the extension/app-server boundary so new result fields and result types can pass through without a Codex release.", + "items": true, + "type": [ + "array", + "null" + ] + }, + "type": { + "enum": [ + "webSearch" + ], + "title": "WebSearchThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "query", + "type" + ], + "title": "WebSearchThreadItem", + "type": "object" + }, + { + "properties": { + "id": { + "type": "string" + }, + "path": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": { + "enum": [ + "imageView" + ], + "title": "ImageViewThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "path", + "type" + ], + "title": "ImageViewThreadItem", + "type": "object" + }, + { + "description": "Display item emitted by the interruptible `clock.sleep` tool.", + "properties": { + "durationMs": { + "format": "uint64", + "minimum": 0.0, + "type": "integer" + }, + "id": { + "type": "string" + }, + "type": { + "enum": [ + "sleep" + ], + "title": "SleepThreadItemType", + "type": "string" + } + }, + "required": [ + "durationMs", + "id", + "type" + ], + "title": "SleepThreadItem", + "type": "object" + }, + { + "properties": { + "failure": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ImageGenerationFailure" + }, + { + "type": "null" + } + ], + "default": null + }, + "id": { + "type": "string" + }, + "result": { + "type": "string" + }, + "revisedPrompt": { + "type": [ + "string", + "null" + ] + }, + "savedPath": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "status": { + "type": "string" + }, + "transparentBackground": { + "default": null, + "type": [ + "boolean", + "null" + ] + }, + "type": { + "enum": [ + "imageGeneration" + ], + "title": "ImageGenerationThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "result", + "status", + "type" + ], + "title": "ImageGenerationThreadItem", + "type": "object" + }, + { + "properties": { + "id": { + "type": "string" + }, + "review": { + "type": "string" + }, + "type": { + "enum": [ + "enteredReviewMode" + ], + "title": "EnteredReviewModeThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "review", + "type" + ], + "title": "EnteredReviewModeThreadItem", + "type": "object" + }, + { + "properties": { + "id": { + "type": "string" + }, + "review": { + "type": "string" + }, + "type": { + "enum": [ + "exitedReviewMode" + ], + "title": "ExitedReviewModeThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "review", + "type" + ], + "title": "ExitedReviewModeThreadItem", + "type": "object" + }, + { + "properties": { + "id": { + "type": "string" + }, + "type": { + "enum": [ + "contextCompaction" + ], + "title": "ContextCompactionThreadItemType", + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "title": "ContextCompactionThreadItem", + "type": "object" + } + ] + }, + "ThreadItemEntry": { + "properties": { + "completedAtMs": { + "description": "Unix timestamp (milliseconds) when the item completed, if recorded by the producer.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "item": { + "$ref": "#/definitions/v2/ThreadItem" + }, + "startedAtMs": { + "description": "Unix timestamp (milliseconds) when the item started, if recorded by the producer.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "turnId": { + "description": "Turn containing this item.", + "type": "string" + } + }, + "required": [ + "item", + "turnId" + ], + "type": "object" + }, + "ThreadItemsListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item.", + "type": [ + "string", + "null" + ] + }, + "limit": { + "description": "Optional item page size.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "sortDirection": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SortDirection" + }, + { + "type": "null" + } + ], + "description": "Optional item pagination direction; defaults to ascending." + }, + "threadId": { + "type": "string" + }, + "turnId": { + "description": "Optional turn id to filter by. When omitted, returns items across the thread.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "threadId" + ], + "title": "ThreadItemsListParams", + "type": "object" + }, + "ThreadItemsListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "backwardsCursor": { + "description": "Opaque cursor to pass as `cursor` when reversing `sortDirection`. This is only populated when the page contains at least one item.", + "type": [ + "string", + "null" + ] + }, + "data": { + "items": { + "$ref": "#/definitions/v2/ThreadItemEntry" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item. if None, there are no more items to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ThreadItemsListResponse", + "type": "object" + }, + "ThreadListCwdFilter": { + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ] + }, + "ThreadListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "archived": { + "description": "Optional archived filter; when set to true, only archived threads are returned. If false or null, only non-archived threads are returned.", + "type": [ + "boolean", + "null" + ] + }, + "cursor": { + "description": "Opaque pagination cursor returned by a previous call.", + "type": [ + "string", + "null" + ] + }, + "cwd": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadListCwdFilter" + }, + { + "type": "null" + } + ], + "description": "Optional cwd filter or filters; when set, only threads whose session cwd exactly matches one of these paths are returned." + }, + "limit": { + "description": "Optional page size; defaults to a reasonable server-side value.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "modelProviders": { + "description": "Optional provider filter; when set, only sessions recorded under these providers are returned. When present but empty, includes all providers.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "originators": { + "description": "Optional originator allowlist, matching any supplied value exactly. Supported by hosted backends only; the local app-server rejects a nonempty list. Omitted or empty lists leave originators unrestricted.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "searchTerm": { + "description": "Optional substring filter for the extracted thread title.", + "type": [ + "string", + "null" + ] + }, + "sectionId": { + "description": "Omit to include every section, set to `null` for unsectioned threads, or provide a section ID to return only threads in that section.", + "type": [ + "string", + "null" + ] + }, + "sortDirection": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SortDirection" + }, + { + "type": "null" + } + ], + "description": "Optional sort direction; defaults to descending (newest first)." + }, + "sortKey": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadSortKey" + }, + { + "type": "null" + } + ], + "description": "Optional sort key; defaults to created_at." + }, + "sourceKinds": { + "description": "Optional source filter; when set, only sessions from these source kinds are returned. When omitted or empty, defaults to interactive sources.", + "items": { + "$ref": "#/definitions/v2/ThreadSourceKind" + }, + "type": [ + "array", + "null" + ] + }, + "useStateDbOnly": { + "description": "If true, return from the state DB without scanning JSONL rollouts to repair thread metadata. Omitted or false preserves scan-and-repair behavior.", + "type": "boolean" + } + }, + "title": "ThreadListParams", + "type": "object" + }, + "ThreadListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "backwardsCursor": { + "description": "Opaque cursor to pass as `cursor` when reversing `sortDirection`. This is only populated when the page contains at least one thread. Use it with the opposite `sortDirection`; for timestamp sorts it anchors at the start of the page timestamp so same-second updates are not skipped.", + "type": [ + "string", + "null" + ] + }, + "data": { + "items": { + "$ref": "#/definitions/v2/Thread" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item. if None, there are no more items to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ThreadListResponse", + "type": "object" + }, + "ThreadLoadedListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cursor": { + "description": "Opaque pagination cursor returned by a previous call.", + "type": [ + "string", + "null" + ] + }, + "limit": { + "description": "Optional page size; defaults to no limit.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "title": "ThreadLoadedListParams", + "type": "object" + }, + "ThreadLoadedListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "data": { + "description": "Thread ids for sessions currently loaded in memory.", + "items": { + "type": "string" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last item. if None, there are no more items to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ThreadLoadedListResponse", + "type": "object" + }, + "ThreadMemoryMode": { + "enum": [ + "enabled", + "disabled" + ], + "type": "string" + }, + "ThreadMetadataGitInfoUpdateParams": { + "properties": { + "branch": { + "description": "Omit to leave the stored branch unchanged, set to `null` to clear it, or provide a non-empty string to replace it.", + "type": [ + "string", + "null" + ] + }, + "originUrl": { + "description": "Omit to leave the stored origin URL unchanged, set to `null` to clear it, or provide a non-empty string to replace it.", + "type": [ + "string", + "null" + ] + }, + "sha": { + "description": "Omit to leave the stored commit unchanged, set to `null` to clear it, or provide a non-empty string to replace it.", + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "ThreadMetadataUpdateParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "gitInfo": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadMetadataGitInfoUpdateParams" + }, + { + "type": "null" + } + ], + "description": "Patch the stored Git metadata for this thread. Omit a field to leave it unchanged, set it to `null` to clear it, or provide a string to replace the stored value." + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadMetadataUpdateParams", + "type": "object" + }, + "ThreadMetadataUpdateResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "thread": { + "$ref": "#/definitions/v2/Thread" + } + }, + "required": [ + "thread" + ], + "title": "ThreadMetadataUpdateResponse", + "type": "object" + }, + "ThreadNameUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + }, + "threadName": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "threadId" + ], + "title": "ThreadNameUpdatedNotification", + "type": "object" + }, + "ThreadProjectUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "projectId": { + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "projectId", + "threadId" + ], + "title": "ThreadProjectUpdatedNotification", + "type": "object" + }, + "ThreadQueueChangedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadQueueChangedNotification", + "type": "object" + }, + "ThreadReadParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "includeTurns": { + "description": "When true, include turns and their items from rollout history. Full-history hydration is deprecated for paginated threads; prefer a metadata-only read and page with `thread/turns/list` and `thread/items/list`.", + "type": "boolean" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadReadParams", + "type": "object" + }, + "ThreadReadResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "thread": { + "$ref": "#/definitions/v2/Thread" + } + }, + "required": [ + "thread" + ], + "title": "ThreadReadResponse", + "type": "object" + }, + "ThreadRealtimeAudioChunk": { + "description": "EXPERIMENTAL - thread realtime audio chunk.", + "properties": { + "data": { + "type": "string" + }, + "itemId": { + "type": [ + "string", + "null" + ] + }, + "numChannels": { + "format": "uint16", + "minimum": 0.0, + "type": "integer" + }, + "sampleRate": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "samplesPerChannel": { + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "data", + "numChannels", + "sampleRate" + ], + "type": "object" + }, + "ThreadRealtimeBemItemPresentation": { + "description": "EXPERIMENTAL - how an existing agent item appears in a realtime conversation.", + "oneOf": [ + { + "properties": { + "type": { + "enum": [ + "wholeItem" + ], + "title": "WholeItemThreadRealtimeBemItemPresentationType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "WholeItemThreadRealtimeBemItemPresentation", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "inlineMarkdown" + ], + "title": "InlineMarkdownThreadRealtimeBemItemPresentationType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "InlineMarkdownThreadRealtimeBemItemPresentation", + "type": "object" + }, + { + "properties": { + "index": { + "format": "uint32", + "minimum": 0.0, + "type": "integer" + }, + "type": { + "enum": [ + "inlineVisualization" + ], + "title": "InlineVisualizationThreadRealtimeBemItemPresentationType", + "type": "string" + } + }, + "required": [ + "index", + "type" + ], + "title": "InlineVisualizationThreadRealtimeBemItemPresentation", + "type": "object" + } + ] + }, + "ThreadRealtimeClosedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - emitted when thread realtime transport closes.", + "properties": { + "reason": { + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadRealtimeClosedNotification", + "type": "object" + }, + "ThreadRealtimeErrorNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - emitted when thread realtime encounters an error.", + "properties": { + "message": { + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "message", + "threadId" + ], + "title": "ThreadRealtimeErrorNotification", + "type": "object" + }, + "ThreadRealtimeInitialItem": { + "description": "EXPERIMENTAL - role-bearing text item included when a realtime V3 session starts.", + "properties": { + "role": { + "$ref": "#/definitions/v2/ConversationTextRole" + }, + "text": { + "type": "string" + } + }, + "required": [ + "role", + "text" + ], + "type": "object" + }, + "ThreadRealtimeItem": { + "description": "EXPERIMENTAL - a thread-scoped realtime item in the canonical timeline.", + "oneOf": [ + { + "properties": { + "type": { + "enum": [ + "realtimeSessionStarted" + ], + "title": "RealtimeSessionStartedThreadRealtimeItemType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "RealtimeSessionStartedThreadRealtimeItem", + "type": "object" + }, + { + "properties": { + "role": { + "$ref": "#/definitions/v2/ThreadRealtimeTranscriptRole" + }, + "text": { + "type": "string" + }, + "type": { + "enum": [ + "transcriptSegment" + ], + "title": "TranscriptSegmentThreadRealtimeItemType", + "type": "string" + } + }, + "required": [ + "role", + "text", + "type" + ], + "title": "TranscriptSegmentThreadRealtimeItem", + "type": "object" + }, + { + "properties": { + "item_id": { + "type": "string" + }, + "presentation": { + "$ref": "#/definitions/v2/ThreadRealtimeBemItemPresentation" + }, + "turn_id": { + "type": "string" + }, + "type": { + "enum": [ + "bemItemPromoted" + ], + "title": "BemItemPromotedThreadRealtimeItemType", + "type": "string" + } + }, + "required": [ + "item_id", + "presentation", + "turn_id", + "type" + ], + "title": "BemItemPromotedThreadRealtimeItem", + "type": "object" + }, + { + "properties": { + "outcome": { + "$ref": "#/definitions/v2/ThreadRealtimeSessionOutcome" + }, + "type": { + "enum": [ + "realtimeSessionClosed" + ], + "title": "RealtimeSessionClosedThreadRealtimeItemType", + "type": "string" + } + }, + "required": [ + "outcome", + "type" + ], + "title": "RealtimeSessionClosedThreadRealtimeItem", + "type": "object" + } + ], + "properties": { + "id": { + "type": "string" + }, + "realtimeSessionId": { + "type": "string" + } + }, + "required": [ + "id", + "realtimeSessionId" + ], + "type": "object" + }, + "ThreadRealtimeItemAddedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - raw non-audio thread realtime item emitted by the backend.", + "properties": { + "item": true, + "threadId": { + "type": "string" + } + }, + "required": [ + "item", + "threadId" + ], + "title": "ThreadRealtimeItemAddedNotification", + "type": "object" + }, + "ThreadRealtimeItemCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - a realtime timeline item published after canonical commit.", + "properties": { + "item": { + "$ref": "#/definitions/v2/ThreadRealtimeItem" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "item", + "threadId" + ], + "title": "ThreadRealtimeItemCompletedNotification", + "type": "object" + }, + "ThreadRealtimeItemStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - a realtime timeline item started before its content streams.", + "properties": { + "item": { + "$ref": "#/definitions/v2/ThreadRealtimeItem" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "item", + "threadId" + ], + "title": "ThreadRealtimeItemStartedNotification", + "type": "object" + }, + "ThreadRealtimeItemTranscriptDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - text appended to an active realtime transcript item.", + "properties": { + "delta": { + "type": "string" + }, + "itemId": { + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "delta", + "itemId", + "threadId" + ], + "title": "ThreadRealtimeItemTranscriptDeltaNotification", + "type": "object" + }, + "ThreadRealtimeOutputAudioDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - streamed output audio emitted by thread realtime.", + "properties": { + "audio": { + "$ref": "#/definitions/v2/ThreadRealtimeAudioChunk" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "audio", + "threadId" + ], + "title": "ThreadRealtimeOutputAudioDeltaNotification", + "type": "object" + }, + "ThreadRealtimeSdpNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - emitted with the remote SDP for a WebRTC realtime session.", + "properties": { + "sdp": { + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "sdp", + "threadId" + ], + "title": "ThreadRealtimeSdpNotification", + "type": "object" + }, + "ThreadRealtimeSessionOutcome": { + "enum": [ + "ended", + "failed" + ], + "type": "string" + }, + "ThreadRealtimeStartTransport": { + "description": "EXPERIMENTAL - transport used by thread realtime.", + "oneOf": [ + { + "properties": { + "type": { + "enum": [ + "websocket" + ], + "title": "WebsocketThreadRealtimeStartTransportType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "WebsocketThreadRealtimeStartTransport", + "type": "object" + }, + { + "properties": { + "sdp": { + "description": "SDP offer generated by a WebRTC RTCPeerConnection after configuring audio and the realtime events data channel.", + "type": "string" + }, + "type": { + "enum": [ + "webrtc" + ], + "title": "WebrtcThreadRealtimeStartTransportType", + "type": "string" + } + }, + "required": [ + "sdp", + "type" + ], + "title": "WebrtcThreadRealtimeStartTransport", + "type": "object" + }, + { + "properties": { + "callId": { + "description": "Identifier of a realtime call already created and negotiated by the client.", + "type": "string" + }, + "type": { + "enum": [ + "existingCall" + ], + "title": "ExistingCallThreadRealtimeStartTransportType", + "type": "string" + } + }, + "required": [ + "callId", + "type" + ], + "title": "ExistingCallThreadRealtimeStartTransport", + "type": "object" + } + ] + }, + "ThreadRealtimeStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - emitted when thread realtime startup is accepted.", + "properties": { + "realtimeSessionId": { + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + }, + "version": { + "$ref": "#/definitions/v2/RealtimeConversationVersion" + } + }, + "required": [ + "threadId", + "version" + ], + "title": "ThreadRealtimeStartedNotification", + "type": "object" + }, + "ThreadRealtimeTranscriptDeltaNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - flat transcript delta emitted whenever realtime transcript text changes.", + "properties": { + "delta": { + "description": "Live transcript delta from the realtime event.", + "type": "string" + }, + "role": { + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "delta", + "role", + "threadId" + ], + "title": "ThreadRealtimeTranscriptDeltaNotification", + "type": "object" + }, + "ThreadRealtimeTranscriptDoneNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "EXPERIMENTAL - final transcript text emitted when realtime completes a transcript part.", + "properties": { + "role": { + "type": "string" + }, + "text": { + "description": "Final complete text for the transcript part.", + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "role", + "text", + "threadId" + ], + "title": "ThreadRealtimeTranscriptDoneNotification", + "type": "object" + }, + "ThreadRealtimeTranscriptRole": { + "enum": [ + "user", + "assistant" + ], + "type": "string" + }, + "ThreadResumeInitialTurnsPageParams": { + "properties": { + "itemsView": { + "anyOf": [ + { + "$ref": "#/definitions/v2/TurnItemsView" + }, + { + "type": "null" + } + ], + "description": "How much item detail to include for each returned turn; defaults to summary." + }, + "limit": { + "description": "Optional turn page size.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "sortDirection": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SortDirection" + }, + { + "type": "null" + } + ], + "description": "Optional turn pagination direction; defaults to descending." + } + }, + "type": "object" + }, + "ThreadResumeParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "There are three ways to resume a thread: 1. By thread_id: load the thread from disk by thread_id and resume it. 2. By history: instantiate the thread from memory and resume it. 3. By path: load the thread from disk by path and resume it.\n\nFor non-running threads, the precedence is: history > non-empty path > thread_id. If using history or a non-empty path for a non-running thread, the thread_id param will be ignored.\n\nIf thread_id identifies a running thread, app-server rejoins that thread and treats a non-empty path as a consistency check against the active rollout path. Empty string path values are treated as absent.\n\nPrefer using thread_id whenever possible.", + "properties": { + "approvalPolicy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AskForApproval" + }, + { + "type": "null" + } + ] + }, + "approvalsReviewer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + { + "type": "null" + } + ], + "description": "Override where approval requests are routed for review on this thread and subsequent turns." + }, + "baseInstructions": { + "type": [ + "string", + "null" + ] + }, + "config": { + "additionalProperties": true, + "type": [ + "object", + "null" + ] + }, + "cwd": { + "type": [ + "string", + "null" + ] + }, + "developerInstructions": { + "type": [ + "string", + "null" + ] + }, + "excludeTurns": { + "description": "When true, return only thread metadata and live-resume state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after resuming. Full-history hydration is deprecated for paginated threads; use this with `thread/turns/list` and `thread/items/list` instead.", + "type": "boolean" + }, + "model": { + "description": "Configuration overrides for the resumed thread, if any.", + "type": [ + "string", + "null" + ] + }, + "modelProvider": { + "type": [ + "string", + "null" + ] + }, + "personality": { + "anyOf": [ + { + "$ref": "#/definitions/v2/Personality" + }, + { + "type": "null" + } + ], + "description": "@deprecated `friendly` and `pragmatic` no longer select a style. Changing this does not rewrite the thread's existing instructions." + }, + "sandbox": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SandboxMode" + }, + { + "type": "null" + } + ] + }, + "serviceTier": { + "type": [ + "string", + "null" + ] + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadResumeParams", + "type": "object" + }, + "ThreadResumeResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "approvalPolicy": { + "$ref": "#/definitions/v2/AskForApproval" + }, + "approvalsReviewer": { + "allOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + } + ], + "description": "Reviewer currently used for approval requests on this thread." + }, + "collaborationMode": { + "anyOf": [ + { + "$ref": "#/definitions/v2/CollaborationMode" + }, + { + "type": "null" + } + ], + "description": "Effective collaboration mode. Absent when resuming from an older server." + }, + "cwd": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "disabledPluginIds": { + "default": [], + "description": "Saved list of disabled plugin IDs. Does not yet filter plugin capabilities.", + "items": { + "type": "string" + }, + "type": "array" + }, + "instructionSources": { + "default": [], + "description": "Environment-native paths to instruction source files currently loaded for this thread.", + "items": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": "array" + }, + "itemsBackwardsCursor": { + "default": null, + "description": "Opaque cursor for hydrating paginated items backwards.\n\nPass this as `cursor` to `thread/items/list` with `sortDirection: \"desc\"`. The first page includes the item identified by the cursor.", + "type": [ + "string", + "null" + ] + }, + "model": { + "type": "string" + }, + "modelProvider": { + "type": "string" + }, + "reasoningEffort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ] + }, + "sandbox": { + "allOf": [ + { + "$ref": "#/definitions/v2/SandboxPolicy" + } + ], + "description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance." + }, + "serviceTier": { + "type": [ + "string", + "null" + ] + }, + "thread": { + "$ref": "#/definitions/v2/Thread" + }, + "turnsBackwardsCursor": { + "default": null, + "description": "Opaque cursor for hydrating paginated turns backwards.\n\nPass this as `cursor` to `thread/turns/list` with `sortDirection: \"desc\"`. The first page includes the turn identified by the cursor.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "approvalPolicy", + "approvalsReviewer", + "cwd", + "model", + "modelProvider", + "sandbox", + "thread" + ], + "title": "ThreadResumeResponse", + "type": "object" + }, + "ThreadRevertParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Replace a paginated thread's durable history with the prefix before one turn.\n\nThis only changes persisted conversation history. It does not revert local file changes.", + "properties": { + "beforeTurnId": { + "description": "Turn excluded from the replacement history, together with every later turn.", + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "beforeTurnId", + "threadId" + ], + "title": "ThreadRevertParams", + "type": "object" + }, + "ThreadRevertResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "itemsBackwardsCursor": { + "description": "Opaque cursor for hydrating paginated items backwards.\n\nPass this as `cursor` to `thread/items/list` with `sortDirection: \"desc\"`. The first page includes the item identified by the cursor.", + "type": [ + "string", + "null" + ] + }, + "thread": { + "allOf": [ + { + "$ref": "#/definitions/v2/Thread" + } + ], + "description": "Updated loaded thread metadata. `turns` is always empty; hydrate retained history through `thread/turns/list`." + }, + "turnsBackwardsCursor": { + "description": "Opaque cursor for hydrating paginated turns backwards.\n\nPass this as `cursor` to `thread/turns/list` with `sortDirection: \"desc\"`. The first page includes the turn identified by the cursor.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "thread" + ], + "title": "ThreadRevertResponse", + "type": "object" + }, + "ThreadRevertedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadRevertedNotification", + "type": "object" + }, + "ThreadSearchResult": { + "properties": { + "snippet": { + "type": "string" + }, + "thread": { + "$ref": "#/definitions/v2/Thread" + } + }, + "required": [ + "snippet", + "thread" + ], + "type": "object" + }, + "ThreadSearchSortKey": { + "enum": [ + "created_at", + "updated_at", + "recency_at" + ], + "type": "string" + }, + "ThreadSection": { + "description": "An independently persisted, user-visible thread section.", + "properties": { + "appearance": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadSectionAppearance" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Optional appearance synchronized across clients." + }, + "id": { + "description": "Opaque UUIDv7 identity that remains stable when the section is renamed.", + "type": "string" + }, + "name": { + "description": "The current user-visible section name.", + "type": "string" + } + }, + "required": [ + "id", + "name" + ], + "type": "object" + }, + "ThreadSectionAppearance": { + "description": "Extensible visual presentation for a custom thread section.", + "properties": { + "color": { + "type": [ + "string", + "null" + ] + }, + "icon": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "ThreadSectionCreateParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Parameters for creating an independently persisted thread section.", + "properties": { + "appearance": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadSectionAppearance" + }, + { + "type": "null" + } + ], + "default": null + }, + "name": { + "description": "The user-visible name of the section.", + "type": "string" + } + }, + "required": [ + "name" + ], + "title": "ThreadSectionCreateParams", + "type": "object" + }, + "ThreadSectionCreateResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "The independently persisted section created by the server.", + "properties": { + "section": { + "$ref": "#/definitions/v2/ThreadSection" + } + }, + "required": [ + "section" + ], + "title": "ThreadSectionCreateResponse", + "type": "object" + }, + "ThreadSectionDeleteParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Parameters for deleting an independently persisted thread section.", + "properties": { + "sectionId": { + "description": "The stable, server-generated identity of the section to delete.", + "type": "string" + } + }, + "required": [ + "sectionId" + ], + "title": "ThreadSectionDeleteParams", + "type": "object" + }, + "ThreadSectionDeleteResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Successful deletion does not return additional section data.", + "title": "ThreadSectionDeleteResponse", + "type": "object" + }, + "ThreadSectionListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Parameters for listing independently persisted thread sections.", + "properties": { + "cursor": { + "description": "Opaque pagination cursor returned by a previous call.", + "type": [ + "string", + "null" + ] + }, + "limit": { + "description": "Maximum number of sections to return.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + } + }, + "title": "ThreadSectionListParams", + "type": "object" + }, + "ThreadSectionListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "One page of independently persisted thread sections.", + "properties": { + "data": { + "items": { + "$ref": "#/definitions/v2/ThreadSection" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor for the next page, or `null` when no sections remain.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ThreadSectionListResponse", + "type": "object" + }, + "ThreadSectionMoveParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Parameters for moving a thread within a server-owned section ordering.", + "properties": { + "beforeThreadId": { + "description": "Existing thread to insert before; omission or null appends to the section.", + "type": [ + "string", + "null" + ] + }, + "sectionId": { + "description": "Destination section, or `null` to remove the thread from its section.", + "type": [ + "string", + "null" + ] + }, + "threadId": { + "description": "Thread to move into, within, or out of a section.", + "type": "string" + } + }, + "required": [ + "sectionId", + "threadId" + ], + "title": "ThreadSectionMoveParams", + "type": "object" + }, + "ThreadSectionMoveResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThreadSectionMoveResponse", + "type": "object" + }, + "ThreadSectionUpdateParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Parameters for updating an independently persisted thread section.", + "properties": { + "appearance": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadSectionAppearance" + }, + { + "type": "null" + } + ], + "description": "Omit to preserve appearance, use `null` to clear it, or provide a replacement." + }, + "name": { + "description": "The updated user-visible name of the section.", + "type": "string" + }, + "sectionId": { + "description": "The stable, server-generated identity of the section to update.", + "type": "string" + } + }, + "required": [ + "name", + "sectionId" + ], + "title": "ThreadSectionUpdateParams", + "type": "object" + }, + "ThreadSectionUpdateResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "The independently persisted section after its name is updated.", + "properties": { + "section": { + "$ref": "#/definitions/v2/ThreadSection" + } + }, + "required": [ + "section" + ], + "title": "ThreadSectionUpdateResponse", + "type": "object" + }, + "ThreadSetNameParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "name": { + "type": "string" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "name", + "threadId" + ], + "title": "ThreadSetNameParams", + "type": "object" + }, + "ThreadSetNameResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThreadSetNameResponse", + "type": "object" + }, + "ThreadSettings": { + "properties": { + "activePermissionProfile": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ActivePermissionProfile" + }, + { + "type": "null" + } + ] + }, + "approvalPolicy": { + "$ref": "#/definitions/v2/AskForApproval" + }, + "approvalsReviewer": { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + "collaborationMode": { + "$ref": "#/definitions/v2/CollaborationMode" + }, + "cwd": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "disabledPluginIds": { + "default": [], + "description": "Saved list of disabled plugin IDs. Does not yet filter plugin capabilities.", + "items": { + "type": "string" + }, + "type": "array" + }, + "effort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ] + }, + "model": { + "type": "string" + }, + "modelProvider": { + "type": "string" + }, + "personality": { + "anyOf": [ + { + "$ref": "#/definitions/v2/Personality" + }, + { + "type": "null" + } + ], + "description": "@deprecated Reports the saved setting; `friendly` and `pragmatic` no longer select a style." + }, + "sandboxPolicy": { + "$ref": "#/definitions/v2/SandboxPolicy" + }, + "serviceTier": { + "type": [ + "string", + "null" + ] + }, + "summary": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningSummary" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "approvalPolicy", + "approvalsReviewer", + "collaborationMode", + "cwd", + "model", + "modelProvider", + "sandboxPolicy" + ], + "type": "object" + }, + "ThreadSettingsUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + }, + "threadSettings": { + "$ref": "#/definitions/v2/ThreadSettings" + } + }, + "required": [ + "threadId", + "threadSettings" + ], + "title": "ThreadSettingsUpdatedNotification", + "type": "object" + }, + "ThreadShellCommandParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "command": { + "description": "Shell command string evaluated by the thread's configured shell. Unlike `command/exec`, this intentionally preserves shell syntax such as pipes, redirects, and quoting. This runs unsandboxed with full access rather than inheriting the thread sandbox policy.", + "type": "string" + }, + "threadId": { + "type": "string" + }, + "timeoutMs": { + "description": "Maximum execution time in milliseconds. Defaults to one hour when omitted or null. Must be non-negative; zero requests an immediate timeout, not unlimited execution. Does not affect the immediate RPC acknowledgement.", + "format": "int64", + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "command", + "threadId" + ], + "title": "ThreadShellCommandParams", + "type": "object" + }, + "ThreadShellCommandResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ThreadShellCommandResponse", + "type": "object" + }, + "ThreadSortKey": { + "enum": [ + "created_at", + "updated_at", + "recency_at", + "section_position" + ], + "type": "string" + }, + "ThreadSource": { + "type": "string" + }, + "ThreadSourceKind": { + "enum": [ + "cli", + "vscode", + "exec", + "appServer", + "subAgent", + "subAgentReview", + "subAgentCompact", + "subAgentThreadSpawn", + "subAgentOther", + "unknown" + ], + "type": "string" + }, + "ThreadStartParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "approvalPolicy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AskForApproval" + }, + { + "type": "null" + } + ] + }, + "approvalsReviewer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + { + "type": "null" + } + ], + "description": "Override where approval requests are routed for review on this thread and subsequent turns." + }, + "baseInstructions": { + "type": [ + "string", + "null" + ] + }, + "config": { + "additionalProperties": true, + "type": [ + "object", + "null" + ] + }, + "cwd": { + "type": [ + "string", + "null" + ] + }, + "developerInstructions": { + "type": [ + "string", + "null" + ] + }, + "ephemeral": { + "type": [ + "boolean", + "null" + ] + }, + "model": { + "type": [ + "string", + "null" + ] + }, + "modelProvider": { + "type": [ + "string", + "null" + ] + }, + "personality": { + "anyOf": [ + { + "$ref": "#/definitions/v2/Personality" + }, + { + "type": "null" + } + ], + "description": "@deprecated `friendly` and `pragmatic` no longer select a style." + }, + "sandbox": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SandboxMode" + }, + { + "type": "null" + } + ] + }, + "serviceName": { + "type": [ + "string", + "null" + ] + }, + "serviceTier": { + "type": [ + "string", + "null" + ] + }, + "sessionStartSource": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadStartSource" + }, + { + "type": "null" + } + ] + }, + "threadSource": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ThreadSource" + }, + { + "type": "null" + } + ], + "description": "Optional client-supplied analytics source classification for this thread." + } + }, + "title": "ThreadStartParams", + "type": "object" + }, + "ThreadStartResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "approvalPolicy": { + "$ref": "#/definitions/v2/AskForApproval" + }, + "approvalsReviewer": { + "allOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + } + ], + "description": "Reviewer currently used for approval requests on this thread." + }, + "cwd": { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + "disabledPluginIds": { + "default": [], + "description": "Saved list of disabled plugin IDs. Does not yet filter plugin capabilities.", + "items": { + "type": "string" + }, + "type": "array" + }, + "instructionSources": { + "default": [], + "description": "Environment-native paths to instruction source files currently loaded for this thread.", + "items": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": "array" + }, + "model": { + "type": "string" + }, + "modelProvider": { + "type": "string" + }, + "reasoningEffort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ] + }, + "sandbox": { + "allOf": [ + { + "$ref": "#/definitions/v2/SandboxPolicy" + } + ], + "description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance." + }, + "serviceTier": { + "type": [ + "string", + "null" + ] + }, + "thread": { + "$ref": "#/definitions/v2/Thread" + } + }, + "required": [ + "approvalPolicy", + "approvalsReviewer", + "cwd", + "model", + "modelProvider", + "sandbox", + "thread" + ], + "title": "ThreadStartResponse", + "type": "object" + }, + "ThreadStartSource": { + "enum": [ + "startup", + "clear" + ], + "type": "string" + }, + "ThreadStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "thread": { + "$ref": "#/definitions/v2/Thread" + } + }, + "required": [ + "thread" + ], + "title": "ThreadStartedNotification", + "type": "object" + }, + "ThreadStatus": { + "oneOf": [ + { + "properties": { + "type": { + "enum": [ + "notLoaded" + ], + "title": "NotLoadedThreadStatusType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "NotLoadedThreadStatus", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "idle" + ], + "title": "IdleThreadStatusType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "IdleThreadStatus", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "systemError" + ], + "title": "SystemErrorThreadStatusType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "SystemErrorThreadStatus", + "type": "object" + }, + { + "properties": { + "activeFlags": { + "items": { + "$ref": "#/definitions/v2/ThreadActiveFlag" + }, + "type": "array" + }, + "type": { + "enum": [ + "active" + ], + "title": "ActiveThreadStatusType", + "type": "string" + } + }, + "required": [ + "activeFlags", + "type" + ], + "title": "ActiveThreadStatus", + "type": "object" + } + ] + }, + "ThreadStatusChangedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "status": { + "$ref": "#/definitions/v2/ThreadStatus" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "status", + "threadId" + ], + "title": "ThreadStatusChangedNotification", + "type": "object" + }, + "ThreadTimelineEntry": { + "description": "EXPERIMENTAL - one item or turn boundary in canonical rollout order.", + "oneOf": [ + { + "properties": { + "item": { + "$ref": "#/definitions/v2/ThreadItem" + }, + "position": { + "format": "uint64", + "minimum": 0.0, + "type": "integer" + }, + "turnId": { + "type": "string" + }, + "type": { + "enum": [ + "item" + ], + "title": "ItemThreadTimelineEntryType", + "type": "string" + } + }, + "required": [ + "item", + "position", + "turnId", + "type" + ], + "title": "ItemThreadTimelineEntry", + "type": "object" + }, + { + "properties": { + "item": { + "$ref": "#/definitions/v2/ThreadRealtimeItem" + }, + "position": { + "format": "uint64", + "minimum": 0.0, + "type": "integer" + }, + "type": { + "enum": [ + "realtime" + ], + "title": "RealtimeThreadTimelineEntryType", + "type": "string" + } + }, + "required": [ + "item", + "position", + "type" + ], + "title": "RealtimeThreadTimelineEntry", + "type": "object" + }, + { + "properties": { + "position": { + "format": "uint64", + "minimum": 0.0, + "type": "integer" + }, + "started_at": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "turn_id": { + "type": "string" + }, + "type": { + "enum": [ + "turnStarted" + ], + "title": "TurnStartedThreadTimelineEntryType", + "type": "string" + } + }, + "required": [ + "position", + "turn_id", + "type" + ], + "title": "TurnStartedThreadTimelineEntry", + "type": "object" + }, + { + "properties": { + "completed_at": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "duration_ms": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "error": { + "anyOf": [ + { + "$ref": "#/definitions/v2/TurnError" + }, + { + "type": "null" + } + ] + }, + "position": { + "format": "uint64", + "minimum": 0.0, + "type": "integer" + }, + "started_at": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "status": { + "$ref": "#/definitions/v2/TurnStatus" + }, + "turn_id": { + "type": "string" + }, + "type": { + "enum": [ + "turnCompleted" + ], + "title": "TurnCompletedThreadTimelineEntryType", + "type": "string" + } + }, + "required": [ + "position", + "status", + "turn_id", + "type" + ], + "title": "TurnCompletedThreadTimelineEntry", + "type": "object" + } + ] + }, + "ThreadTokenUsage": { + "properties": { + "last": { + "$ref": "#/definitions/v2/TokenUsageBreakdown" + }, + "modelContextWindow": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "total": { + "$ref": "#/definitions/v2/TokenUsageBreakdown" + } + }, + "required": [ + "last", + "total" + ], + "type": "object" + }, + "ThreadTokenUsageUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + }, + "tokenUsage": { + "$ref": "#/definitions/v2/ThreadTokenUsage" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "threadId", + "tokenUsage", + "turnId" + ], + "title": "ThreadTokenUsageUpdatedNotification", + "type": "object" + }, + "ThreadTurnsListParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cursor": { + "description": "Opaque cursor to pass to the next call to continue after the last turn.", + "type": [ + "string", + "null" + ] + }, + "itemsView": { + "anyOf": [ + { + "$ref": "#/definitions/v2/TurnItemsView" + }, + { + "type": "null" + } + ], + "description": "How much item detail to include for each returned turn; defaults to summary." + }, + "limit": { + "description": "Optional turn page size.", + "format": "uint32", + "minimum": 0.0, + "type": [ + "integer", + "null" + ] + }, + "sortDirection": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SortDirection" + }, + { + "type": "null" + } + ], + "description": "Optional turn pagination direction; defaults to descending." + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadTurnsListParams", + "type": "object" + }, + "ThreadTurnsListResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "backwardsCursor": { + "description": "Opaque cursor to pass as `cursor` when reversing `sortDirection`. This is only populated when the page contains at least one turn. Use it with the opposite `sortDirection` to include the anchor turn again and catch updates to that turn.", + "type": [ + "string", + "null" + ] + }, + "data": { + "items": { + "$ref": "#/definitions/v2/Turn" + }, + "type": "array" + }, + "nextCursor": { + "description": "Opaque cursor to pass to the next call to continue after the last turn. if None, there are no more turns to return.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "title": "ThreadTurnsListResponse", + "type": "object" + }, + "ThreadUnarchiveParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadUnarchiveParams", + "type": "object" + }, + "ThreadUnarchiveResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "thread": { + "$ref": "#/definitions/v2/Thread" + } + }, + "required": [ + "thread" + ], + "title": "ThreadUnarchiveResponse", + "type": "object" + }, + "ThreadUnarchivedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadUnarchivedNotification", + "type": "object" + }, + "ThreadUnsubscribeParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + } + }, + "required": [ + "threadId" + ], + "title": "ThreadUnsubscribeParams", + "type": "object" + }, + "ThreadUnsubscribeResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "status": { + "$ref": "#/definitions/v2/ThreadUnsubscribeStatus" + } + }, + "required": [ + "status" + ], + "title": "ThreadUnsubscribeResponse", + "type": "object" + }, + "ThreadUnsubscribeStatus": { + "enum": [ + "notLoaded", + "notSubscribed", + "unsubscribed" + ], + "type": "string" + }, + "ThreadUsage": { + "properties": { + "estimatedUsageCreditsMicros": { + "format": "int64", + "type": "integer" + }, + "estimatedUsageUsdMicros": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "groups": { + "items": { + "$ref": "#/definitions/v2/ThreadUsageBreakdownGroup" + }, + "type": "array" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "estimatedUsageCreditsMicros", + "groups", + "threadId" + ], + "type": "object" + }, + "ThreadUsageBreakdownGroup": { + "properties": { + "cachedInputTokens": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "estimatedUsageCreditsMicros": { + "format": "int64", + "type": "integer" + }, + "inputTokens": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "model": { + "type": [ + "string", + "null" + ] + }, + "netNewInputTokens": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "outputTokens": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "reasoningEffort": { + "type": [ + "string", + "null" + ] + }, + "speed": { + "type": [ + "string", + "null" + ] + }, + "totalTokens": { + "format": "int64", + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "estimatedUsageCreditsMicros" + ], + "type": "object" + }, + "TokenUsageBreakdown": { + "properties": { + "cacheWriteInputTokens": { + "default": 0, + "format": "int64", + "type": "integer" + }, + "cachedInputTokens": { + "format": "int64", + "type": "integer" + }, + "inputTokens": { + "format": "int64", + "type": "integer" + }, + "outputTokens": { + "format": "int64", + "type": "integer" + }, + "reasoningOutputTokens": { + "format": "int64", + "type": "integer" + }, + "totalTokens": { + "format": "int64", + "type": "integer" + } + }, + "required": [ + "cachedInputTokens", + "inputTokens", + "outputTokens", + "reasoningOutputTokens", + "totalTokens" + ], + "type": "object" + }, + "Tool": { + "description": "Definition for a tool the client can call.", + "properties": { + "_meta": true, + "annotations": true, + "description": { + "type": [ + "string", + "null" + ] + }, + "icons": { + "items": true, + "type": [ + "array", + "null" + ] + }, + "inputSchema": true, + "name": { + "type": "string" + }, + "outputSchema": true, + "title": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "inputSchema", + "name" + ], + "type": "object" + }, + "ToolExposureSurface": { + "description": "A model-facing surface on which a tool can be exposed.", + "oneOf": [ + { + "description": "Nested tools available to Code Mode scripts.", + "enum": [ + "code_mode" + ], + "type": "string" + }, + { + "description": "Tools discovered later through tool search.", + "enum": [ + "deferred" + ], + "type": "string" + }, + { + "description": "Tools present in the model's initial tool list.", + "enum": [ + "direct" + ], + "type": "string" + } + ] + }, + "ToolsV2": { + "properties": { + "web_search": { + "anyOf": [ + { + "$ref": "#/definitions/v2/WebSearchToolConfig" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "Turn": { + "properties": { + "completedAt": { + "description": "Unix timestamp (in seconds) when the turn completed.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "durationMs": { + "description": "Duration between turn start and completion in milliseconds, if known.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "error": { + "anyOf": [ + { + "$ref": "#/definitions/v2/TurnError" + }, + { + "type": "null" + } + ], + "description": "Only populated when the Turn's status is failed." + }, + "id": { + "description": "Identifier for this turn. Codex-generated turn IDs are UUIDv7.", + "type": "string" + }, + "items": { + "description": "Thread items currently included in this turn payload.", + "items": { + "$ref": "#/definitions/v2/ThreadItem" + }, + "type": "array" + }, + "itemsView": { + "allOf": [ + { + "$ref": "#/definitions/v2/TurnItemsView" + } + ], + "default": "full", + "description": "Describes how much of `items` has been loaded for this turn." + }, + "startedAt": { + "description": "Unix timestamp (in seconds) when the turn started.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "status": { + "$ref": "#/definitions/v2/TurnStatus" + } + }, + "required": [ + "id", + "items", + "status" + ], + "type": "object" + }, + "TurnCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + }, + "turn": { + "$ref": "#/definitions/v2/Turn" + } + }, + "required": [ + "threadId", + "turn" + ], + "title": "TurnCompletedNotification", + "type": "object" + }, + "TurnDiffUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Notification that the turn-level unified diff has changed. Contains the latest aggregated diff across all file changes in the turn.", + "properties": { + "diff": { + "type": "string" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "diff", + "threadId", + "turnId" + ], + "title": "TurnDiffUpdatedNotification", + "type": "object" + }, + "TurnEnvironmentParams": { + "properties": { + "cwd": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "environmentId": { + "type": "string" + }, + "runtimeWorkspaceRoots": { + "description": "Environment-native runtime workspace roots. Omitted defaults to `cwd`.", + "items": { + "$ref": "#/definitions/v2/LegacyAppPathString" + }, + "type": [ + "array", + "null" + ] + } + }, + "required": [ + "cwd", + "environmentId" + ], + "type": "object" + }, + "TurnError": { + "properties": { + "additionalDetails": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "codexErrorInfo": { + "anyOf": [ + { + "$ref": "#/definitions/v2/CodexErrorInfo" + }, + { + "type": "null" + } + ] + }, + "message": { + "type": "string" + }, + "misalignment": { + "anyOf": [ + { + "$ref": "#/definitions/v2/MisalignmentErrorDetails" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Optional public explanation and continuation instruction for a misalignment block." + } + }, + "required": [ + "message" + ], + "type": "object" + }, + "TurnInterruptParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "threadId", + "turnId" + ], + "title": "TurnInterruptParams", + "type": "object" + }, + "TurnInterruptResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TurnInterruptResponse", + "type": "object" + }, + "TurnItemsView": { + "oneOf": [ + { + "description": "`items` was not loaded for this turn. The field is intentionally empty.", + "enum": [ + "notLoaded" + ], + "type": "string" + }, + { + "description": "`items` contains only a display summary for this turn.", + "enum": [ + "summary" + ], + "type": "string" + }, + { + "description": "`items` contains every ThreadItem available from persisted app-server history for this turn.", + "enum": [ + "full" + ], + "type": "string" + } + ] + }, + "TurnModerationMetadataNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "metadata": true, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "metadata", + "threadId", + "turnId" + ], + "title": "TurnModerationMetadataNotification", + "type": "object" + }, + "TurnPlanStep": { + "properties": { + "status": { + "$ref": "#/definitions/v2/TurnPlanStepStatus" + }, + "step": { + "type": "string" + } + }, + "required": [ + "status", + "step" + ], + "type": "object" + }, + "TurnPlanStepStatus": { + "enum": [ + "pending", + "inProgress", + "completed" + ], + "type": "string" + }, + "TurnPlanUpdatedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "explanation": { + "type": [ + "string", + "null" + ] + }, + "plan": { + "items": { + "$ref": "#/definitions/v2/TurnPlanStep" + }, + "type": "array" + }, + "threadId": { + "type": "string" + }, + "turnId": { + "type": "string" + } + }, + "required": [ + "plan", + "threadId", + "turnId" + ], + "title": "TurnPlanUpdatedNotification", + "type": "object" + }, + "TurnStartParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "approvalPolicy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AskForApproval" + }, + { + "type": "null" + } + ], + "description": "Override the approval policy for this turn and subsequent turns." + }, + "approvalsReviewer": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ApprovalsReviewer" + }, + { + "type": "null" + } + ], + "description": "Override where approval requests are routed for review on this turn and subsequent turns." + }, + "clientUserMessageId": { + "type": [ + "string", + "null" + ] + }, + "cwd": { + "description": "Override the working directory for this turn and subsequent turns.", + "type": [ + "string", + "null" + ] + }, + "disabledPluginIds": { + "description": "Replace this thread's disabled plugin IDs. Omitted/null preserves the list; [] clears it.", + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "effort": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningEffort" + }, + { + "type": "null" + } + ], + "description": "Override the reasoning effort for this turn and subsequent turns." + }, + "input": { + "items": { + "$ref": "#/definitions/v2/UserInput" + }, + "type": "array" + }, + "model": { + "description": "Override the model for this turn and subsequent turns.", + "type": [ + "string", + "null" + ] + }, + "outputSchema": { + "description": "Optional JSON Schema used to constrain the final assistant message for this turn." + }, + "personality": { + "anyOf": [ + { + "$ref": "#/definitions/v2/Personality" + }, + { + "type": "null" + } + ], + "description": "@deprecated `friendly` and `pragmatic` no longer select a style. Changing this does not rewrite the thread's existing instructions." + }, + "sandboxPolicy": { + "anyOf": [ + { + "$ref": "#/definitions/v2/SandboxPolicy" + }, + { + "type": "null" + } + ], + "description": "Override the sandbox policy for this turn and subsequent turns." + }, + "serviceTier": { + "description": "Override the service tier for this turn and subsequent turns.", + "type": [ + "string", + "null" + ] + }, + "serviceTierForTurn": { + "description": "Override the service tier only when this request starts a new turn. Use \"default\" for standard speed. Omitted or null inherits the thread's tier. Does not change the thread's tier or a turn being steered.", + "type": [ + "string", + "null" + ] + }, + "summary": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ReasoningSummary" + }, + { + "type": "null" + } + ], + "description": "Override the reasoning summary for this turn and subsequent turns." + }, + "threadId": { + "type": "string" + }, + "toolOutput": { + "anyOf": [ + { + "$ref": "#/definitions/v2/TurnToolOutput" + }, + { + "type": "null" + } + ] + }, + "turnTrigger": { + "description": "Optional source classification for the caller that starts this turn. Ignored when this request steers an already-active turn.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "input", + "threadId" + ], + "title": "TurnStartParams", + "type": "object" + }, + "TurnStartResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "turn": { + "$ref": "#/definitions/v2/Turn" + } + }, + "required": [ + "turn" + ], + "title": "TurnStartResponse", + "type": "object" + }, + "TurnStartedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "threadId": { + "type": "string" + }, + "turn": { + "$ref": "#/definitions/v2/Turn" + } + }, + "required": [ + "threadId", + "turn" + ], + "title": "TurnStartedNotification", + "type": "object" + }, + "TurnStatus": { + "enum": [ + "completed", + "interrupted", + "failed", + "inProgress" + ], + "type": "string" + }, + "TurnSteerParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "clientUserMessageId": { + "type": [ + "string", + "null" + ] + }, + "expectedTurnId": { + "description": "Required active turn id precondition. The request fails when it does not match the currently active turn.", + "type": "string" + }, + "input": { + "items": { + "$ref": "#/definitions/v2/UserInput" + }, + "type": "array" + }, + "threadId": { + "type": "string" + } + }, + "required": [ + "expectedTurnId", + "input", + "threadId" + ], + "title": "TurnSteerParams", + "type": "object" + }, + "TurnSteerResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "turnId": { + "type": "string" + } + }, + "required": [ + "turnId" + ], + "title": "TurnSteerResponse", + "type": "object" + }, + "TurnToolOutput": { + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": [ + "string", + "null" + ] + }, + "output": { + "$ref": "#/definitions/v2/FunctionCallOutputBody" + } + }, + "required": [ + "name", + "output" + ], + "type": "object" + }, + "TurnsPage": { + "properties": { + "backwardsCursor": { + "type": [ + "string", + "null" + ] + }, + "data": { + "items": { + "$ref": "#/definitions/v2/Turn" + }, + "type": "array" + }, + "nextCursor": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "data" + ], + "type": "object" + }, + "UserInput": { + "oneOf": [ + { + "properties": { + "text": { + "type": "string" + }, + "text_elements": { + "default": [], + "description": "UI-defined spans within `text` used to render or persist special elements.", + "items": { + "$ref": "#/definitions/v2/TextElement" + }, + "type": "array" + }, + "type": { + "enum": [ + "text" + ], + "title": "TextUserInputType", + "type": "string" + } + }, + "required": [ + "text", + "type" + ], + "title": "TextUserInput", + "type": "object" + }, + { + "anyOf": [ + { + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ], + "title": "UrlUserInput", + "type": "object" + }, + { + "properties": { + "fileId": { + "type": "string" + } + }, + "required": [ + "fileId" + ], + "title": "FileIdUserInput", + "type": "object" + } + ], + "properties": { + "detail": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ImageDetail" + }, + { + "type": "null" + } + ], + "default": null + }, + "type": { + "enum": [ + "image" + ], + "title": "ImageUserInputType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "ImageUserInput", + "type": "object" + }, + { + "properties": { + "detail": { + "anyOf": [ + { + "$ref": "#/definitions/v2/ImageDetail" + }, + { + "type": "null" + } + ], + "default": null + }, + "path": { + "type": "string" + }, + "type": { + "enum": [ + "localImage" + ], + "title": "LocalImageUserInputType", + "type": "string" + } + }, + "required": [ + "path", + "type" + ], + "title": "LocalImageUserInput", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "audio" + ], + "title": "AudioUserInputType", + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "type", + "url" + ], + "title": "AudioUserInput", + "type": "object" + }, + { + "properties": { + "path": { + "type": "string" + }, + "type": { + "enum": [ + "localAudio" + ], + "title": "LocalAudioUserInputType", + "type": "string" + } + }, + "required": [ + "path", + "type" + ], + "title": "LocalAudioUserInput", + "type": "object" + }, + { + "properties": { + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "type": { + "enum": [ + "skill" + ], + "title": "SkillUserInputType", + "type": "string" + } + }, + "required": [ + "name", + "path", + "type" + ], + "title": "SkillUserInput", + "type": "object" + }, + { + "properties": { + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "type": { + "enum": [ + "mention" + ], + "title": "MentionUserInputType", + "type": "string" + } + }, + "required": [ + "name", + "path", + "type" + ], + "title": "MentionUserInput", + "type": "object" + } + ] + }, + "Verbosity": { + "description": "Controls output length/detail on GPT-5 models via the Responses API. Serialized with lowercase values to match the OpenAI API.", + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" + }, + "WarningNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "message": { + "description": "Concise warning message for the user.", + "type": "string" + }, + "threadId": { + "description": "Optional thread target when the warning applies to a specific thread.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "message" + ], + "title": "WarningNotification", + "type": "object" + }, + "WebSearchAction": { + "oneOf": [ + { + "properties": { + "queries": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "query": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "search" + ], + "title": "SearchWebSearchActionType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "SearchWebSearchAction", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "openPage" + ], + "title": "OpenPageWebSearchActionType", + "type": "string" + }, + "url": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "type" + ], + "title": "OpenPageWebSearchAction", + "type": "object" + }, + { + "properties": { + "pattern": { + "type": [ + "string", + "null" + ] + }, + "type": { + "enum": [ + "findInPage" + ], + "title": "FindInPageWebSearchActionType", + "type": "string" + }, + "url": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "type" + ], + "title": "FindInPageWebSearchAction", + "type": "object" + }, + { + "properties": { + "type": { + "enum": [ + "other" + ], + "title": "OtherWebSearchActionType", + "type": "string" + } + }, + "required": [ + "type" + ], + "title": "OtherWebSearchAction", + "type": "object" + } + ] + }, + "WebSearchContextSize": { + "enum": [ + "low", + "medium", + "high" + ], + "type": "string" + }, + "WebSearchLocation": { + "additionalProperties": false, + "properties": { + "city": { + "type": [ + "string", + "null" + ] + }, + "country": { + "type": [ + "string", + "null" + ] + }, + "region": { + "type": [ + "string", + "null" + ] + }, + "timezone": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "WebSearchMode": { + "enum": [ + "disabled", + "cached", + "indexed", + "live" + ], + "type": "string" + }, + "WebSearchToolConfig": { + "additionalProperties": false, + "properties": { + "allowed_domains": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "context_size": { + "anyOf": [ + { + "$ref": "#/definitions/v2/WebSearchContextSize" + }, + { + "type": "null" + } + ] + }, + "location": { + "anyOf": [ + { + "$ref": "#/definitions/v2/WebSearchLocation" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" + }, + "WindowsSandboxImplementation": { + "enum": [ + "elevated", + "unelevated", + "mxc" + ], + "type": "string" + }, + "WindowsSandboxReadiness": { + "enum": [ + "ready", + "notConfigured", + "updateRequired" + ], + "type": "string" + }, + "WindowsSandboxReadinessResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "status": { + "$ref": "#/definitions/v2/WindowsSandboxReadiness" + } + }, + "required": [ + "status" + ], + "title": "WindowsSandboxReadinessResponse", + "type": "object" + }, + "WindowsSandboxSetupCompletedNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "error": { + "type": [ + "string", + "null" + ] + }, + "mode": { + "$ref": "#/definitions/v2/WindowsSandboxSetupMode" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "mode", + "success" + ], + "title": "WindowsSandboxSetupCompletedNotification", + "type": "object" + }, + "WindowsSandboxSetupMode": { + "enum": [ + "elevated", + "unelevated" + ], + "type": "string" + }, + "WindowsSandboxSetupStartParams": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cwd": { + "anyOf": [ + { + "$ref": "#/definitions/v2/AbsolutePathBuf" + }, + { + "type": "null" + } + ] + }, + "mode": { + "$ref": "#/definitions/v2/WindowsSandboxSetupMode" + } + }, + "required": [ + "mode" + ], + "title": "WindowsSandboxSetupStartParams", + "type": "object" + }, + "WindowsSandboxSetupStartResponse": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "started": { + "type": "boolean" + } + }, + "required": [ + "started" + ], + "title": "WindowsSandboxSetupStartResponse", + "type": "object" + }, + "WindowsWorldWritableWarningNotification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "extraCount": { + "format": "uint", + "minimum": 0.0, + "type": "integer" + }, + "failedScan": { + "type": "boolean" + }, + "samplePaths": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "extraCount", + "failedScan", + "samplePaths" + ], + "title": "WindowsWorldWritableWarningNotification", + "type": "object" + }, + "WorkspaceMessage": { + "properties": { + "archivedAt": { + "description": "Unix timestamp (in seconds) when the message was archived.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "createdAt": { + "description": "Unix timestamp (in seconds) when the message was created.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "messageBody": { + "type": "string" + }, + "messageId": { + "type": "string" + }, + "messageType": { + "$ref": "#/definitions/v2/WorkspaceMessageType" + } + }, + "required": [ + "messageBody", + "messageId", + "messageType" + ], + "type": "object" + }, + "WorkspaceMessageType": { + "enum": [ + "headline", + "announcement", + "unknown" + ], + "type": "string" + }, + "WorkspaceRouting": { + "properties": { + "accountRoutingOverride": { + "$ref": "#/definitions/v2/AccountRoutingOverride" + }, + "backendOrigin": { + "type": "string" + }, + "chatgptAccountId": { + "type": "string" + } + }, + "required": [ + "accountRoutingOverride", + "backendOrigin", + "chatgptAccountId" + ], + "type": "object" + }, + "WriteStatus": { + "enum": [ + "ok", + "okOverridden" + ], + "type": "string" + } + } + }, + "title": "CodexAppServerProtocol", + "type": "object" +} \ No newline at end of file diff --git a/scripts/check-codegen b/scripts/check-codegen new file mode 100755 index 0000000..3384626 --- /dev/null +++ b/scripts/check-codegen @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# Codegen drift: regenerates the committed generated files (codexwire's +# protocol types, from the committed Codex app-server schema) and fails if +# any differs from what is committed. A failure means a generated file was +# hand-edited, reformatted or made by another generator version, or the +# schema changed without regenerating: run scripts/gen-codex-protocol and +# commit the result. +set -euo pipefail +cd "$(dirname "$0")/.." +generated=( + src/protocol.rs +) +scripts/gen-codex-protocol +if ! git diff --quiet -- "${generated[@]}"; then + git --no-pager diff --stat -- "${generated[@]}" >&2 + echo "check-codegen: generated files differ from what the Codex schema makes (the regenerated ones are now in the tree: see git diff, commit them)" >&2 + exit 1 +fi +echo "check-codegen: ok" diff --git a/scripts/gen-codex-protocol b/scripts/gen-codex-protocol new file mode 100755 index 0000000..e5e10c7 --- /dev/null +++ b/scripts/gen-codex-protocol @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Regenerate the protocol types (src/protocol.rs) from the committed +# app-server schema. Offline: the input is +# schema/{codex_app_server_protocol.schemas.json,VERSION}. +# +# `--refresh [CODEX]` first re-dumps the schema from a codex binary (default +# `codex` on PATH) and records its version: do that when bumping the pinned +# Codex, then review the diff of src/protocol.rs. +# +# `--check [CODEX]` only checks that a codex binary is the pinned version +# (schema/VERSION) and exits non-zero if not. +set -euo pipefail +cd "$(dirname "$0")/.." +pinned=$(&2 + exit 1 + fi + echo "gen-codex-protocol: codex $have matches the pin" + exit 0 + ;; + --refresh) + codex=${2:-codex} + tmp=$(mktemp -d) + trap 'rm -rf "$tmp"' EXIT + "$codex" app-server generate-json-schema --out "$tmp" >/dev/null + cp "$tmp/codex_app_server_protocol.schemas.json" schema/ + new=$(codex_version "$codex") + [[ $new == "$pinned" ]] || echo "gen-codex-protocol: pin moves $pinned -> $new" >&2 + echo "$new" >schema/VERSION + ;; + "") ;; + *) + echo "usage: $0 [--refresh [CODEX] | --check [CODEX]]" >&2 + exit 2 + ;; +esac +python3 -I scripts/gen-codex-protocol.py schema/codex_app_server_protocol.schemas.json \ + schema/VERSION src/protocol.rs +rustfmt --edition 2024 src/protocol.rs diff --git a/scripts/gen-codex-protocol.py b/scripts/gen-codex-protocol.py new file mode 100755 index 0000000..e9e12a5 --- /dev/null +++ b/scripts/gen-codex-protocol.py @@ -0,0 +1,456 @@ +#!/usr/bin/env python3 +"""Generate codexwire's protocol types from Codex's app-server JSON Schema. + +Input: the committed schema bundle (`codex app-server generate-json-schema`, +see `scripts/gen-codex-protocol`) and its VERSION file. Output: serde types +for the methods and notifications codexwire uses (ROOTS below and every +type they reach), plus `Request`/`Notification`/`ServerRequest` impls that +tie each method name to its params and response. Stdlib only, offline. + +Shapes: objects become structs (optional or nullable fields `Option`), +string enums and `oneOf`s become enums with an `Unknown(Value)` catch-all +(a newer Codex adding a variant must not break decoding), `oneOf`s tagged +by a `type` field become internally tagged enums; anything else (mixed +`anyOf`, untyped) stays `serde_json::Value`. + +The catch-all is serde's untagged fallback, so a *known* tag whose body +doesn't decode (a field missing or of another type) lands in `Unknown` +too, silently: callers that care about schema drift log `Unknown` values. +""" + +import json +import keyword +import re +import sys + +# Client requests (method -> params; response is Response). +REQUESTS = [ + "initialize", + "thread/start", + "thread/resume", + "turn/start", + "turn/interrupt", +] +# Server notifications codexwire reads. +NOTIFICATIONS = [ + "error", + "thread/started", + "turn/started", + "turn/completed", + "item/started", + "item/completed", + "item/agentMessage/delta", + "thread/tokenUsage/updated", + "account/rateLimits/updated", +] +# Server requests codexwire answers. +SERVER_REQUESTS = [ + "item/commandExecution/requestApproval", + "item/fileChange/requestApproval", + "mcpServer/elicitation/request", +] +# Kept as raw JSON: big, and codexwire never looks inside. +OPAQUE = { + "SandboxPolicy", + "GitInfo", + "ThreadStatus", + "ActivePermissionProfile", + "McpServerElicitationRequestParams", + "CollabAgentState", + "WebSearchAction", + "HookPromptFragment", + "MemoryCitation", + "AsyncUserInputQuestion", + "FunctionCallOutputBody", + "McpToolCallResult", + "DynamicToolCallOutputContentItem", + "CommandAction", + "NetworkPolicyAmendment", + "AdditionalPermissionProfile", + "TextElement", +} + +RUST_KW = set(keyword.kwlist) | { + "type", + "ref", + "match", + "move", + "mod", + "self", + "super", + "crate", + "loop", + "use", + "where", + "impl", + "trait", + "fn", + "let", + "mut", + "pub", + "static", + "struct", + "enum", + "extern", + "unsafe", + "dyn", + "abstract", + "final", + "override", + "macro", + "box", + "priv", + "typeof", + "unsized", + "virtual", + "yield", + "try", + "async", + "await", + "const", +} + + +def snake(name): + s = re.sub(r"[^0-9A-Za-z]+", "_", name).strip("_") + s = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s) + s = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", s).lower() + if not s or s[0].isdigit(): + s = "f_" + s + return f"r#{s}" if s in RUST_KW else s + + +def pascal(name): + parts = re.split(r"[^0-9A-Za-z]+", name) + s = "".join(p[:1].upper() + p[1:] for p in parts if p) + if not s or s[0].isdigit(): + s = "V" + s + return "Self_" if s == "Self" else s + + +def catch_all(out): + """Close an enum with its catch-all (`Unknown`, or `UnknownValue` when + the protocol has an `unknown` value of its own).""" + lines = "\n".join(out).splitlines() + taken = any( + ln.strip() == "Unknown," or ln.strip().startswith("Unknown(") for ln in lines + ) + v = "UnknownValue" if taken else "Unknown" + out.append( + " /// A value this Codex version doesn't know, or a known one whose" + " body didn't decode." + ) + out.append(f" #[serde(untagged)]\n {v}(Value),\n}}\n") + return "\n".join(out) + "\n" + + +class Gen: + def __init__(self, bundle): + top = bundle["definitions"] + self.defs = {k: v for k, v in top.items() if k != "v2"} + self.defs.update(top["v2"]) # v2 wins on a shared name + self.top = top + self.items = {} # name -> rust source + self.order = [] + self.defaultable = {} + self.pending = [] + + def ref(self, r): + name = r.split("/")[-1] + if name not in self.items and name not in self.pending: + self.pending.append(name) + return name + + def drain(self): + while self.pending: + name = self.pending.pop(0) + if name in self.items: + continue + self.items[name] = None # reserve (cycles) + self.order.append(name) + if name in OPAQUE: + self.items[name] = f"pub type {name} = Value;\n" + self.defaultable[name] = True + else: + self.items[name] = self.define(name, self.defs[name]) + + # A rust type for a schema used in a field (inline objects are named + # after `hint`). + def ty(self, s, hint): + if s is True or s == {}: + return "Value" + if "$ref" in s: + return self.ref(s["$ref"]) + for k in ("anyOf", "oneOf"): + if k in s and "properties" not in s: + alts = s[k] + non_null = [a for a in alts if a.get("type") != "null"] + if len(non_null) == 1 and len(non_null) < len(alts): + return f"Option<{self.ty(non_null[0], hint)}>" + if k == "oneOf" or all("$ref" not in a for a in alts): + return self.inline(s, hint) + return "Value" + if "allOf" in s and len(s["allOf"]) == 1: + return self.ty(s["allOf"][0], hint) + t = s.get("type") + if isinstance(t, list): + rest = [x for x in t if x != "null"] + inner = dict(s, type=rest[0]) if len(rest) == 1 else {} + base = self.ty(inner, hint) + return f"Option<{base}>" if "null" in t else base + if t == "string": + if "enum" in s and len(s["enum"]) > 1: + return self.inline(s, hint) + return "String" + if t == "integer": + return "u64" if str(s.get("format", "")).startswith("uint") else "i64" + if t == "number": + return "f64" + if t == "boolean": + return "bool" + if t == "array": + return f"Vec<{self.ty(s.get('items', {}), hint + 'Item')}>" + if t == "object": + if s.get("properties"): + return self.inline(s, hint) + ap = s.get("additionalProperties", True) + v = "Value" if ap is True or ap is False else self.ty(ap, hint + "Value") + return f"BTreeMap" + return "Value" + + def inline(self, s, hint): + name = pascal(hint) + while name in self.items or name in self.defs: + name += "_" + self.items[name] = None + self.order.append(name) + self.items[name] = self.define(name, s) + return name + + def define(self, name, s): + doc = doc_lines(s.get("description")) + if "oneOf" in s and "properties" not in s: + return doc + self.one_of(name, s["oneOf"]) + if s.get("type") == "string" and "enum" in s: + self.defaultable[name] = False + return doc + self.enum(name, [(v, None) for v in s["enum"]]) + if "properties" in s: + return doc + self.struct(name, s) + self.defaultable[name] = True + return doc + f"pub type {name} = {self.ty(s, name + 'Inner')};\n" + + def enum(self, name, values): + out = [ + "#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]", + f"pub enum {name} {{", + ] + seen = set() + for v, d in values: + vn = pascal(v) + while vn in seen: + vn += "_" + seen.add(vn) + out += doc_lines(d, " ").splitlines() + out.append(f' #[serde(rename = "{v}")]\n {vn},') + return catch_all(out) + + def one_of(self, name, alts): + self.defaultable[name] = False + if all(a.get("type") == "string" and "enum" in a for a in alts): + vals = [(v, a.get("description")) for a in alts for v in a["enum"]] + return self.enum(name, vals) + tag = all( + a.get("type") == "object" + and "enum" in a.get("properties", {}).get("type", {}) + and len(a["properties"]["type"]["enum"]) == 1 + for a in alts + ) + out = ["#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]"] + if tag: + out.append('#[serde(tag = "type")]') + out.append(f"pub enum {name} {{") + for a in alts: + if tag: + v = a["properties"]["type"]["enum"][0] + body = dict( + a, + properties={ + k: p for k, p in a["properties"].items() if k != "type" + }, + ) + sname = a.get("title") or (name + pascal(v)) + if sname in self.defs or sname in self.items: + sname = name + pascal(v) + self.items[sname] = None + self.order.append(sname) + self.items[sname] = self.struct(sname, body) + out += doc_lines(a.get("description"), " ").splitlines() + out.append(f' #[serde(rename = "{v}")]\n {pascal(v)}({sname}),') + elif a.get("type") == "string" and "enum" in a: + for v in a["enum"]: + out += doc_lines(a.get("description"), " ").splitlines() + out.append(f' #[serde(rename = "{v}")]\n {pascal(v)},') + elif ( + a.get("type") == "object" + and len(a.get("required", [])) == 1 + and len(a.get("properties", {})) == 1 + ): + key = a["required"][0] + inner = self.ty(a["properties"][key], name + pascal(key)) + out += doc_lines(a.get("description"), " ").splitlines() + out.append( + f' #[serde(rename = "{key}")]\n {pascal(key)}({inner}),' + ) + return catch_all(out) + + def struct(self, name, s): + req = set(s.get("required", [])) + props = dict(s.get("properties", {})) + # Properties of `anyOf`/`oneOf` alternatives (one of several + # shapes) are each optional. + for k in ("anyOf", "oneOf"): + for a in s.get(k, []): + for pk, pv in a.get("properties", {}).items(): + props.setdefault(pk, pv) + fields = [] + defaultable = True + for pk in sorted(props): + ps = props[pk] + t = self.ty(ps, name + pascal(pk)) + opt = pk not in req and not t.startswith("Option<") + if opt: + t = f"Option<{t}>" + if t.startswith("Option<"): + attr = '#[serde(default, skip_serializing_if = "Option::is_none")]' + else: + attr = None + base = t.split("<")[0] + if base not in ( + "Vec", + "BTreeMap", + "Value", + "String", + "i64", + "u64", + "f64", + "bool", + ) and not self.defaultable.get(base, False): + defaultable = False + fields.append( + (pk, t, attr, ps.get("description") if isinstance(ps, dict) else None) + ) + self.defaultable[name] = defaultable + derive = "Debug, Clone, PartialEq, Serialize, Deserialize" + ( + ", Default" if defaultable else "" + ) + out = [f"#[derive({derive})]", f"pub struct {name} {{"] + for pk, t, attr, d in fields: + out += doc_lines(d, " ").splitlines() + fname = snake(pk) + if fname.removeprefix("r#") != pk: + out.append(f' #[serde(rename = "{pk}")]') + if attr: + out.append(f" {attr}") + out.append(f" pub {fname}: {t},") + out.append("}\n") + return "\n".join(out) + "\n" + + +def md_safe(ln): + """Keep the schema's prose from being read as rustdoc markup: outside + code spans and [`path`] links, brackets are escaped (rustdoc would try + to resolve them as links) and a bare URL becomes an autolink.""" + parts = re.split(r"(\[`[^`]*`\]|`[^`]*`|]*>)", ln) + for i in range(0, len(parts), 2): + t = re.sub(r"([\[\]])", r"\\\1", parts[i]) + parts[i] = re.sub(r"https?://[^\s<>]*[^\s<>).,;:]", lambda m: f"<{m[0]}>", t) + return "".join(parts) + + +def doc_lines(d, indent=""): + if not d: + return "" + lines = d.strip().replace("\r", "").split("\n") + return "".join( + f"{indent}///{(' ' + md_safe(ln.rstrip())) if ln.strip() else ''}\n" for ln in lines + ) + + +def methods(top, union): + out = {} + for a in top[union]["oneOf"]: + m = a["properties"]["method"]["enum"][0] + p = a["properties"].get("params", {}).get("$ref") + out[m] = p.split("/")[-1] if p else None + return out + + +def main(): + schema, version, out_path = sys.argv[1:4] + bundle = json.load(open(schema)) + ver = open(version).read().strip() + g = Gen(bundle) + top = bundle["definitions"] + impls = [] + creq = methods(top, "ClientRequest") + for m in REQUESTS: + p = creq[m] + r = p.removesuffix("Params") + "Response" + g.ref(p) + g.ref(r) + impls.append( + f'impl Request for {p} {{\n const METHOD: &\'static str = "{m}";\n type Response = {r};\n}}\n' + ) + notes = methods(top, "ServerNotification") + for m in NOTIFICATIONS: + p = notes[m] + g.ref(p) + impls.append( + f'impl Notification for {p} {{\n const METHOD: &\'static str = "{m}";\n}}\n' + ) + sreq = methods(top, "ServerRequest") + for m in SERVER_REQUESTS: + p = sreq[m] + r = p.removesuffix("Params") + "Response" + g.ref(p) + g.ref(r) + impls.append( + f'impl ServerRequest for {p} {{\n const METHOD: &\'static str = "{m}";\n type Response = {r};\n}}\n' + ) + g.drain() + head = f"""// @generated by scripts/gen-codex-protocol from +// schema/ (codex {ver}). Do not edit. + +use alloc::collections::BTreeMap; + +use serde::{{Deserialize, Serialize, de::DeserializeOwned}}; +use serde_json::Value; + +/// The Codex version this schema came from (`codex --version`). +pub const CODEX_VERSION: &str = "{ver}"; + +/// A client request: its method name and response type. +pub trait Request: Serialize {{ + const METHOD: &'static str; + type Response: DeserializeOwned; +}} + +/// A server notification: its method name. +pub trait Notification: DeserializeOwned {{ + const METHOD: &'static str; +}} + +/// A server-to-client request: its method name and response type. +pub trait ServerRequest: DeserializeOwned {{ + const METHOD: &'static str; + type Response: Serialize; +}} + +""" + body = "".join(impls) + "\n" + "\n".join(g.items[n] for n in sorted(g.order)) + with open(out_path, "w") as f: + f.write(head + body) + + +if __name__ == "__main__": + main() diff --git a/src/auth.rs b/src/auth.rs new file mode 100644 index 0000000..1cbaf11 --- /dev/null +++ b/src/auth.rs @@ -0,0 +1,184 @@ +//! Codex's `ChatGPT` login (`/auth.json`) shared with a session's +//! own `CODEX_HOME`: copied in before the app-server starts, copied back when +//! Codex refreshed its tokens and nobody else changed the real one since. +//! (The same rule a tool that refreshes the login and copies it back follows.) +//! +//! Unix only: the files are made 0600 and the directories 0700. + +use std::path::{Path, PathBuf}; + +/// Copy a refreshed `auth.json` back (pure decision): `orig` what was +/// copied in, `now_real` the real file now, `after` the session's copy. +/// Only when Codex rewrote it, it is a JSON object, and the real one is +/// unchanged since. +pub fn auth_to_copy_back(orig: &[u8], now_real: &[u8], after: &[u8]) -> bool { + after != orig + && now_real == orig + && !after.is_empty() + && serde_json::from_slice::(after).is_ok_and(|v| v.is_object()) +} + +/// What was copied into a session's home, to copy back on close. +/// +/// It holds the copied `auth.json` (its tokens), so its `Debug` shows only +/// the length of it. +#[derive(Clone)] +pub struct Copied { + pub real: PathBuf, + pub ours: PathBuf, + orig: Vec, +} + +impl Copied { + /// The length of the `auth.json` that was copied in. + pub fn orig_len(&self) -> usize { + self.orig.len() + } +} + +impl core::fmt::Debug for Copied { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Copied") + .field("real", &self.real) + .field("ours", &self.ours) + .field( + "orig", + &format_args!("[redacted; {} bytes]", self.orig.len()), + ) + .finish() + } +} + +/// Make `home` (0700) and copy `/auth.json` into it (0600). +pub async fn copy_in(from: &Path, home: &Path) -> std::io::Result { + mkdir_private(home).await?; + let real = from.join("auth.json"); + let orig = tokio::fs::read(&real).await?; + let ours = home.join("auth.json"); + write_private_atomic(&ours, &orig).await?; + Ok(Copied { real, ours, orig }) +} + +/// Copy the session's `auth.json` back when [`auth_to_copy_back`] says so. +/// Returns whether it did. +/// +/// Not atomic against another writer of the real file: one that writes it +/// between this reading it and the rename loses its write. The window is +/// short (a read and a rename); callers that share the real file across +/// processes serialise their copy-backs. +pub async fn copy_back(c: &Copied) -> std::io::Result { + let after = match tokio::fs::read(&c.ours).await { + Ok(b) => b, + Err(e) if e.kind() == std::io::ErrorKind::NotFound => return Ok(false), + Err(e) => return Err(e), + }; + let now_real = tokio::fs::read(&c.real).await?; + if !auth_to_copy_back(&c.orig, &now_real, &after) { + return Ok(false); + } + write_private_atomic(&c.real, &after).await?; + Ok(true) +} + +/// `mkdir -p -m 0700`: only the directories it creates get 0700; an +/// existing `p` keeps its mode. +pub async fn mkdir_private(p: &Path) -> std::io::Result<()> { + let mut b = tokio::fs::DirBuilder::new(); + b.recursive(true).mode(0o700); + b.create(p).await +} + +/// Write `data` to `p` (0600) through a temp file and a rename. +async fn write_private_atomic(p: &Path, data: &[u8]) -> std::io::Result<()> { + let name = p + .file_name() + .map(|n| n.to_string_lossy().into_owned()) + .unwrap_or_default(); + let nanos = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .map_or(0, |d| d.subsec_nanos()); + let tmp = p.with_file_name(format!(".{name}.codexwire-{}-{nanos}", std::process::id())); + let r = async { + let mut f = tokio::fs::OpenOptions::new() + .write(true) + .create_new(true) + .mode(0o600) + .open(&tmp) + .await?; + tokio::io::AsyncWriteExt::write_all(&mut f, data).await?; + f.sync_all().await?; + tokio::fs::rename(&tmp, p).await + } + .await; + if r.is_err() { + let _ = tokio::fs::remove_file(&tmp).await; + } + r +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn copy_back_decisions() { + let orig = br#"{"tokens":1}"#; + let new = br#"{"tokens":2}"#; + assert!( + auth_to_copy_back(orig, orig, new), + "refreshed, real unchanged" + ); + assert!(!auth_to_copy_back(orig, orig, orig), "not refreshed"); + assert!( + !auth_to_copy_back(orig, br#"{"tokens":3}"#, new), + "real changed meanwhile" + ); + assert!(!auth_to_copy_back(orig, orig, b""), "emptied"); + assert!(!auth_to_copy_back(orig, orig, b"not json"), "garbage"); + assert!(!auth_to_copy_back(orig, orig, b"[1]"), "not an object"); + } + + #[test] + fn debug_redacts_the_tokens() { + let c = Copied { + real: PathBuf::from("/r/auth.json"), + ours: PathBuf::from("/s/auth.json"), + orig: br#"{"tokens":{"access_token":"eyJsecret","refresh_token":"rt-secret"}}"# + .to_vec(), + }; + let d = format!("{c:?}"); + assert!(!d.contains("secret") && !d.contains("eyJ"), "{d}"); + let n = c.orig_len(); + assert!(d.contains(&format!("[redacted; {n} bytes]")), "{d}"); + assert!(d.contains("/r/auth.json"), "{d}"); + } + + #[tokio::test] + async fn copies_in_and_back() { + use std::os::unix::fs::PermissionsExt as _; + let d = tempfile::tempdir().unwrap(); + let real_home = d.path().join("real"); + tokio::fs::create_dir(&real_home).await.unwrap(); + tokio::fs::write(real_home.join("auth.json"), b"{\"a\":1}") + .await + .unwrap(); + let home = d.path().join("session/home"); + let c = copy_in(&real_home, &home).await.unwrap(); + let mode = tokio::fs::metadata(&c.ours) + .await + .unwrap() + .permissions() + .mode(); + assert_eq!(mode & 0o777, 0o600); + assert!(!copy_back(&c).await.unwrap(), "untouched: nothing to copy"); + tokio::fs::write(&c.ours, b"{\"a\":2}").await.unwrap(); + assert!(copy_back(&c).await.unwrap()); + assert_eq!(tokio::fs::read(&c.real).await.unwrap(), b"{\"a\":2}"); + // The real one changed since: leave it. + let c2 = copy_in(&real_home, &home).await.unwrap(); + tokio::fs::write(&c2.real, b"{\"other\":1}").await.unwrap(); + tokio::fs::write(&c2.ours, b"{\"a\":3}").await.unwrap(); + assert!(!copy_back(&c2).await.unwrap()); + assert_eq!(tokio::fs::read(&c2.real).await.unwrap(), b"{\"other\":1}"); + } +} diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..764a68d --- /dev/null +++ b/src/client.rs @@ -0,0 +1,635 @@ +//! The app-server client: writes requests, matches responses by id, and +//! hands the server's notifications and requests to the caller in order. +//! Generic over the transport (the child's stdio, or an in-process duplex +//! in tests). + +use alloc::collections::VecDeque; +use alloc::sync::Arc; +use core::sync::atomic::{AtomicI64, Ordering}; +use std::collections::HashMap; +use std::path::Path; +use std::process::Stdio; + +use serde_json::Value; +use tokio::io::{AsyncBufReadExt as _, AsyncRead, AsyncWrite, AsyncWriteExt as _, BufReader}; +use tokio::sync::{Mutex, mpsc, oneshot}; + +use crate::protocol::Request; +use crate::rpc::{self, Incoming, RequestId, RpcError}; + +/// Why a request failed. +#[derive(Debug, Clone, PartialEq)] +pub enum ClientError { + /// The server answered with an error. + Rpc(RpcError), + /// The connection closed before the answer. + Closed, + /// Writing failed. + Io(String), + /// The params didn't serialise as JSON. + Encode(String), + /// The answer didn't decode as the method's response type. + Decode(String), +} + +impl core::fmt::Display for ClientError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Rpc(e) => write!(f, "app-server error: {e}"), + Self::Closed => f.write_str("app-server connection closed"), + Self::Io(e) => write!(f, "app-server write: {e}"), + Self::Encode(e) => write!(f, "app-server request params: {e}"), + Self::Decode(e) => write!(f, "app-server answer: {e}"), + } + } +} + +impl core::error::Error for ClientError {} + +/// What the server sends us, in order. +#[derive(Debug, Clone, PartialEq)] +pub enum ServerMessage { + /// Answer it with [`Client::respond`] or [`Client::respond_error`]. + Request { + id: RequestId, + method: String, + params: Value, + }, + Notification { + method: String, + params: Value, + }, + /// A line that didn't parse, or wasn't UTF-8: why (logged and skipped + /// by most callers). The connection goes on. + Malformed(String), +} + +/// The calls waiting for an answer, and whether the reader has stopped +/// (then no call waits: it would wait forever). +#[derive(Default)] +struct PendingState { + closed: bool, + waiting: HashMap>>, +} + +type Pending = Arc>; + +/// Removes a call's entry when its future is done or dropped (cancelled by +/// a `select!` or a timeout), so abandoned calls don't pile up. +struct Waiting<'a> { + pending: &'a Pending, + id: i64, +} + +impl Drop for Waiting<'_> { + fn drop(&mut self) { + lock(self.pending).waiting.remove(&self.id); + } +} + +/// The request side; cheap to share (`Arc`). +pub struct Client { + writer: Mutex>, + next_id: AtomicI64, + pending: Pending, +} + +/// The server's notifications and requests; `None` once it closed. +pub type Messages = mpsc::UnboundedReceiver; + +fn lock(m: &std::sync::Mutex) -> std::sync::MutexGuard<'_, T> { + m.lock().unwrap_or_else(std::sync::PoisonError::into_inner) +} + +impl Client { + /// Start reading `reader` (a task) and writing to `writer`. + /// + /// The reader runs until `reader` ends (EOF or an I/O error); a line + /// that isn't JSON-RPC or isn't UTF-8 comes out as + /// [`ServerMessage::Malformed`] and the reading goes on. + /// + /// Neither the line length nor the [`Messages`] channel is bounded: a + /// caller that stops reading `Messages`, or a server that writes one + /// huge line, grows memory. + /// + /// # Panics + /// + /// Outside a tokio runtime (it spawns the reader with `tokio::spawn`). + pub fn new(reader: R, writer: W) -> (Arc, Messages) + where + R: AsyncRead + Send + Unpin + 'static, + W: AsyncWrite + Send + Unpin + 'static, + { + let pending: Pending = Arc::default(); + let (tx, rx) = mpsc::unbounded_channel(); + tokio::spawn(read_server(reader, Arc::clone(&pending), tx)); + let c = Self { + writer: Mutex::new(Box::new(writer)), + next_id: AtomicI64::new(1), + pending, + }; + (Arc::new(c), rx) + } + + async fn write(&self, line: &str) -> Result<(), ClientError> { + let mut w = self.writer.lock().await; + w.write_all(line.as_bytes()) + .await + .map_err(|e| ClientError::Io(e.to_string()))?; + w.flush().await.map_err(|e| ClientError::Io(e.to_string())) + } + + /// Send a raw request and await its result. + /// + /// [`ClientError::Closed`] at once once the server's output has ended. + /// There is no timeout of its own: wrap it (or [`Client::request`]) in + /// `tokio::time::timeout`. Dropping the future (a timeout, a `select!`) + /// forgets the request; a late answer to it is ignored. + pub async fn call(&self, method: &str, params: &Value) -> Result { + let id = self.next_id.fetch_add(1, Ordering::Relaxed); + let (tx, rx) = oneshot::channel(); + { + let mut p = lock(&self.pending); + if p.closed { + return Err(ClientError::Closed); + } + p.waiting.insert(id, tx); + } + let _waiting = Waiting { + pending: &self.pending, + id, + }; + self.write(&rpc::request(&Value::from(id), method, params)) + .await?; + match rx.await { + Ok(Ok(v)) => Ok(v), + Ok(Err(e)) => Err(ClientError::Rpc(e)), + Err(_) => Err(ClientError::Closed), + } + } + + /// A typed request (its method and response from the generated + /// protocol). + pub async fn request(&self, params: &R) -> Result { + let p = serde_json::to_value(params).map_err(|e| ClientError::Encode(e.to_string()))?; + let v = self.call(R::METHOD, &p).await?; + serde_json::from_value(v).map_err(|e| ClientError::Decode(format!("{}: {e}", R::METHOD))) + } + + pub async fn notify(&self, method: &str, params: Option<&Value>) -> Result<(), ClientError> { + self.write(&rpc::notification(method, params)).await + } + + pub async fn respond(&self, id: &RequestId, result: &Value) -> Result<(), ClientError> { + self.write(&rpc::response(id, result)).await + } + + pub async fn respond_error( + &self, + id: &RequestId, + code: i64, + message: &str, + ) -> Result<(), ClientError> { + self.write(&rpc::error_response(id, code, message)).await + } + + /// Close our side (the app-server exits on EOF). + pub async fn shutdown(&self) { + let _ = self.writer.lock().await.shutdown().await; + } +} + +/// The reader task: route answers to their calls, hand the rest to `tx`. +async fn read_server( + reader: R, + p: Pending, + tx: mpsc::UnboundedSender, +) { + let mut reader = BufReader::new(reader); + let mut buf = Vec::new(); + loop { + buf.clear(); + match reader.read_until(b'\n', &mut buf).await { + Ok(0) | Err(_) => break, + Ok(_) => {} + } + let line = match core::str::from_utf8(&buf) { + Ok(l) => l, + Err(e) => { + let _ = tx.send(ServerMessage::Malformed(format!( + "JSON-RPC line is not UTF-8: {e}" + ))); + continue; + } + }; + let msg = match rpc::parse_line(line) { + Ok(None) => continue, + Ok(Some(m)) => m, + Err(e) => { + let _ = tx.send(ServerMessage::Malformed(e)); + continue; + } + }; + match msg { + Incoming::Response { id, result } => answer(&p, &id, Ok(result)), + Incoming::Error { id, error } => answer(&p, &id, Err(error)), + Incoming::Request { id, method, params } => { + let _ = tx.send(ServerMessage::Request { id, method, params }); + } + Incoming::Notification { method, params } => { + let _ = tx.send(ServerMessage::Notification { method, params }); + } + } + } + // Closed: fail whatever is still waiting (dropping the senders), and + // every later call. + let mut p = lock(&p); + p.closed = true; + p.waiting.clear(); +} + +fn answer(p: &Pending, id: &RequestId, r: Result) { + let Some(id) = id.as_i64() else { return }; + if let Some(tx) = lock(p).waiting.remove(&id) { + let _ = tx.send(r); + } +} + +/// The last lines the child wrote on stderr (for error messages). +#[derive(Clone, Default)] +pub struct StderrTail(Arc>>); + +impl StderrTail { + const KEEP: usize = 20; + + /// Keep `line`, dropping the oldest past the last 20 (for a child this + /// crate didn't spawn; `spawn_app_server` fills its own). + pub fn push(&self, line: String) { + let mut q = lock(&self.0); + if q.len() == Self::KEEP { + q.pop_front(); + } + q.push_back(line); + } + + /// Keep each line of `reader` until it ends (EOF or an I/O error). + /// Lines that aren't UTF-8 are kept lossily (`U+FFFD`), so the reading + /// never stops early and the child never writes into a closed pipe. + pub async fn read_from(&self, reader: R) { + let mut reader = BufReader::new(reader); + let mut buf = Vec::new(); + loop { + buf.clear(); + match reader.read_until(b'\n', &mut buf).await { + Ok(0) | Err(_) => break, + Ok(_) => {} + } + let line = String::from_utf8_lossy(&buf); + self.push(line.trim_end_matches(['\n', '\r']).to_owned()); + } + } + + /// The kept lines, oldest first, one a line. + pub fn text(&self) -> String { + lock(&self.0) + .iter() + .map(String::as_str) + .collect::>() + .join("\n") + } +} + +/// `text` with secret-looking words (`sk-…`, a JWT, a long token, the +/// value after `Bearer` or of a `key=`/`token:`-style pair) as +/// `[redacted]`, cut to `max` characters. +pub fn redact(text: &str, max: usize) -> String { + let mut out = String::with_capacity(text.len().min(max)); + for (i, line) in text.lines().enumerate() { + if i > 0 { + out.push('\n'); + } + let mut after_bearer = false; + for (j, w) in line.split(' ').enumerate() { + if j > 0 { + out.push(' '); + } + if after_bearer || secretish(w) { + out.push_str("[redacted]"); + } else if let Some((k, _)) = secret_pair(w) { + out.push_str(k); + out.push_str("[redacted]"); + } else { + out.push_str(w); + } + after_bearer = w.eq_ignore_ascii_case("bearer") || w.eq_ignore_ascii_case("bearer:"); + } + } + if out.chars().count() > max { + let mut cut: String = out.chars().take(max.saturating_sub(1)).collect(); + cut.push('…'); + cut + } else { + out + } +} + +/// A word that looks like a credential on its own. +fn secretish(w: &str) -> bool { + let w = w.trim_matches(|c: char| "\"'`,;()[]{}<>".contains(c)); + let tokenish = w.len() >= 24 + && w.chars() + .all(|c| c.is_ascii_alphanumeric() || "-_.=+/".contains(c)) + && w.chars().any(|c| c.is_ascii_digit()) + && !w.contains("//"); + w.starts_with("sk-") || w.starts_with("eyJ") || tokenish +} + +/// `token=…`, `"api_key":"…"`, `password: …` (the part up to and +/// including the separator, and the value). +fn secret_pair(w: &str) -> Option<(&str, &str)> { + let i = w.find(['=', ':'])?; + let key = w[..i] + .trim_matches(|c: char| "\"'`{,".contains(c)) + .to_ascii_lowercase(); + let secret = [ + "token", "secret", "password", "passwd", "api_key", "apikey", "auth", "key", + ] + .iter() + .any(|s| key.ends_with(s)) + && !key.ends_with("tokens"); + let value = &w[i + 1..]; + (secret && !value.is_empty()).then(|| (&w[..=i], value)) +} + +/// The parent's environment variables a `codex app-server` gets (besides +/// the backend's own, like `CODEX_HOME`): it starts from an empty one, so +/// no secret of the parent's reaches the session. +/// +/// No proxy variables (`HTTPS_PROXY`, `NO_PROXY`, ...): a proxy URL can +/// carry credentials. A caller that needs them passes them in `env`. +pub const ENV_ALLOW: &[&str] = &[ + "PATH", + "HOME", + "USER", + "LOGNAME", + "LANG", + "LC_ALL", + "TZ", + "TMPDIR", + "SSL_CERT_FILE", + "NIX_SSL_CERT_FILE", +]; + +/// [`ENV_ALLOW`]'s values from `from` (the parent's environment), then +/// `extra` (which wins). +pub fn child_env( + from: impl IntoIterator, + extra: &[(String, String)], +) -> Vec<(String, String)> { + let mut env: Vec<(String, String)> = from + .into_iter() + .filter(|(k, _)| ENV_ALLOW.contains(&k.as_str())) + .filter(|(k, _)| !extra.iter().any(|(e, _)| e == k)) + .collect(); + env.extend(extra.iter().cloned()); + env +} + +/// A running `codex app-server`. +pub struct AppServer { + pub client: Arc, + pub messages: Messages, + pub child: tokio::process::Child, + pub stderr: StderrTail, +} + +/// Spawn ` app-server ` in `cwd` with only `env` and the +/// parent's [`ENV_ALLOW`] variables (killed when dropped). +/// +/// For a graceful stop, [`Client::shutdown`] (the server exits on EOF), +/// then await `child.wait()` under a timeout before dropping it. +/// +/// # Panics +/// +/// Outside a tokio runtime, like [`Client::new`]. +pub fn spawn_app_server( + command: &str, + args: &[String], + env: &[(String, String)], + cwd: &Path, +) -> std::io::Result { + let mut cmd = tokio::process::Command::new(command); + cmd.arg("app-server") + .args(args) + .current_dir(cwd) + .env_clear() + .envs(child_env(std::env::vars(), env)) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .kill_on_drop(true); + let mut child = cmd.spawn()?; + let (Some(stdin), Some(stdout), Some(stderr)) = + (child.stdin.take(), child.stdout.take(), child.stderr.take()) + else { + return Err(std::io::Error::other("app-server stdio not piped")); + }; + let tail = StderrTail::default(); + let t = tail.clone(); + tokio::spawn(async move { t.read_from(stderr).await }); + let (client, messages) = Client::new(stdout, stdin); + Ok(AppServer { + client, + messages, + child, + stderr: tail, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use serde_json::json; + + #[test] + fn redacts_and_caps_stderr() { + let t = "error: auth failed Bearer abc.def token=hunter2 key sk-proj-123\n\ + jwt eyJhbGciOi x 0123456789abcdefABCDEF0123 max_tokens=5 at /home/alice/x.rs:3"; + assert_eq!( + redact(t, 1000), + "error: auth failed Bearer [redacted] token=[redacted] key [redacted]\n\ + jwt [redacted] x [redacted] max_tokens=5 at /home/alice/x.rs:3" + ); + assert_eq!(redact("\"api_key\":\"zz\"", 100), "\"api_key\":[redacted]"); + let long = "a ".repeat(2000); + let r = redact(&long, 50); + assert_eq!(r.chars().count(), 50); + assert!(r.ends_with('…')); + } + + #[test] + fn the_child_env_is_an_allowlist() { + let parent = [ + ("PATH", "/bin"), + ("HOME", "/home/alice"), + ("ANTHROPIC_API_KEY", "sk-x"), + ("DAEMON_TOKEN", "t"), + ("CODEX_HOME", "/parent/codex"), + ] + .map(|(k, v)| (k.to_owned(), v.to_owned())); + let extra = [("CODEX_HOME".to_owned(), "/s/codex".to_owned())]; + let env = child_env(parent, &extra); + assert_eq!( + env, + [ + ("PATH", "/bin"), + ("HOME", "/home/alice"), + ("CODEX_HOME", "/s/codex") + ] + .map(|(k, v)| (k.to_owned(), v.to_owned())) + ); + } + + #[tokio::test] + async fn matches_responses_and_forwards_the_rest() { + let (ours, theirs) = tokio::io::duplex(4096); + let (rd, wr) = tokio::io::split(ours); + let (client, mut msgs) = Client::new(rd, wr); + let (sr, mut sw) = tokio::io::split(theirs); + let mut sr = BufReader::new(sr).lines(); + let c = Arc::clone(&client); + let call = tokio::spawn(async move { c.call("thread/start", &json!({"cwd":"/w"})).await }); + let line = sr.next_line().await.unwrap().unwrap(); + let v: Value = serde_json::from_str(&line).unwrap(); + assert_eq!(v["method"], "thread/start"); + let id = v["id"].clone(); + // A notification and a server request before the answer. + sw.write_all(b"{\"method\":\"thread/started\",\"params\":{}}\n{\"id\":0,\"method\":\"item/fileChange/requestApproval\",\"params\":{}}\n") + .await + .unwrap(); + sw.write_all(rpc::response(&id, &json!({"ok":true})).as_bytes()) + .await + .unwrap(); + assert_eq!(call.await.unwrap().unwrap(), json!({"ok":true})); + assert!( + matches!(msgs.recv().await, Some(ServerMessage::Notification { method, .. }) if method == "thread/started") + ); + assert!( + matches!(msgs.recv().await, Some(ServerMessage::Request { method, .. }) if method == "item/fileChange/requestApproval") + ); + client + .respond(&json!(0), &json!({"decision":"accept"})) + .await + .unwrap(); + assert_eq!( + sr.next_line().await.unwrap().unwrap(), + r#"{"id":0,"result":{"decision":"accept"}}"# + ); + // An error answer, then the server goes away mid-request. + let c = Arc::clone(&client); + let call = tokio::spawn(async move { c.call("turn/start", &json!({})).await }); + let v: Value = serde_json::from_str(&sr.next_line().await.unwrap().unwrap()).unwrap(); + sw.write_all(rpc::error_response(&v["id"], -1, "bad").as_bytes()) + .await + .unwrap(); + assert!(matches!(call.await.unwrap(), Err(ClientError::Rpc(e)) if e.message == "bad")); + let c = Arc::clone(&client); + let call = tokio::spawn(async move { c.call("turn/start", &json!({})).await }); + let _ = sr.next_line().await.unwrap(); + drop(sw); + drop(sr); + assert_eq!(call.await.unwrap(), Err(ClientError::Closed)); + assert_eq!(msgs.recv().await, None); + } + + /// What the server reads: our lines. + type ServerIn = tokio::io::Lines>; + + /// A client over two pipes: the server's output (`out`) and its input + /// (`inp`), so either can close alone. + fn piped() -> (Arc, Messages, tokio::io::DuplexStream, ServerIn) { + let (out_ours, out_theirs) = tokio::io::duplex(4096); + let (in_ours, in_theirs) = tokio::io::duplex(4096); + let (client, msgs) = Client::new(out_ours, in_ours); + (client, msgs, out_theirs, BufReader::new(in_theirs).lines()) + } + + async fn within(f: F) -> F::Output { + tokio::time::timeout(core::time::Duration::from_secs(5), f) + .await + .expect("hung") + } + + #[tokio::test] + async fn a_call_after_the_server_output_ended_fails_at_once() { + let (client, mut msgs, out, _inp) = piped(); + // The server's stdout closes; its stdin (ours to write) stays open. + drop(out); + assert_eq!(within(msgs.recv()).await, None); + assert_eq!( + within(client.call("thread/start", &json!({}))).await, + Err(ClientError::Closed) + ); + assert!(lock(&client.pending).waiting.is_empty()); + } + + #[tokio::test] + async fn a_line_that_is_not_utf8_is_malformed_and_reading_goes_on() { + let (client, mut msgs, mut out, mut inp) = piped(); + let c = Arc::clone(&client); + let call = tokio::spawn(async move { c.call("turn/start", &json!({})).await }); + let v: Value = serde_json::from_str(&inp.next_line().await.unwrap().unwrap()).unwrap(); + out.write_all( + b"\xff\xfe not utf-8\n{\"method\":\"turn/started\",\"params\":{}}\nnot json\n", + ) + .await + .unwrap(); + out.write_all(rpc::response(&v["id"], &json!(1)).as_bytes()) + .await + .unwrap(); + assert!( + matches!(within(msgs.recv()).await, Some(ServerMessage::Malformed(e)) if e.contains("UTF-8")) + ); + assert!( + matches!(within(msgs.recv()).await, Some(ServerMessage::Notification { method, .. }) if method == "turn/started") + ); + assert!(matches!( + within(msgs.recv()).await, + Some(ServerMessage::Malformed(_)) + )); + assert_eq!(within(call).await.unwrap(), Ok(json!(1))); + } + + #[tokio::test] + async fn a_cancelled_call_forgets_its_request() { + let (client, mut msgs, mut out, mut inp) = piped(); + let r = tokio::time::timeout( + core::time::Duration::from_millis(50), + client.call("turn/start", &json!({})), + ) + .await; + assert!(r.is_err(), "no answer: times out"); + assert!(lock(&client.pending).waiting.is_empty()); + // A late answer to it is ignored; the connection goes on. + let v: Value = serde_json::from_str(&inp.next_line().await.unwrap().unwrap()).unwrap(); + out.write_all(rpc::response(&v["id"], &json!(1)).as_bytes()) + .await + .unwrap(); + out.write_all(b"{\"method\":\"x\"}\n").await.unwrap(); + assert!( + matches!(within(msgs.recv()).await, Some(ServerMessage::Notification { method, .. }) if method == "x") + ); + } + + #[tokio::test] + async fn stderr_lines_that_are_not_utf8_are_kept_lossily() { + let tail = StderrTail::default(); + tail.read_from(&b"one\n\xff two\r\nthree"[..]).await; + assert_eq!(tail.text(), "one\n\u{fffd} two\nthree"); + for i in 0..30 { + tail.push(i.to_string()); + } + assert_eq!(tail.text().lines().count(), 20); + assert!(tail.text().starts_with("10\n")); + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..9fd12f6 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,59 @@ +//! `codexwire`: a client for `OpenAI` Codex's app-server (`codex app-server`, +//! JSON-RPC over the child's stdio), the Codex counterpart to ccwire. +//! +//! Faithful to Codex's own protocol: [`protocol`] is generated from the +//! pinned Codex's JSON Schema (`scripts/gen-codex-protocol`; the schema and +//! its `VERSION` are in `schema/`, [`CODEX_VERSION`] is the version), [`rpc`] +//! frames its messages, [`client`] runs the child and matches responses to +//! requests, and [`auth`] gives a session its own copy of `auth.json`. +//! +//! The README follows (its example is compiled as a doctest). +//! +#![doc = include_str!("../README.md")] +// Owned arguments where the callee keeps them, and Result-returning helpers +// kept uniform; the error docs would only restate the messages. +#![allow( + clippy::missing_errors_doc, + clippy::missing_panics_doc, + clippy::needless_pass_by_value, + clippy::unnecessary_wraps +)] +// `#[tokio::test]` expands to `block_on`, which clippy.toml keeps out of +// the library itself. +#![cfg_attr(test, allow(clippy::disallowed_methods))] + +extern crate alloc; + +pub mod auth; +pub mod client; +#[allow( + missing_docs, + clippy::pedantic, + clippy::large_enum_variant, + clippy::enum_variant_names, + clippy::doc_markdown, + non_camel_case_types, + reason = "generated" +)] +pub mod protocol; +pub mod rpc; + +pub use protocol::CODEX_VERSION; + +/// The version in an app-server `userAgent` (`/ (...)`). +pub fn user_agent_version(ua: &str) -> Option<&str> { + let (_, rest) = ua.split_once('/')?; + rest.split_whitespace().next() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn version_from_user_agent() { + let ua = "my-client/0.158.0 (NixOS 26.11.0; x86_64) dumb (my-client; 0.1.0)"; + assert_eq!(user_agent_version(ua), Some("0.158.0")); + assert_eq!(user_agent_version("nothing"), None); + } +} diff --git a/src/protocol.rs b/src/protocol.rs new file mode 100644 index 0000000..fa36c4e --- /dev/null +++ b/src/protocol.rs @@ -0,0 +1,2000 @@ +// @generated by scripts/gen-codex-protocol from +// schema/ (codex 0.158.0). Do not edit. + +use alloc::collections::BTreeMap; + +use serde::{Deserialize, Serialize, de::DeserializeOwned}; +use serde_json::Value; + +/// The Codex version this schema came from (`codex --version`). +pub const CODEX_VERSION: &str = "0.158.0"; + +/// A client request: its method name and response type. +pub trait Request: Serialize { + const METHOD: &'static str; + type Response: DeserializeOwned; +} + +/// A server notification: its method name. +pub trait Notification: DeserializeOwned { + const METHOD: &'static str; +} + +/// A server-to-client request: its method name and response type. +pub trait ServerRequest: DeserializeOwned { + const METHOD: &'static str; + type Response: Serialize; +} + +impl Request for InitializeParams { + const METHOD: &'static str = "initialize"; + type Response = InitializeResponse; +} +impl Request for ThreadStartParams { + const METHOD: &'static str = "thread/start"; + type Response = ThreadStartResponse; +} +impl Request for ThreadResumeParams { + const METHOD: &'static str = "thread/resume"; + type Response = ThreadResumeResponse; +} +impl Request for TurnStartParams { + const METHOD: &'static str = "turn/start"; + type Response = TurnStartResponse; +} +impl Request for TurnInterruptParams { + const METHOD: &'static str = "turn/interrupt"; + type Response = TurnInterruptResponse; +} +impl Notification for ErrorNotification { + const METHOD: &'static str = "error"; +} +impl Notification for ThreadStartedNotification { + const METHOD: &'static str = "thread/started"; +} +impl Notification for TurnStartedNotification { + const METHOD: &'static str = "turn/started"; +} +impl Notification for TurnCompletedNotification { + const METHOD: &'static str = "turn/completed"; +} +impl Notification for ItemStartedNotification { + const METHOD: &'static str = "item/started"; +} +impl Notification for ItemCompletedNotification { + const METHOD: &'static str = "item/completed"; +} +impl Notification for AgentMessageDeltaNotification { + const METHOD: &'static str = "item/agentMessage/delta"; +} +impl Notification for ThreadTokenUsageUpdatedNotification { + const METHOD: &'static str = "thread/tokenUsage/updated"; +} +impl Notification for AccountRateLimitsUpdatedNotification { + const METHOD: &'static str = "account/rateLimits/updated"; +} +impl ServerRequest for CommandExecutionRequestApprovalParams { + const METHOD: &'static str = "item/commandExecution/requestApproval"; + type Response = CommandExecutionRequestApprovalResponse; +} +impl ServerRequest for FileChangeRequestApprovalParams { + const METHOD: &'static str = "item/fileChange/requestApproval"; + type Response = FileChangeRequestApprovalResponse; +} +impl ServerRequest for McpServerElicitationRequestParams { + const METHOD: &'static str = "mcpServer/elicitation/request"; + type Response = McpServerElicitationRequestResponse; +} + +/// A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem). +/// +/// IMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using \[AbsolutePathBufGuard::new\]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute. +pub type AbsolutePathBuf = String; + +/// Sparse rolling rate-limit update. +/// +/// Clients should merge available values into the most recent `account/rateLimits/read` response or refetch that snapshot. Nullable account metadata may be unavailable in a rolling update and does not clear a previously observed value. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct AccountRateLimitsUpdatedNotification { + #[serde(rename = "rateLimits")] + pub rate_limits: RateLimitSnapshot, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct AddPatchChangeKind {} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum AgentMessageDelivery { + #[serde(rename = "async")] + Async, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct AgentMessageDeltaNotification { + pub delta: String, + #[serde(rename = "itemId")] + pub item_id: String, + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "turnId")] + pub turn_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct AgentMessageThreadItem { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub delivery: Option, + pub id: String, + #[serde(rename = "memoryCitation")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub memory_citation: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub phase: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub questions: Option>, + pub text: String, +} + +pub type AgentPath = String; + +/// Configures who approval requests are routed to for review. Examples include sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations. Defaults to `user`. `auto_review` uses a carefully prompted subagent to gather relevant context and apply a risk-based decision framework before approving or denying the request. The legacy value `guardian_subagent` is accepted for compatibility. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ApprovalsReviewer { + #[serde(rename = "user")] + User, + #[serde(rename = "auto_review")] + AutoReview, + #[serde(rename = "guardian_subagent")] + GuardianSubagent, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum AskForApproval { + #[serde(rename = "untrusted")] + Untrusted, + #[serde(rename = "on-request")] + OnRequest, + #[serde(rename = "never")] + Never, + #[serde(rename = "granular")] + Granular(AskForApprovalGranular), + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct AskForApprovalGranular { + pub mcp_elicitations: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub request_permissions: Option, + pub rules: bool, + pub sandbox_approval: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub skill_approval: Option, +} + +pub type AsyncUserInputQuestion = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct AudioUserInput { + pub url: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ClientInfo { + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub title: Option, + pub version: String, +} + +/// This translation layer make sure that we expose codex error code in camel case. +/// +/// When an upstream HTTP status is available (for example, from the Responses API or a provider), it is forwarded in `httpStatusCode` on the relevant `codexErrorInfo` variant. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum CodexErrorInfo { + #[serde(rename = "contextWindowExceeded")] + ContextWindowExceeded, + #[serde(rename = "sessionBudgetExceeded")] + SessionBudgetExceeded, + #[serde(rename = "usageLimitExceeded")] + UsageLimitExceeded, + #[serde(rename = "rateLimitExceeded")] + RateLimitExceeded, + #[serde(rename = "flexUnavailable")] + FlexUnavailable, + #[serde(rename = "serverOverloaded")] + ServerOverloaded, + #[serde(rename = "cyberPolicy")] + CyberPolicy, + #[serde(rename = "misalignmentPolicyViolation")] + MisalignmentPolicyViolation, + #[serde(rename = "internalServerError")] + InternalServerError, + #[serde(rename = "unauthorized")] + Unauthorized, + #[serde(rename = "badRequest")] + BadRequest, + #[serde(rename = "threadRollbackFailed")] + ThreadRollbackFailed, + #[serde(rename = "sandboxError")] + SandboxError, + #[serde(rename = "other")] + Other, + #[serde(rename = "httpConnectionFailed")] + HttpConnectionFailed(CodexErrorInfoHttpConnectionFailed), + /// Failed to connect to the response SSE stream. + #[serde(rename = "responseStreamConnectionFailed")] + ResponseStreamConnectionFailed(CodexErrorInfoResponseStreamConnectionFailed), + /// The response SSE stream disconnected in the middle of a turn before completion. + #[serde(rename = "responseStreamDisconnected")] + ResponseStreamDisconnected(CodexErrorInfoResponseStreamDisconnected), + /// Reached the retry limit for responses. + #[serde(rename = "responseTooManyFailedAttempts")] + ResponseTooManyFailedAttempts(CodexErrorInfoResponseTooManyFailedAttempts), + /// Returned when `turn/start` or `turn/steer` is submitted while the current active turn cannot accept same-turn steering, for example `/review` or manual `/compact`. + #[serde(rename = "activeTurnNotSteerable")] + ActiveTurnNotSteerable(CodexErrorInfoActiveTurnNotSteerable), + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct CodexErrorInfoActiveTurnNotSteerable { + #[serde(rename = "turnKind")] + pub turn_kind: NonSteerableTurnKind, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct CodexErrorInfoHttpConnectionFailed { + #[serde(rename = "httpStatusCode")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub http_status_code: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct CodexErrorInfoResponseStreamConnectionFailed { + #[serde(rename = "httpStatusCode")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub http_status_code: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct CodexErrorInfoResponseStreamDisconnected { + #[serde(rename = "httpStatusCode")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub http_status_code: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct CodexErrorInfoResponseTooManyFailedAttempts { + #[serde(rename = "httpStatusCode")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub http_status_code: Option, +} + +pub type CollabAgentState = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum CollabAgentTool { + #[serde(rename = "spawnAgent")] + SpawnAgent, + #[serde(rename = "sendInput")] + SendInput, + #[serde(rename = "resumeAgent")] + ResumeAgent, + #[serde(rename = "wait")] + Wait, + #[serde(rename = "closeAgent")] + CloseAgent, + #[serde(rename = "sendMessage")] + SendMessage, + #[serde(rename = "followupTask")] + FollowupTask, + #[serde(rename = "interruptAgent")] + InterruptAgent, + #[serde(rename = "listAgents")] + ListAgents, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum CollabAgentToolCallStatus { + #[serde(rename = "inProgress")] + InProgress, + #[serde(rename = "completed")] + Completed, + #[serde(rename = "failed")] + Failed, + #[serde(rename = "interrupted")] + Interrupted, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct CollabAgentToolCallThreadItem { + /// Last known status of the target agents, when available. + #[serde(rename = "agentsStates")] + pub agents_states: BTreeMap, + /// Unique identifier for this collab tool call. + pub id: String, + /// Model requested for the spawned agent, when applicable. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model: Option, + /// Prompt text sent as part of the collab tool call, when available. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub prompt: Option, + /// Reasoning effort requested for the spawned agent, when applicable. + #[serde(rename = "reasoningEffort")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reasoning_effort: Option, + /// Thread ID of the receiving agent, when applicable. In case of spawn operation, this corresponds to the newly spawned agent. + #[serde(rename = "receiverThreadIds")] + pub receiver_thread_ids: Vec, + /// Thread ID of the agent issuing the collab request. + #[serde(rename = "senderThreadId")] + pub sender_thread_id: String, + /// Current status of the collab tool call. + pub status: CollabAgentToolCallStatus, + /// Name of the collab tool that was invoked. + pub tool: CollabAgentTool, +} + +/// Collaboration mode for a Codex session. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct CollaborationMode { + pub mode: ModeKind, + pub settings: Settings, +} + +pub type CommandAction = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum CommandExecutionApprovalDecision { + /// User approved the command. + #[serde(rename = "accept")] + Accept, + /// User approved the command and future prompts in the same session-scoped approval cache should run without prompting. + #[serde(rename = "acceptForSession")] + AcceptForSession, + /// User approved the command, and wants to apply the proposed execpolicy amendment so future matching commands can run without prompting. + #[serde(rename = "acceptWithExecpolicyAmendment")] + AcceptWithExecpolicyAmendment(CommandExecutionApprovalDecisionAcceptWithExecpolicyAmendment), + /// User chose a persistent network policy rule (allow/deny) for this host. + #[serde(rename = "applyNetworkPolicyAmendment")] + ApplyNetworkPolicyAmendment(CommandExecutionApprovalDecisionApplyNetworkPolicyAmendment), + /// User denied the command. The agent will continue the turn. + #[serde(rename = "decline")] + Decline, + /// User denied the command. The turn will also be immediately interrupted. + #[serde(rename = "cancel")] + Cancel, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct CommandExecutionApprovalDecisionAcceptWithExecpolicyAmendment { + pub execpolicy_amendment: Vec, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct CommandExecutionApprovalDecisionApplyNetworkPolicyAmendment { + pub network_policy_amendment: NetworkPolicyAmendment, +} + +/// Distinguishes a command approval from input sent to an existing terminal. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum CommandExecutionApprovalKind { + #[serde(rename = "command")] + Command, + #[serde(rename = "writeStdin")] + WriteStdin, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct CommandExecutionRequestApprovalParams { + /// Unique identifier for this specific approval callback. + /// + /// For regular shell/unified_exec approvals, this is null. + /// + /// For zsh-exec-bridge subcommand approvals, multiple callbacks can belong to one parent `itemId`, so `approvalId` is a distinct opaque callback id (a UUID) used to disambiguate routing. Stdin approvals also use a distinct callback id; inspect `kind` to distinguish them. + #[serde(rename = "approvalId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub approval_id: Option, + /// The command to be executed. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub command: Option, + /// Best-effort parsed command actions for friendly display. + #[serde(rename = "commandActions")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub command_actions: Option>, + /// The command's working directory. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cwd: Option, + /// Environment in which the command will run. + #[serde(rename = "environmentId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub environment_id: Option, + #[serde(rename = "itemId")] + pub item_id: String, + /// Kind of action under review. Defaults to `command` for older servers. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub kind: Option, + /// Optional context for a managed-network approval prompt. + #[serde(rename = "networkApprovalContext")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub network_approval_context: Option, + /// Optional proposed execpolicy amendment to allow similar commands without prompting. + #[serde(rename = "proposedExecpolicyAmendment")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub proposed_execpolicy_amendment: Option>, + /// Optional proposed network policy amendments (allow/deny host) for future requests. + #[serde(rename = "proposedNetworkPolicyAmendments")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub proposed_network_policy_amendments: Option>, + /// Optional explanatory reason (e.g. request for network access). + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reason: Option, + /// Unix timestamp (in milliseconds) when this approval request started. + #[serde(rename = "startedAtMs")] + pub started_at_ms: i64, + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "turnId")] + pub turn_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct CommandExecutionRequestApprovalResponse { + pub decision: CommandExecutionApprovalDecision, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum CommandExecutionSource { + #[serde(rename = "agent")] + Agent, + #[serde(rename = "userShell")] + UserShell, + #[serde(rename = "unifiedExecStartup")] + UnifiedExecStartup, + #[serde(rename = "unifiedExecInteraction")] + UnifiedExecInteraction, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum CommandExecutionStatus { + #[serde(rename = "inProgress")] + InProgress, + #[serde(rename = "completed")] + Completed, + #[serde(rename = "failed")] + Failed, + #[serde(rename = "declined")] + Declined, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct CommandExecutionThreadItem { + /// The command's output, aggregated from stdout and stderr. + #[serde(rename = "aggregatedOutput")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub aggregated_output: Option, + /// The command to be executed. + pub command: String, + /// A best-effort parsing of the command to understand the action(s) it will perform. This returns a list of CommandAction objects because a single shell command may be composed of many commands piped together. + #[serde(rename = "commandActions")] + pub command_actions: Vec, + /// The command's working directory. + pub cwd: LegacyAppPathString, + /// The duration of the command execution in milliseconds. + #[serde(rename = "durationMs")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub duration_ms: Option, + /// The command's exit code. + #[serde(rename = "exitCode")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub exit_code: Option, + pub id: String, + /// Trusted first-party plugin id when this command resolves to one plugin script. + #[serde(rename = "pluginId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub plugin_id: Option, + /// Identifier for the underlying PTY process (when available). + #[serde(rename = "processId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub process_id: Option, + /// Safe plugin-relative path when this command resolves to one plugin script. + #[serde(rename = "scriptPath")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub script_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub source: Option, + pub status: CommandExecutionStatus, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ContextCompactionThreadItem { + pub id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct CreditsSnapshot { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub balance: Option, + #[serde(rename = "hasCredits")] + pub has_credits: bool, + pub unlimited: bool, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct DeletePatchChangeKind {} + +pub type DynamicToolCallOutputContentItem = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum DynamicToolCallStatus { + #[serde(rename = "inProgress")] + InProgress, + #[serde(rename = "completed")] + Completed, + #[serde(rename = "failed")] + Failed, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct DynamicToolCallThreadItem { + pub arguments: Value, + #[serde(rename = "contentItems")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub content_items: Option>, + /// The duration of the dynamic tool call in milliseconds. + #[serde(rename = "durationMs")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub duration_ms: Option, + pub id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + pub status: DynamicToolCallStatus, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub success: Option, + pub tool: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct EnteredReviewModeThreadItem { + pub id: String, + pub review: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ErrorNotification { + pub error: TurnError, + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "turnId")] + pub turn_id: String, + #[serde(rename = "willRetry")] + pub will_retry: bool, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ExitedReviewModeThreadItem { + pub id: String, + pub review: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum FileChangeApprovalDecision { + /// User approved the file changes. + #[serde(rename = "accept")] + Accept, + /// User approved the file changes and future changes to the same files should run without prompting. + #[serde(rename = "acceptForSession")] + AcceptForSession, + /// User denied the file changes. The agent will continue the turn. + #[serde(rename = "decline")] + Decline, + /// User denied the file changes. The turn will also be immediately interrupted. + #[serde(rename = "cancel")] + Cancel, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct FileChangeRequestApprovalParams { + /// \[UNSTABLE\] When set, the agent is asking the user to allow writes under this root for the remainder of the session (unclear if this is honored today). + #[serde(rename = "grantRoot")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub grant_root: Option, + #[serde(rename = "itemId")] + pub item_id: String, + /// Optional explanatory reason (e.g. request for extra write access). + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reason: Option, + /// Unix timestamp (in milliseconds) when this approval request started. + #[serde(rename = "startedAtMs")] + pub started_at_ms: i64, + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "turnId")] + pub turn_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FileChangeRequestApprovalResponse { + pub decision: FileChangeApprovalDecision, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FileChangeThreadItem { + pub changes: Vec, + pub id: String, + pub status: PatchApplyStatus, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FileUpdateChange { + pub diff: String, + pub kind: PatchChangeKind, + pub path: String, +} + +pub type FunctionCallOutputBody = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FunctionCallOutputThreadItem { + pub id: String, + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + pub output: FunctionCallOutputBody, +} + +pub type GitInfo = Value; + +pub type HookPromptFragment = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct HookPromptThreadItem { + pub fragments: Vec, + pub id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ImageDetail { + #[serde(rename = "auto")] + Auto, + #[serde(rename = "low")] + Low, + #[serde(rename = "high")] + High, + #[serde(rename = "original")] + Original, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(tag = "type")] +pub enum ImageGenerationFailure { + #[serde(rename = "usageLimitExceeded")] + UsageLimitExceeded(UsageLimitExceededImageGenerationFailure), + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ImageGenerationThreadItem { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub failure: Option, + pub id: String, + pub result: String, + #[serde(rename = "revisedPrompt")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub revised_prompt: Option, + #[serde(rename = "savedPath")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub saved_path: Option, + pub status: String, + #[serde(rename = "transparentBackground")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub transparent_background: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ImageUserInput { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub detail: Option, + #[serde(rename = "fileId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub file_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub url: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ImageViewThreadItem { + pub id: String, + pub path: LegacyAppPathString, +} + +/// Client-declared capabilities negotiated during initialize. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct InitializeCapabilities { + /// Opt into receiving experimental API methods and fields. + #[serde(rename = "experimentalApi")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub experimental_api: Option, + /// Use explicit gateway OAuth login instead of automatic browser authorization. Applies to this app-server's gateway runtime; later connections cannot undo it. + #[serde(rename = "explicitGatewayOauth")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub explicit_gateway_oauth: Option, + /// MCP extension settings declared by the app-server client. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub extensions: Option>, + /// Legacy opt-in for the `openai/form` MCP extension. + /// + /// New clients should declare `openai/form` in [`Self::extensions`]. + #[serde(rename = "mcpServerOpenaiFormElicitation")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mcp_server_openai_form_elicitation: Option, + /// Exact notification method names that should be suppressed for this connection (for example `thread/started`). + #[serde(rename = "optOutNotificationMethods")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub opt_out_notification_methods: Option>, + /// Opt into `attestation/generate` requests for upstream `x-oai-attestation`. + #[serde(rename = "requestAttestation")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub request_attestation: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct InitializeParams { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub capabilities: Option, + #[serde(rename = "clientInfo")] + pub client_info: ClientInfo, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct InitializeResponse { + /// Absolute path to the server's $CODEX_HOME directory. + #[serde(rename = "codexHome")] + pub codex_home: AbsolutePathBuf, + /// Platform family for the running app-server target, for example `"unix"` or `"windows"`. + #[serde(rename = "platformFamily")] + pub platform_family: String, + /// Operating system for the running app-server target, for example `"macos"`, `"linux"`, or `"windows"`. + #[serde(rename = "platformOs")] + pub platform_os: String, + #[serde(rename = "userAgent")] + pub user_agent: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ItemCompletedNotification { + /// Unix timestamp (in milliseconds) when this item lifecycle completed. + #[serde(rename = "completedAtMs")] + pub completed_at_ms: i64, + pub item: ThreadItem, + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "turnId")] + pub turn_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ItemStartedNotification { + pub item: ThreadItem, + /// Unix timestamp (in milliseconds) when this item lifecycle started. + #[serde(rename = "startedAtMs")] + pub started_at_ms: i64, + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "turnId")] + pub turn_id: String, +} + +pub type LegacyAppPathString = String; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct LocalAudioUserInput { + pub path: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct LocalImageUserInput { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub detail: Option, + pub path: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum McpAppDisplayMode { + #[serde(rename = "inline")] + Inline, + #[serde(rename = "fullscreen")] + Fullscreen, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +/// UI resource and display preference for model invocations, captured from the tool descriptor. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct McpAppUi { + #[serde(rename = "preferredModelDisplayMode")] + pub preferred_model_display_mode: McpAppDisplayMode, + #[serde(rename = "resourceUri")] + pub resource_uri: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum McpServerElicitationAction { + #[serde(rename = "accept")] + Accept, + #[serde(rename = "decline")] + Decline, + #[serde(rename = "cancel")] + Cancel, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +pub type McpServerElicitationRequestParams = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct McpServerElicitationRequestResponse { + /// Optional client metadata for form-mode action handling. + #[serde(rename = "_meta")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub meta: Option, + pub action: McpServerElicitationAction, + /// Structured user input for accepted elicitations, mirroring RMCP `CreateElicitationResult`. + /// + /// This is nullable because decline/cancel responses have no content. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub content: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct McpToolCallAppContext { + #[serde(rename = "actionName")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub action_name: Option, + #[serde(rename = "appName")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub app_name: Option, + #[serde(rename = "connectorId")] + pub connector_id: String, + #[serde(rename = "linkId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub link_id: Option, + #[serde(rename = "resourceUri")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resource_uri: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct McpToolCallError { + pub message: String, +} + +pub type McpToolCallResult = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum McpToolCallStatus { + #[serde(rename = "inProgress")] + InProgress, + #[serde(rename = "completed")] + Completed, + #[serde(rename = "failed")] + Failed, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct McpToolCallThreadItem { + #[serde(rename = "appContext")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub app_context: Option, + pub arguments: Value, + /// The duration of the MCP tool call in milliseconds. + #[serde(rename = "durationMs")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub duration_ms: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub error: Option, + pub id: String, + /// Legacy compatibility field; prefer `mcpAppUi.resourceUri` when available. + #[serde(rename = "mcpAppResourceUri")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mcp_app_resource_uri: Option, + /// Presentation captured from the invoked descriptor; absent in older history. + #[serde(rename = "mcpAppUi")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mcp_app_ui: Option, + #[serde(rename = "pluginId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub plugin_id: Option, + #[serde(rename = "readOnlyHint")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub read_only_hint: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub result: Option, + pub server: String, + pub status: McpToolCallStatus, + pub tool: String, +} + +pub type MemoryCitation = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct MentionUserInput { + pub name: String, + pub path: String, +} + +/// Classifies an assistant message as interim commentary or final answer text. +/// +/// Providers do not emit this consistently, so callers must treat `None` as "phase unknown" and keep compatibility behavior for legacy models. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum MessagePhase { + /// Mid-turn assistant text (for example preamble/progress narration). + /// + /// Additional tool calls or assistant output may follow before turn completion. + #[serde(rename = "commentary")] + Commentary, + /// The assistant's terminal answer text for the current turn. + #[serde(rename = "final_answer")] + FinalAnswer, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct MisalignmentErrorDetails { + /// A substantive localized explanation is required before offering continuation. + #[serde(rename = "detailedExplanation")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub detailed_explanation: Option, + /// Open-ended classification; clients must accept categories added by Responses. + #[serde(rename = "errorType")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub error_type: Option, + /// Instruction to submit as the next turn's user input if continuation is confirmed. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub steer: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct MisalignmentSteer { + pub message: String, +} + +/// Initial collaboration mode to use when the TUI starts. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ModeKind { + #[serde(rename = "plan")] + Plan, + #[serde(rename = "default")] + Default, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct NetworkApprovalContext { + pub host: String, + pub protocol: NetworkApprovalProtocol, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum NetworkApprovalProtocol { + #[serde(rename = "http")] + Http, + #[serde(rename = "https")] + Https, + #[serde(rename = "socks5Tcp")] + Socks5Tcp, + #[serde(rename = "socks5Udp")] + Socks5Udp, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +pub type NetworkPolicyAmendment = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum NonSteerableTurnKind { + #[serde(rename = "review")] + Review, + #[serde(rename = "compact")] + Compact, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum PatchApplyStatus { + #[serde(rename = "inProgress")] + InProgress, + #[serde(rename = "completed")] + Completed, + #[serde(rename = "failed")] + Failed, + #[serde(rename = "declined")] + Declined, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(tag = "type")] +pub enum PatchChangeKind { + #[serde(rename = "add")] + Add(AddPatchChangeKind), + #[serde(rename = "delete")] + Delete(DeletePatchChangeKind), + #[serde(rename = "update")] + Update(UpdatePatchChangeKind), + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +/// Deprecated: `friendly` and `pragmatic` no longer select a style. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum Personality { + #[serde(rename = "none")] + None, + #[serde(rename = "friendly")] + Friendly, + #[serde(rename = "pragmatic")] + Pragmatic, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct PlanThreadItem { + pub id: String, + pub text: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum PlanType { + #[serde(rename = "free")] + Free, + #[serde(rename = "go")] + Go, + #[serde(rename = "plus")] + Plus, + #[serde(rename = "pro")] + Pro, + #[serde(rename = "prolite")] + Prolite, + #[serde(rename = "promax")] + Promax, + #[serde(rename = "team")] + Team, + #[serde(rename = "self_serve_business_prolite")] + SelfServeBusinessProlite, + #[serde(rename = "self_serve_business_usage_based")] + SelfServeBusinessUsageBased, + #[serde(rename = "business")] + Business, + #[serde(rename = "ent26")] + Ent26, + #[serde(rename = "enterprise_cbp_automation")] + EnterpriseCbpAutomation, + #[serde(rename = "enterprise_cbp_usage_based")] + EnterpriseCbpUsageBased, + #[serde(rename = "enterprise")] + Enterprise, + #[serde(rename = "edu")] + Edu, + #[serde(rename = "edu_plus")] + EduPlus, + #[serde(rename = "edu_pro")] + EduPro, + #[serde(rename = "unknown")] + Unknown, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + UnknownValue(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum RateLimitReachedType { + #[serde(rename = "rate_limit_reached")] + RateLimitReached, + #[serde(rename = "workspace_owner_credits_depleted")] + WorkspaceOwnerCreditsDepleted, + #[serde(rename = "workspace_member_credits_depleted")] + WorkspaceMemberCreditsDepleted, + #[serde(rename = "workspace_owner_usage_limit_reached")] + WorkspaceOwnerUsageLimitReached, + #[serde(rename = "workspace_member_usage_limit_reached")] + WorkspaceMemberUsageLimitReached, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct RateLimitSnapshot { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub credits: Option, + #[serde(rename = "individualLimit")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub individual_limit: Option, + #[serde(rename = "limitId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limit_id: Option, + #[serde(rename = "limitName")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub limit_name: Option, + /// Normal model whose display name and reasoning options describe this quota alias. + #[serde(rename = "normalModelSlug")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub normal_model_slug: Option, + #[serde(rename = "planType")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub plan_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub primary: Option, + #[serde(rename = "rateLimitReachedType")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub rate_limit_reached_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub secondary: Option, + /// Backend-reported spend-control state. `None` is unavailable, not a sparse-update recovery. + #[serde(rename = "spendControlReached")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub spend_control_reached: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct RateLimitWindow { + #[serde(rename = "resetsAt")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resets_at: Option, + #[serde(rename = "usedPercent")] + pub used_percent: i64, + #[serde(rename = "windowDurationMins")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub window_duration_mins: Option, +} + +/// A non-empty reasoning effort value advertised by the model. +pub type ReasoningEffort = String; + +/// A summary of the reasoning performed by the model. This can be useful for debugging and understanding the model's reasoning process. See +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ReasoningSummary { + #[serde(rename = "auto")] + Auto, + #[serde(rename = "concise")] + Concise, + #[serde(rename = "detailed")] + Detailed, + /// Option to disable reasoning summaries. + #[serde(rename = "none")] + None, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ReasoningThreadItem { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub content: Option>, + pub id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub summary: Option>, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum SandboxMode { + #[serde(rename = "read-only")] + ReadOnly, + #[serde(rename = "workspace-write")] + WorkspaceWrite, + #[serde(rename = "danger-full-access")] + DangerFullAccess, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +pub type SandboxPolicy = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum SessionSource { + #[serde(rename = "cli")] + Cli, + #[serde(rename = "vscode")] + Vscode, + #[serde(rename = "exec")] + Exec, + #[serde(rename = "appServer")] + AppServer, + #[serde(rename = "unknown")] + Unknown, + #[serde(rename = "custom")] + Custom(String), + #[serde(rename = "subAgent")] + SubAgent(SubAgentSource), + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + UnknownValue(Value), +} + +/// Settings for a collaboration mode. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct Settings { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub developer_instructions: Option, + pub model: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reasoning_effort: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct SkillUserInput { + pub name: String, + pub path: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct SleepThreadItem { + #[serde(rename = "durationMs")] + pub duration_ms: u64, + pub id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct SpendControlLimitSnapshot { + pub limit: String, + #[serde(rename = "remainingPercent")] + pub remaining_percent: i64, + #[serde(rename = "resetsAt")] + pub resets_at: i64, + pub used: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum SubAgentActivityKind { + #[serde(rename = "started")] + Started, + #[serde(rename = "interacted")] + Interacted, + #[serde(rename = "interrupted")] + Interrupted, + #[serde(rename = "completed")] + Completed, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct SubAgentActivityThreadItem { + #[serde(rename = "agentPath")] + pub agent_path: String, + #[serde(rename = "agentThreadId")] + pub agent_thread_id: String, + pub id: String, + pub kind: SubAgentActivityKind, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum SubAgentSource { + #[serde(rename = "review")] + Review, + #[serde(rename = "compact")] + Compact, + #[serde(rename = "memory_consolidation")] + MemoryConsolidation, + #[serde(rename = "thread_spawn")] + ThreadSpawn(SubAgentSourceThreadSpawn), + #[serde(rename = "other")] + Other(String), + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct SubAgentSourceThreadSpawn { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub agent_nickname: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub agent_path: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub agent_role: Option, + pub depth: i64, + pub parent_thread_id: ThreadId, +} + +pub type TextElement = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct TextUserInput { + pub text: String, + /// UI-defined spans within `text` used to render or persist special elements. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub text_elements: Option>, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Thread { + /// Optional random unique nickname assigned to an AgentControl-spawned sub-agent. + #[serde(rename = "agentNickname")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub agent_nickname: Option, + /// Optional role (agent_role) assigned to an AgentControl-spawned sub-agent. + #[serde(rename = "agentRole")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub agent_role: Option, + /// Version of the CLI that created the thread. + #[serde(rename = "cliVersion")] + pub cli_version: String, + /// Unix timestamp (in seconds) when the thread was created. + #[serde(rename = "createdAt")] + pub created_at: i64, + /// Working directory captured for the thread. + pub cwd: AbsolutePathBuf, + /// Whether the thread is ephemeral and should not be materialized on disk. + pub ephemeral: bool, + /// Source thread id when this thread was created by forking another thread. + #[serde(rename = "forkedFromId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub forked_from_id: Option, + /// Optional Git metadata captured when the thread was created. + #[serde(rename = "gitInfo")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub git_info: Option, + /// Persisted thread history contract selected when this thread was created. + #[serde(rename = "historyMode")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub history_mode: Option, + /// Identifier for this thread. Codex-generated thread IDs are UUIDv7. + pub id: String, + /// Current configured model when loaded, otherwise the latest persisted model. Null when unavailable. This is not per-turn execution telemetry. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model: Option, + /// Model provider used for this thread (for example, 'openai'). + #[serde(rename = "modelProvider")] + pub model_provider: String, + /// Optional user-facing thread title. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub name: Option, + /// Originator recorded when the thread was created, independent of its current client or executor. Null when the recorded originator is unavailable. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub originator: Option, + /// The ID of the parent thread. This will only be set if this thread is a subagent. + #[serde(rename = "parentThreadId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub parent_thread_id: Option, + /// \[UNSTABLE\] Path to the thread on disk. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub path: Option, + /// Usually the first user message in the thread, if available. + pub preview: String, + /// Canonical project assignment owned by app-server, if any. + #[serde(rename = "projectId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub project_id: Option, + /// Current configured reasoning effort when loaded, otherwise the latest persisted effort. Null when unset or unavailable. This is not per-turn execution telemetry. + #[serde(rename = "reasoningEffort")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reasoning_effort: Option, + /// Unix timestamp (in seconds) used for thread recency ordering. + #[serde(rename = "recencyAt")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub recency_at: Option, + /// The independently persisted section selected for this thread, if any. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub section: Option, + /// Unix timestamp in seconds when the thread entered its current section. + #[serde(rename = "sectionEnteredAt")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub section_entered_at: Option, + /// Session id shared by threads that belong to the same session tree. + #[serde(rename = "sessionId")] + pub session_id: String, + /// Origin of the thread (CLI, VSCode, codex exec, codex app-server, etc.). + pub source: SessionSource, + /// Current runtime status for the thread. + pub status: ThreadStatus, + /// Optional analytics source classification for this thread. + #[serde(rename = "threadSource")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub thread_source: Option, + /// Only populated on `thread/resume`, `thread/fork`, and `thread/read` (when `includeTurns` is true) responses. For all other responses and notifications returning a Thread, the turns field will be an empty list. + pub turns: Vec, + /// Unix timestamp (in seconds) when the thread was last updated. + #[serde(rename = "updatedAt")] + pub updated_at: i64, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ThreadHistoryMode { + #[serde(rename = "legacy")] + Legacy, + #[serde(rename = "paginated")] + Paginated, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +pub type ThreadId = String; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(tag = "type")] +pub enum ThreadItem { + #[serde(rename = "userMessage")] + UserMessage(UserMessageThreadItem), + #[serde(rename = "hookPrompt")] + HookPrompt(HookPromptThreadItem), + #[serde(rename = "agentMessage")] + AgentMessage(AgentMessageThreadItem), + #[serde(rename = "functionCallOutput")] + FunctionCallOutput(FunctionCallOutputThreadItem), + /// EXPERIMENTAL - proposed plan item content. The completed plan item is authoritative and may not match the concatenation of `PlanDelta` text. + #[serde(rename = "plan")] + Plan(PlanThreadItem), + #[serde(rename = "reasoning")] + Reasoning(ReasoningThreadItem), + #[serde(rename = "commandExecution")] + CommandExecution(CommandExecutionThreadItem), + #[serde(rename = "fileChange")] + FileChange(FileChangeThreadItem), + #[serde(rename = "mcpToolCall")] + McpToolCall(McpToolCallThreadItem), + #[serde(rename = "dynamicToolCall")] + DynamicToolCall(DynamicToolCallThreadItem), + #[serde(rename = "collabAgentToolCall")] + CollabAgentToolCall(CollabAgentToolCallThreadItem), + #[serde(rename = "subAgentActivity")] + SubAgentActivity(SubAgentActivityThreadItem), + #[serde(rename = "webSearch")] + WebSearch(WebSearchThreadItem), + #[serde(rename = "imageView")] + ImageView(ImageViewThreadItem), + /// Display item emitted by the interruptible `clock.sleep` tool. + #[serde(rename = "sleep")] + Sleep(SleepThreadItem), + #[serde(rename = "imageGeneration")] + ImageGeneration(ImageGenerationThreadItem), + #[serde(rename = "enteredReviewMode")] + EnteredReviewMode(EnteredReviewModeThreadItem), + #[serde(rename = "exitedReviewMode")] + ExitedReviewMode(ExitedReviewModeThreadItem), + #[serde(rename = "contextCompaction")] + ContextCompaction(ContextCompactionThreadItem), + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +/// There are three ways to resume a thread: 1. By thread_id: load the thread from disk by thread_id and resume it. 2. By history: instantiate the thread from memory and resume it. 3. By path: load the thread from disk by path and resume it. +/// +/// For non-running threads, the precedence is: history > non-empty path > thread_id. If using history or a non-empty path for a non-running thread, the thread_id param will be ignored. +/// +/// If thread_id identifies a running thread, app-server rejoins that thread and treats a non-empty path as a consistency check against the active rollout path. Empty string path values are treated as absent. +/// +/// Prefer using thread_id whenever possible. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ThreadResumeParams { + #[serde(rename = "approvalPolicy")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub approval_policy: Option, + /// Override where approval requests are routed for review on this thread and subsequent turns. + #[serde(rename = "approvalsReviewer")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub approvals_reviewer: Option, + #[serde(rename = "baseInstructions")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub base_instructions: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub config: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cwd: Option, + #[serde(rename = "developerInstructions")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub developer_instructions: Option, + /// When true, return only thread metadata and live-resume state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after resuming. Full-history hydration is deprecated for paginated threads; use this with `thread/turns/list` and `thread/items/list` instead. + #[serde(rename = "excludeTurns")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub exclude_turns: Option, + /// Configuration overrides for the resumed thread, if any. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model: Option, + #[serde(rename = "modelProvider")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model_provider: Option, + /// @deprecated `friendly` and `pragmatic` no longer select a style. Changing this does not rewrite the thread's existing instructions. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub personality: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sandbox: Option, + #[serde(rename = "serviceTier")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub service_tier: Option, + #[serde(rename = "threadId")] + pub thread_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ThreadResumeResponse { + #[serde(rename = "approvalPolicy")] + pub approval_policy: AskForApproval, + /// Reviewer currently used for approval requests on this thread. + #[serde(rename = "approvalsReviewer")] + pub approvals_reviewer: ApprovalsReviewer, + /// Effective collaboration mode. Absent when resuming from an older server. + #[serde(rename = "collaborationMode")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub collaboration_mode: Option, + pub cwd: AbsolutePathBuf, + /// Saved list of disabled plugin IDs. Does not yet filter plugin capabilities. + #[serde(rename = "disabledPluginIds")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub disabled_plugin_ids: Option>, + /// Environment-native paths to instruction source files currently loaded for this thread. + #[serde(rename = "instructionSources")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub instruction_sources: Option>, + /// Opaque cursor for hydrating paginated items backwards. + /// + /// Pass this as `cursor` to `thread/items/list` with `sortDirection: "desc"`. The first page includes the item identified by the cursor. + #[serde(rename = "itemsBackwardsCursor")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub items_backwards_cursor: Option, + pub model: String, + #[serde(rename = "modelProvider")] + pub model_provider: String, + #[serde(rename = "reasoningEffort")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reasoning_effort: Option, + /// Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance. + pub sandbox: SandboxPolicy, + #[serde(rename = "serviceTier")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub service_tier: Option, + pub thread: Thread, + /// Opaque cursor for hydrating paginated turns backwards. + /// + /// Pass this as `cursor` to `thread/turns/list` with `sortDirection: "desc"`. The first page includes the turn identified by the cursor. + #[serde(rename = "turnsBackwardsCursor")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub turns_backwards_cursor: Option, +} + +/// An independently persisted, user-visible thread section. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ThreadSection { + /// Optional appearance synchronized across clients. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub appearance: Option, + /// Opaque UUIDv7 identity that remains stable when the section is renamed. + pub id: String, + /// The current user-visible section name. + pub name: String, +} + +/// Extensible visual presentation for a custom thread section. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ThreadSectionAppearance { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub color: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub icon: Option, +} + +pub type ThreadSource = String; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct ThreadStartParams { + #[serde(rename = "approvalPolicy")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub approval_policy: Option, + /// Override where approval requests are routed for review on this thread and subsequent turns. + #[serde(rename = "approvalsReviewer")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub approvals_reviewer: Option, + #[serde(rename = "baseInstructions")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub base_instructions: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub config: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cwd: Option, + #[serde(rename = "developerInstructions")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub developer_instructions: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ephemeral: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model: Option, + #[serde(rename = "modelProvider")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model_provider: Option, + /// @deprecated `friendly` and `pragmatic` no longer select a style. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub personality: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sandbox: Option, + #[serde(rename = "serviceName")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub service_name: Option, + #[serde(rename = "serviceTier")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub service_tier: Option, + #[serde(rename = "sessionStartSource")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub session_start_source: Option, + /// Optional client-supplied analytics source classification for this thread. + #[serde(rename = "threadSource")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub thread_source: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ThreadStartResponse { + #[serde(rename = "approvalPolicy")] + pub approval_policy: AskForApproval, + /// Reviewer currently used for approval requests on this thread. + #[serde(rename = "approvalsReviewer")] + pub approvals_reviewer: ApprovalsReviewer, + pub cwd: AbsolutePathBuf, + /// Saved list of disabled plugin IDs. Does not yet filter plugin capabilities. + #[serde(rename = "disabledPluginIds")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub disabled_plugin_ids: Option>, + /// Environment-native paths to instruction source files currently loaded for this thread. + #[serde(rename = "instructionSources")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub instruction_sources: Option>, + pub model: String, + #[serde(rename = "modelProvider")] + pub model_provider: String, + #[serde(rename = "reasoningEffort")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub reasoning_effort: Option, + /// Legacy sandbox policy retained for compatibility. Experimental clients should prefer `activePermissionProfile` for profile provenance. + pub sandbox: SandboxPolicy, + #[serde(rename = "serviceTier")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub service_tier: Option, + pub thread: Thread, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ThreadStartSource { + #[serde(rename = "startup")] + Startup, + #[serde(rename = "clear")] + Clear, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ThreadStartedNotification { + pub thread: Thread, +} + +pub type ThreadStatus = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ThreadTokenUsage { + pub last: TokenUsageBreakdown, + #[serde(rename = "modelContextWindow")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model_context_window: Option, + pub total: TokenUsageBreakdown, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ThreadTokenUsageUpdatedNotification { + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "tokenUsage")] + pub token_usage: ThreadTokenUsage, + #[serde(rename = "turnId")] + pub turn_id: String, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct TokenUsageBreakdown { + #[serde(rename = "cacheWriteInputTokens")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cache_write_input_tokens: Option, + #[serde(rename = "cachedInputTokens")] + pub cached_input_tokens: i64, + #[serde(rename = "inputTokens")] + pub input_tokens: i64, + #[serde(rename = "outputTokens")] + pub output_tokens: i64, + #[serde(rename = "reasoningOutputTokens")] + pub reasoning_output_tokens: i64, + #[serde(rename = "totalTokens")] + pub total_tokens: i64, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Turn { + /// Unix timestamp (in seconds) when the turn completed. + #[serde(rename = "completedAt")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub completed_at: Option, + /// Duration between turn start and completion in milliseconds, if known. + #[serde(rename = "durationMs")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub duration_ms: Option, + /// Only populated when the Turn's status is failed. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub error: Option, + /// Identifier for this turn. Codex-generated turn IDs are UUIDv7. + pub id: String, + /// Thread items currently included in this turn payload. + pub items: Vec, + /// Describes how much of `items` has been loaded for this turn. + #[serde(rename = "itemsView")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub items_view: Option, + /// Unix timestamp (in seconds) when the turn started. + #[serde(rename = "startedAt")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub started_at: Option, + pub status: TurnStatus, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct TurnCompletedNotification { + #[serde(rename = "threadId")] + pub thread_id: String, + pub turn: Turn, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct TurnError { + #[serde(rename = "additionalDetails")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub additional_details: Option, + #[serde(rename = "codexErrorInfo")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub codex_error_info: Option, + pub message: String, + /// Optional public explanation and continuation instruction for a misalignment block. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub misalignment: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct TurnInterruptParams { + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "turnId")] + pub turn_id: String, +} + +pub type TurnInterruptResponse = BTreeMap; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum TurnItemsView { + /// `items` was not loaded for this turn. The field is intentionally empty. + #[serde(rename = "notLoaded")] + NotLoaded, + /// `items` contains only a display summary for this turn. + #[serde(rename = "summary")] + Summary, + /// `items` contains every ThreadItem available from persisted app-server history for this turn. + #[serde(rename = "full")] + Full, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct TurnStartParams { + /// Override the approval policy for this turn and subsequent turns. + #[serde(rename = "approvalPolicy")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub approval_policy: Option, + /// Override where approval requests are routed for review on this turn and subsequent turns. + #[serde(rename = "approvalsReviewer")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub approvals_reviewer: Option, + #[serde(rename = "clientUserMessageId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub client_user_message_id: Option, + /// Override the working directory for this turn and subsequent turns. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cwd: Option, + /// Replace this thread's disabled plugin IDs. Omitted/null preserves the list; \[\] clears it. + #[serde(rename = "disabledPluginIds")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub disabled_plugin_ids: Option>, + /// Override the reasoning effort for this turn and subsequent turns. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub effort: Option, + pub input: Vec, + /// Override the model for this turn and subsequent turns. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model: Option, + /// Optional JSON Schema used to constrain the final assistant message for this turn. + #[serde(rename = "outputSchema")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub output_schema: Option, + /// @deprecated `friendly` and `pragmatic` no longer select a style. Changing this does not rewrite the thread's existing instructions. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub personality: Option, + /// Override the sandbox policy for this turn and subsequent turns. + #[serde(rename = "sandboxPolicy")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub sandbox_policy: Option, + /// Override the service tier for this turn and subsequent turns. + #[serde(rename = "serviceTier")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub service_tier: Option, + /// Override the service tier only when this request starts a new turn. Use "default" for standard speed. Omitted or null inherits the thread's tier. Does not change the thread's tier or a turn being steered. + #[serde(rename = "serviceTierForTurn")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub service_tier_for_turn: Option, + /// Override the reasoning summary for this turn and subsequent turns. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub summary: Option, + #[serde(rename = "threadId")] + pub thread_id: String, + #[serde(rename = "toolOutput")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tool_output: Option, + /// Optional source classification for the caller that starts this turn. Ignored when this request steers an already-active turn. + #[serde(rename = "turnTrigger")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub turn_trigger: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct TurnStartResponse { + pub turn: Turn, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct TurnStartedNotification { + #[serde(rename = "threadId")] + pub thread_id: String, + pub turn: Turn, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum TurnStatus { + #[serde(rename = "completed")] + Completed, + #[serde(rename = "interrupted")] + Interrupted, + #[serde(rename = "failed")] + Failed, + #[serde(rename = "inProgress")] + InProgress, + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct TurnToolOutput { + pub name: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub namespace: Option, + pub output: FunctionCallOutputBody, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct UpdatePatchChangeKind { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub move_path: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct UsageLimitExceededImageGenerationFailure { + #[serde(rename = "limitId")] + pub limit_id: String, + #[serde(rename = "resetsAt")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub resets_at: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(tag = "type")] +pub enum UserInput { + #[serde(rename = "text")] + Text(TextUserInput), + #[serde(rename = "image")] + Image(ImageUserInput), + #[serde(rename = "localImage")] + LocalImage(LocalImageUserInput), + #[serde(rename = "audio")] + Audio(AudioUserInput), + #[serde(rename = "localAudio")] + LocalAudio(LocalAudioUserInput), + #[serde(rename = "skill")] + Skill(SkillUserInput), + #[serde(rename = "mention")] + Mention(MentionUserInput), + /// A value this Codex version doesn't know, or a known one whose body didn't decode. + #[serde(untagged)] + Unknown(Value), +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct UserMessageThreadItem { + #[serde(rename = "clientId")] + #[serde(default, skip_serializing_if = "Option::is_none")] + pub client_id: Option, + pub content: Vec, + pub id: String, +} + +pub type WebSearchAction = Value; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)] +pub struct WebSearchThreadItem { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub action: Option, + pub id: String, + pub query: String, + /// Structured search results returned out-of-band by standalone web search. + /// + /// These stay as opaque JSON at the extension/app-server boundary so new result fields and result types can pass through without a Codex release. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub results: Option>, +} diff --git a/src/rpc.rs b/src/rpc.rs new file mode 100644 index 0000000..fa08219 --- /dev/null +++ b/src/rpc.rs @@ -0,0 +1,205 @@ +//! JSON-RPC framing for the app-server: one JSON object per line, no +//! `"jsonrpc"` member (Codex leaves it out). Requests go both ways (the +//! server asks for approvals), so a line is one of four shapes. + +use serde_json::{Map, Value, json}; + +/// A request id: Codex uses integers, the protocol allows strings. +pub type RequestId = Value; + +/// One line from the server. +#[derive(Debug, Clone, PartialEq)] +pub enum Incoming { + /// The answer to one of our requests. + Response { id: RequestId, result: Value }, + /// One of our requests failed. + Error { id: RequestId, error: RpcError }, + /// The server asks us something (approvals); answer with [`response`]. + Request { + id: RequestId, + method: String, + params: Value, + }, + /// The server tells us something. + Notification { method: String, params: Value }, +} + +/// A JSON-RPC error object. +#[derive(Debug, Clone, PartialEq)] +pub struct RpcError { + pub code: i64, + pub message: String, + pub data: Option, +} + +impl core::fmt::Display for RpcError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{} (code {})", self.message, self.code) + } +} + +/// Parse one line. Blank lines are `Ok(None)`. +pub fn parse_line(line: &str) -> Result, String> { + let line = line.trim(); + if line.is_empty() { + return Ok(None); + } + let v: Value = serde_json::from_str(line).map_err(|e| format!("bad JSON-RPC line: {e}"))?; + let Value::Object(mut o) = v else { + return Err("JSON-RPC line is not an object".into()); + }; + let params = o.remove("params").unwrap_or(Value::Null); + let method = match o.remove("method") { + Some(Value::String(m)) => Some(m), + Some(_) => return Err("JSON-RPC method is not a string".into()), + None => None, + }; + let id = o.remove("id"); + Ok(Some(match (method, id) { + (Some(method), Some(id)) => Incoming::Request { id, method, params }, + (Some(method), None) => Incoming::Notification { method, params }, + (None, Some(id)) => { + if let Some(e) = o.remove("error") { + Incoming::Error { + id, + error: rpc_error(e), + } + } else { + Incoming::Response { + id, + result: o.remove("result").unwrap_or(Value::Null), + } + } + } + (None, None) => return Err("JSON-RPC line has neither method nor id".into()), + })) +} + +fn rpc_error(e: Value) -> RpcError { + let mut o = match e { + Value::Object(o) => o, + other => { + return RpcError { + code: 0, + message: other.to_string(), + data: None, + }; + } + }; + RpcError { + code: o.get("code").and_then(Value::as_i64).unwrap_or(0), + message: match o.remove("message") { + Some(Value::String(s)) => s, + Some(v) => v.to_string(), + None => String::new(), + }, + data: o.remove("data"), + } +} + +/// A request line (with its newline). +pub fn request(id: &RequestId, method: &str, params: &Value) -> String { + line(json!({ "id": id, "method": method, "params": params })) +} + +/// A notification line; `params` left out when `None`. +pub fn notification(method: &str, params: Option<&Value>) -> String { + let mut o = Map::new(); + o.insert("method".into(), method.into()); + if let Some(p) = params { + o.insert("params".into(), p.clone()); + } + line(Value::Object(o)) +} + +/// The answer to a server request. +pub fn response(id: &RequestId, result: &Value) -> String { + line(json!({ "id": id, "result": result })) +} + +/// An error answer to a server request. +pub fn error_response(id: &RequestId, code: i64, message: &str) -> String { + line(json!({ "id": id, "error": { "code": code, "message": message } })) +} + +fn line(v: Value) -> String { + let mut s = v.to_string(); + s.push('\n'); + s +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parses_the_four_shapes() { + let r = parse_line(r#"{"id":1,"result":{"userAgent":"x/1"}}"#).unwrap(); + assert_eq!( + r, + Some(Incoming::Response { + id: json!(1), + result: json!({"userAgent":"x/1"}) + }) + ); + let r = parse_line(r#"{"id":"a","error":{"code":-32600,"message":"no"}}"#).unwrap(); + assert_eq!( + r, + Some(Incoming::Error { + id: json!("a"), + error: RpcError { + code: -32600, + message: "no".into(), + data: None + } + }) + ); + let r = parse_line(r#"{"method":"item/commandExecution/requestApproval","id":0,"params":{"kind":"command"}}"#) + .unwrap(); + assert!( + matches!(r, Some(Incoming::Request { id, method, .. }) if id == json!(0) && method == "item/commandExecution/requestApproval") + ); + let r = + parse_line(r#"{"method":"turn/started","params":{"threadId":"t"},"emittedAtMs":1}"#) + .unwrap(); + assert!( + matches!(r, Some(Incoming::Notification { method, params }) if method == "turn/started" && params["threadId"] == "t") + ); + assert_eq!(parse_line(" \n").unwrap(), None); + assert!(parse_line("[1]").is_err()); + assert!(parse_line("{}").is_err()); + assert!(parse_line("{nope").is_err()); + } + + #[test] + fn writes_lines() { + assert_eq!( + request( + &json!(3), + "turn/interrupt", + &json!({"threadId":"t","turnId":"u"}) + ), + "{\"id\":3,\"method\":\"turn/interrupt\",\"params\":{\"threadId\":\"t\",\"turnId\":\"u\"}}\n" + ); + assert_eq!( + notification("initialized", None), + "{\"method\":\"initialized\"}\n" + ); + assert_eq!( + response(&json!(0), &json!({"decision":"decline"})), + "{\"id\":0,\"result\":{\"decision\":\"decline\"}}\n" + ); + let e = error_response(&json!(7), -32601, "unsupported"); + assert_eq!( + parse_line(&e).unwrap(), + Some(Incoming::Error { + id: json!(7), + error: RpcError { + code: -32601, + message: "unsupported".into(), + data: None + } + }) + ); + } +} diff --git a/tests/corpus.rs b/tests/corpus.rs new file mode 100644 index 0000000..02cd0ea --- /dev/null +++ b/tests/corpus.rs @@ -0,0 +1,115 @@ +//! Decode recorded `codex app-server` output with the generated protocol +//! types. `tests/corpus/` holds the server's side of real sessions (paths, +//! host names and ids scrubbed); a schema or generator change that stops +//! them decoding fails here. + +use codexwire::protocol::{ + CODEX_VERSION, ErrorNotification, InitializeResponse, ItemCompletedNotification, + ItemStartedNotification, Notification, ThreadItem, ThreadStartResponse, + ThreadStartedNotification, TurnCompletedNotification, TurnStartResponse, + TurnStartedNotification, +}; +use codexwire::rpc::{Incoming, parse_line}; +use serde::de::DeserializeOwned; +use serde_json::Value; + +const TURN: &str = include_str!("corpus/codex-0.158.0-turn-unauthenticated.jsonl"); + +fn decode(what: &str, v: Value) -> T { + serde_json::from_value(v).unwrap_or_else(|e| panic!("{what}: {e}")) +} + +fn known_item(what: &str, item: &ThreadItem) { + assert!( + !matches!(item, ThreadItem::Unknown(_)), + "{what}: the item fell back to Unknown: {item:?}" + ); +} + +/// Decode `params` as `T` if `method` is `T`'s; whether it was. +fn try_as(method: &str, params: &Value, check: impl Fn(&T)) -> bool { + if method != T::METHOD { + return false; + } + check(&decode::(method, params.clone())); + true +} + +#[test] +fn the_recorded_turn_decodes() { + let mut decoded = 0; + let mut other = Vec::new(); + for (n, line) in TURN.lines().enumerate() { + let what = format!("line {}", n + 1); + match parse_line(line).unwrap().unwrap() { + Incoming::Response { id, result } => match id.as_i64() { + Some(1) => { + let r: InitializeResponse = decode(&what, result); + assert_eq!( + codexwire::user_agent_version(&r.user_agent), + Some(CODEX_VERSION) + ); + assert_eq!(r.platform_family, "unix"); + } + Some(2) => { + let r: ThreadStartResponse = decode(&what, result); + assert_eq!(r.thread.turns.len(), 0); + } + Some(3) => { + let _: TurnStartResponse = decode(&what, result); + } + _ => panic!("{what}: unexpected answer {id}"), + }, + Incoming::Notification { method, params } => { + let known = try_as::(&method, ¶ms, |_| {}) + || try_as::(&method, ¶ms, |_| {}) + || try_as::(&method, ¶ms, |n| { + assert!(n.turn.error.is_some(), "{what}: the turn failed (no login)"); + }) + || try_as::(&method, ¶ms, |n| { + known_item(&what, &n.item); + }) + || try_as::(&method, ¶ms, |n| { + known_item(&what, &n.item); + }) + || try_as::(&method, ¶ms, |n| { + assert_ne!(n.error.message, ""); + }); + if known { + decoded += 1; + } else { + other.push(method); + } + } + m => panic!("{what}: unexpected {m:?}"), + } + } + assert!(decoded >= 15, "decoded {decoded}"); + // The notifications codexwire has no type for yet. + other.sort(); + other.dedup(); + assert_eq!( + other, + [ + "remoteControl/status/changed", + "thread/status/changed", + "warning" + ] + ); +} + +#[test] +fn an_item_of_a_newer_codex_is_unknown() { + let v = serde_json::json!({"type": "brandNew", "id": "i1"}); + assert_eq!( + serde_json::from_value::(v.clone()).unwrap(), + ThreadItem::Unknown(v) + ); + // A known tag whose body doesn't decode is Unknown too (serde's + // untagged fallback): log Unknown items to see schema drift. + let broken = serde_json::json!({"type": "agentMessage"}); + assert!(matches!( + serde_json::from_value::(broken).unwrap(), + ThreadItem::Unknown(_) + )); +} diff --git a/tests/corpus/codex-0.158.0-turn-unauthenticated.jsonl b/tests/corpus/codex-0.158.0-turn-unauthenticated.jsonl new file mode 100644 index 0000000..5696142 --- /dev/null +++ b/tests/corpus/codex-0.158.0-turn-unauthenticated.jsonl @@ -0,0 +1,22 @@ +{"id":1,"result":{"userAgent":"example/0.158.0 (NixOS 26.11.0; x86_64) unknown (example; 0.1.0)","codexHome":"/home/user/.codex","platformFamily":"unix","platformOs":"linux"}} +{"method":"remoteControl/status/changed","params":{"status":"disabled","serverName":"host","installationId":"00000000-0000-4000-8000-000000000000","environmentId":null},"emittedAtMs":1793943124212} +{"id":2,"result":{"thread":{"id":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","environments":[{"environmentId":"local","cwd":"/home/user/work","runtimeWorkspaceRoots":["/home/user/work"]}],"extra":null,"sessionId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","forkedFromId":null,"parentThreadId":null,"preview":"","ephemeral":false,"section":null,"sectionEnteredAt":null,"projectId":null,"historyMode":"paginated","modelProvider":"openai","model":"gpt-6-astra","reasoningEffort":null,"createdAt":1793943124,"updatedAt":1793943124,"recencyAt":1793943124,"status":{"type":"idle"},"path":"/home/user/.codex/sessions/2026/11/06/rollout-2026-11-06T13-32-04-01a1af57-b8f5-7a60-8bc6-51c88e95ee2d.jsonl","cwd":"/home/user/work","cliVersion":"0.158.0","originator":"example","source":"vscode","canAcceptDirectInput":true,"threadSource":null,"agentNickname":null,"agentRole":null,"gitInfo":null,"name":null,"daybreakEnabled":null,"turns":[]},"model":"gpt-6-astra","modelProvider":"openai","serviceTier":null,"disabledPluginIds":[],"cwd":"/home/user/work","runtimeWorkspaceRoots":["/home/user/work"],"instructionSources":[],"approvalPolicy":"on-request","approvalsReviewer":"user","sandbox":{"type":"readOnly","networkAccess":false},"activePermissionProfile":{"id":":read-only","extends":null},"reasoningEffort":null,"multiAgentMode":"explicitRequestOnly"}} +{"method":"thread/started","params":{"thread":{"id":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","environments":[{"environmentId":"local","cwd":"/home/user/work","runtimeWorkspaceRoots":["/home/user/work"]}],"extra":null,"sessionId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","forkedFromId":null,"parentThreadId":null,"preview":"","ephemeral":false,"section":null,"sectionEnteredAt":null,"projectId":null,"historyMode":"paginated","modelProvider":"openai","model":"gpt-6-astra","reasoningEffort":null,"createdAt":1793943124,"updatedAt":1793943124,"recencyAt":1793943124,"status":{"type":"idle"},"path":"/home/user/.codex/sessions/2026/11/06/rollout-2026-11-06T13-32-04-01a1af57-b8f5-7a60-8bc6-51c88e95ee2d.jsonl","cwd":"/home/user/work","cliVersion":"0.158.0","originator":"example","source":"vscode","canAcceptDirectInput":true,"threadSource":null,"agentNickname":null,"agentRole":null,"gitInfo":null,"name":null,"daybreakEnabled":null,"turns":[]}},"emittedAtMs":1793943124224} +{"id":3,"result":{"turn":{"id":"01a1af57-b901-7f81-bbc9-bae05424af9c","items":[],"itemsView":"notLoaded","status":"inProgress","error":null,"startedAt":null,"completedAt":null,"durationMs":null}}} +{"method":"thread/status/changed","params":{"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","status":{"type":"active","activeFlags":[]}},"emittedAtMs":1793943124303} +{"method":"turn/started","params":{"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turn":{"id":"01a1af57-b901-7f81-bbc9-bae05424af9c","items":[],"itemsView":"notLoaded","status":"inProgress","error":null,"startedAt":1793943124,"completedAt":null,"durationMs":null}},"emittedAtMs":1793943124303} +{"method":"item/started","params":{"item":{"type":"userMessage","id":"01a1af57-b9cb-73f0-9f39-6ca05ba0ca11","clientId":null,"content":[{"type":"text","text":"say hi","text_elements":[]}]},"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c","startedAtMs":1793943124428},"emittedAtMs":1793943124428} +{"method":"item/completed","params":{"item":{"type":"userMessage","id":"01a1af57-b9cb-73f0-9f39-6ca05ba0ca11","clientId":null,"content":[{"type":"text","text":"say hi","text_elements":[]}]},"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c","completedAtMs":1793943124428},"emittedAtMs":1793943124430} +{"method":"error","params":{"error":{"message":"Reconnecting... 2/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: wss://api.openai.com/v1/responses, cf-ray: a561b7322acb5b7a-CGY","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943124835} +{"method":"error","params":{"error":{"message":"Reconnecting... 3/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: wss://api.openai.com/v1/responses, cf-ray: a561b735acd1fde2-SIN","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943125411} +{"method":"error","params":{"error":{"message":"Reconnecting... 4/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: wss://api.openai.com/v1/responses, cf-ray: a561b73b6fa82bcc-CGY","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943126316} +{"method":"error","params":{"error":{"message":"Reconnecting... 5/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: wss://api.openai.com/v1/responses, cf-ray: a561b746fc1dcdf5-SIN","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943128177} +{"method":"warning","params":{"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","message":"Falling back from WebSockets to HTTPS transport. unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: wss://api.openai.com/v1/responses, cf-ray: a561b75b7815576c-SIN"},"emittedAtMs":1793943131453} +{"method":"error","params":{"error":{"message":"Reconnecting... 1/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: a561b75c183f651c-CEB, request id: req_00000000000000000000000000000000","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943132314} +{"method":"error","params":{"error":{"message":"Reconnecting... 2/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: a561b7631ef9f8e0-SIN, request id: req_00000000000000000000000000000000","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943132939} +{"method":"error","params":{"error":{"message":"Reconnecting... 3/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: a561b7682decaf73-CGY, request id: req_00000000000000000000000000000000","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943134297} +{"method":"error","params":{"error":{"message":"Reconnecting... 4/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: a561b772cbc5271e-CEB, request id: req_00000000000000000000000000000000","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943135909} +{"method":"error","params":{"error":{"message":"Reconnecting... 5/5","codexErrorInfo":{"responseStreamDisconnected":{"httpStatusCode":401}},"additionalDetails":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: a561b7822c82e764-CGY, request id: req_00000000000000000000000000000000","misalignment":null},"willRetry":true,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943137919} +{"method":"thread/status/changed","params":{"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","status":{"type":"systemError"}},"emittedAtMs":1793943142050} +{"method":"error","params":{"error":{"message":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: a561b7992e7aaf73-CGY, request id: req_00000000000000000000000000000000","codexErrorInfo":{"httpConnectionFailed":{"httpStatusCode":401}},"additionalDetails":null,"misalignment":null},"willRetry":false,"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turnId":"01a1af57-b901-7f81-bbc9-bae05424af9c"},"emittedAtMs":1793943142050} +{"method":"turn/completed","params":{"threadId":"01a1af57-b8f5-7a60-8bc6-51c88e95ee2d","turn":{"id":"01a1af57-b901-7f81-bbc9-bae05424af9c","items":[],"itemsView":"notLoaded","status":"failed","error":{"message":"unexpected status 401 Unauthorized: Missing bearer or basic authentication in header, url: https://api.openai.com/v1/responses, cf-ray: a561b7992e7aaf73-CGY, request id: req_00000000000000000000000000000000","codexErrorInfo":{"httpConnectionFailed":{"httpStatusCode":401}},"additionalDetails":null,"misalignment":null},"startedAt":1793943124,"completedAt":1793943142,"durationMs":17828}},"emittedAtMs":1793943142059} diff --git a/tests/fake_codex b/tests/fake_codex new file mode 100755 index 0000000..246e1e5 --- /dev/null +++ b/tests/fake_codex @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +"""A stand-in for `codex app-server`, for tests/spawn.rs. + +It writes a line that isn't UTF-8 to stdout and to stderr, then answers +`initialize` like the real server and `fake/info` with what it was started +with (its args, cwd, environment and pid), until its stdin ends. +""" + +import json +import os +import sys + +if sys.argv[1:2] != ["app-server"]: + sys.exit("usage: fake_codex app-server [ARGS]") + +out = sys.stdout.buffer +err = sys.stderr.buffer +err.write(b"\xff\xfe not utf-8\nfake stderr ok\n") +err.flush() +out.write(b"\xff\xfe not utf-8\n") +out.flush() + + +def send(msg): + out.write(json.dumps(msg).encode() + b"\n") + out.flush() + + +for line in sys.stdin.buffer: + msg = json.loads(line) + if "id" not in msg: + continue + if msg["method"] == "initialize": + name = msg["params"]["clientInfo"]["name"] + result = { + "userAgent": f"{name}/0.158.0 (fake) unknown ({name}; 0.1.0)", + "codexHome": os.environ.get("CODEX_HOME", ""), + "platformFamily": "unix", + "platformOs": "linux", + } + elif msg["method"] == "fake/info": + result = { + "args": sys.argv[2:], + "cwd": os.getcwd(), + "env": dict(os.environ), + "pid": os.getpid(), + } + else: + send({"id": msg["id"], "error": {"code": -32601, "message": "unknown method"}}) + continue + send({"id": msg["id"], "result": result}) diff --git a/tests/spawn.rs b/tests/spawn.rs new file mode 100644 index 0000000..1dd4170 --- /dev/null +++ b/tests/spawn.rs @@ -0,0 +1,103 @@ +//! `spawn_app_server` against a fake `codex` (`tests/fake_codex`, python3): +//! the args, the cwd, the allowlisted environment, both readers past a +//! line that isn't UTF-8, and the kill on drop. + +// `#[tokio::test]` expands to `block_on`. +#![allow(clippy::disallowed_methods)] + +use core::time::Duration; + +use codexwire::client::{ENV_ALLOW, ServerMessage, spawn_app_server}; +use codexwire::protocol::{CODEX_VERSION, ClientInfo, InitializeParams}; +use serde_json::{Value, json}; + +const FAKE: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/fake_codex"); + +async fn within(f: F) -> F::Output { + tokio::time::timeout(Duration::from_secs(10), f) + .await + .expect("hung") +} + +#[tokio::test] +async fn spawns_the_app_server() { + let cwd = tempfile::tempdir().unwrap(); + let env = [("CODEX_HOME".to_owned(), "/s/codex".to_owned())]; + let mut server = spawn_app_server(FAKE, &["--flag".to_owned()], &env, cwd.path()).unwrap(); + + // Its first line isn't UTF-8: reported, and the connection goes on. + assert!(matches!( + within(server.messages.recv()).await, + Some(ServerMessage::Malformed(e)) if e.contains("UTF-8") + )); + let init = within(server.client.request(&InitializeParams { + capabilities: None, + client_info: ClientInfo { + name: "test".into(), + title: None, + version: "0.1.0".into(), + }, + })) + .await + .unwrap(); + assert_eq!( + codexwire::user_agent_version(&init.user_agent), + Some(CODEX_VERSION) + ); + assert_eq!(init.codex_home, "/s/codex"); + + let info = within(server.client.call("fake/info", &json!({}))) + .await + .unwrap(); + assert_eq!(info["args"], json!(["--flag"])); + assert_eq!( + std::path::Path::new(info["cwd"].as_str().unwrap()), + cwd.path().canonicalize().unwrap() + ); + let Value::Object(child_env) = &info["env"] else { + panic!("env: {info}") + }; + for k in child_env.keys() { + assert!( + ENV_ALLOW.contains(&k.as_str()) || k == "CODEX_HOME", + "{k} reached the child" + ); + } + assert_eq!(child_env["CODEX_HOME"], "/s/codex"); + + // Its stderr: the line that isn't UTF-8 kept lossily, and the next. + within(async { + while !server.stderr.text().contains("fake stderr ok") { + tokio::time::sleep(Duration::from_millis(10)).await; + } + }) + .await; + assert!( + server + .stderr + .text() + .starts_with("\u{fffd}\u{fffd} not utf-8\n") + ); + + // Dropped: killed. + let pid = info["pid"].as_u64().unwrap(); + drop(server); + within(async { + while alive(pid) { + tokio::time::sleep(Duration::from_millis(10)).await; + } + }) + .await; +} + +/// Whether `pid` runs (a zombie, killed and not yet reaped, doesn't). +fn alive(pid: u64) -> bool { + match std::fs::read_to_string(format!("/proc/{pid}/stat")) { + // `pid (comm) state ...` + Ok(stat) => stat + .rsplit_once(") ") + .is_some_and(|(_, rest)| !rest.starts_with('Z')), + // No /proc (not Linux): a zombie can't be told apart; assume gone. + Err(_) => false, + } +}