diff --git a/sdk/python-runtime/README.md b/sdk/python-runtime/README.md new file mode 100644 index 0000000000..0e7b26d5fc --- /dev/null +++ b/sdk/python-runtime/README.md @@ -0,0 +1,9 @@ +# Codex CLI Runtime for Python SDK + +Platform-specific runtime package consumed by the published `codex-app-server-sdk`. + +This package is staged during release so the SDK can pin an exact Codex CLI +version without checking platform binaries into the repo. + +`codex-cli-bin` is intentionally wheel-only. Do not build or publish an sdist +for this package. diff --git a/sdk/python-runtime/hatch_build.py b/sdk/python-runtime/hatch_build.py new file mode 100644 index 0000000000..319e6973fb --- /dev/null +++ b/sdk/python-runtime/hatch_build.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + + +class RuntimeBuildHook(BuildHookInterface): + def initialize(self, version: str, build_data: dict[str, object]) -> None: + del version + if self.target_name == "sdist": + raise RuntimeError( + "codex-cli-bin is wheel-only; build and publish platform wheels only." + ) + + build_data["pure_python"] = False + build_data["infer_tag"] = True diff --git a/sdk/python-runtime/pyproject.toml b/sdk/python-runtime/pyproject.toml new file mode 100644 index 0000000000..761dccbb9f --- /dev/null +++ b/sdk/python-runtime/pyproject.toml @@ -0,0 +1,45 @@ +[build-system] +requires = ["hatchling>=1.24.0"] +build-backend = "hatchling.build" + +[project] +name = "codex-cli-bin" +version = "0.0.0-dev" +description = "Pinned Codex CLI runtime for the Python SDK" +readme = "README.md" +requires-python = ">=3.10" +license = { text = "Apache-2.0" } +authors = [{ name = "OpenAI" }] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] + +[project.urls] +Homepage = "https://github.com/openai/codex" +Repository = "https://github.com/openai/codex" +Issues = "https://github.com/openai/codex/issues" + +[tool.hatch.build] +exclude = [ + ".venv/**", + ".pytest_cache/**", + "dist/**", + "build/**", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/codex_cli_bin"] +include = ["src/codex_cli_bin/bin/**"] + +[tool.hatch.build.targets.wheel.hooks.custom] + +[tool.hatch.build.targets.sdist] + +[tool.hatch.build.targets.sdist.hooks.custom] diff --git a/sdk/python-runtime/src/codex_cli_bin/__init__.py b/sdk/python-runtime/src/codex_cli_bin/__init__.py new file mode 100644 index 0000000000..8059d39211 --- /dev/null +++ b/sdk/python-runtime/src/codex_cli_bin/__init__.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +import os +from pathlib import Path + +PACKAGE_NAME = "codex-cli-bin" + + +def bundled_codex_path() -> Path: + exe = "codex.exe" if os.name == "nt" else "codex" + path = Path(__file__).resolve().parent / "bin" / exe + if not path.is_file(): + raise FileNotFoundError( + f"{PACKAGE_NAME} is installed but missing its packaged codex binary at {path}" + ) + return path + + +__all__ = ["PACKAGE_NAME", "bundled_codex_path"] diff --git a/sdk/python/README.md b/sdk/python/README.md index 1fa2e5a882..ef3abdf630 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -11,6 +11,10 @@ cd sdk/python python -m pip install -e . ``` +Published SDK builds pin an exact `codex-cli-bin` runtime dependency. For local +repo development, pass `AppServerConfig(codex_bin=...)` to point at a local +build explicitly. + ## Quickstart ```python @@ -40,33 +44,45 @@ python examples/01_quickstart_constructor/sync.py python examples/01_quickstart_constructor/async.py ``` -## Bundled runtime binaries (out of the box) +## Runtime packaging -The SDK ships with platform-specific bundled binaries, so end users do not need updater scripts. +The repo no longer checks `codex` binaries into `sdk/python`. -Runtime binary source (single source, no fallback): +Published SDK builds are pinned to an exact `codex-cli-bin` package version, +and that runtime package carries the platform-specific binary for the target +wheel. -- `src/codex_app_server/bin/darwin-arm64/codex` -- `src/codex_app_server/bin/darwin-x64/codex` -- `src/codex_app_server/bin/linux-arm64/codex` -- `src/codex_app_server/bin/linux-x64/codex` -- `src/codex_app_server/bin/windows-arm64/codex.exe` -- `src/codex_app_server/bin/windows-x64/codex.exe` +For local repo development, the checked-in `sdk/python-runtime` package is only +a template for staged release artifacts. Editable installs should use an +explicit `codex_bin` override instead. -## Maintainer workflow (refresh binaries/types) +## Maintainer workflow ```bash cd sdk/python -python scripts/update_sdk_artifacts.py --channel stable --bundle-all-platforms -# or -python scripts/update_sdk_artifacts.py --channel alpha --bundle-all-platforms +python scripts/update_sdk_artifacts.py generate-types +python scripts/update_sdk_artifacts.py \ + stage-sdk \ + /tmp/codex-python-release/codex-app-server-sdk \ + --runtime-version 1.2.3 +python scripts/update_sdk_artifacts.py \ + stage-runtime \ + /tmp/codex-python-release/codex-cli-bin \ + /path/to/codex \ + --runtime-version 1.2.3 ``` -This refreshes all bundled OS/arch binaries and regenerates protocol-derived Python types. +This supports the CI release flow: + +- run `generate-types` before packaging +- stage `codex-app-server-sdk` once with an exact `codex-cli-bin==...` dependency +- stage `codex-cli-bin` on each supported platform runner with the same pinned runtime version +- build and publish `codex-cli-bin` as platform wheels only; do not publish an sdist ## Compatibility and versioning - Package: `codex-app-server-sdk` +- Runtime package: `codex-cli-bin` - Current SDK version in this repo: `0.2.0` - Python: `>=3.10` - Target protocol: Codex `app-server` JSON-RPC v2 diff --git a/sdk/python/docs/faq.md b/sdk/python/docs/faq.md index 410c210b27..ebfd2ddad2 100644 --- a/sdk/python/docs/faq.md +++ b/sdk/python/docs/faq.md @@ -33,15 +33,27 @@ Use `thread(...)` for simple continuation. Use `thread_resume(...)` when you nee Common causes: -- bundled runtime binary missing for your OS/arch under `src/codex_app_server/bin/*` +- published runtime package (`codex-cli-bin`) is not installed +- local `codex_bin` override points to a missing file - local auth/session is missing - incompatible/old app-server -Maintainers can refresh bundled binaries with: +Maintainers stage releases by building the SDK once and the runtime once per +platform with the same pinned runtime version. Publish `codex-cli-bin` as +platform wheels only; do not publish an sdist: ```bash cd sdk/python -python scripts/update_sdk_artifacts.py --channel stable --bundle-all-platforms +python scripts/update_sdk_artifacts.py generate-types +python scripts/update_sdk_artifacts.py \ + stage-sdk \ + /tmp/codex-python-release/codex-app-server-sdk \ + --runtime-version 1.2.3 +python scripts/update_sdk_artifacts.py \ + stage-runtime \ + /tmp/codex-python-release/codex-cli-bin \ + /path/to/codex \ + --runtime-version 1.2.3 ``` ## Why does a turn "hang"? diff --git a/sdk/python/docs/getting-started.md b/sdk/python/docs/getting-started.md index a3d52afdf8..9108902b38 100644 --- a/sdk/python/docs/getting-started.md +++ b/sdk/python/docs/getting-started.md @@ -14,7 +14,7 @@ python -m pip install -e . Requirements: - Python `>=3.10` -- bundled runtime binary for your platform (shipped in package) +- installed `codex-cli-bin` runtime package, or an explicit `codex_bin` override - Local Codex auth/session configured ## 2) Run your first turn diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index 2bfc7de2ae..f5129cbf93 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -30,7 +30,7 @@ Repository = "https://github.com/openai/codex" Issues = "https://github.com/openai/codex/issues" [project.optional-dependencies] -dev = ["pytest>=8.0", "datamodel-code-generator==0.31.2"] +dev = ["pytest>=8.0", "datamodel-code-generator==0.31.2", "ruff>=0.11"] [tool.hatch.build] exclude = [ @@ -44,7 +44,6 @@ exclude = [ [tool.hatch.build.targets.wheel] packages = ["src/codex_app_server"] include = [ - "src/codex_app_server/bin/**", "src/codex_app_server/py.typed", ] diff --git a/sdk/python/scripts/update_sdk_artifacts.py b/sdk/python/scripts/update_sdk_artifacts.py index 11521caee3..da4cbceb1a 100755 --- a/sdk/python/scripts/update_sdk_artifacts.py +++ b/sdk/python/scripts/update_sdk_artifacts.py @@ -10,15 +10,12 @@ import shutil import stat import subprocess import sys -import tarfile import tempfile import types import typing -import urllib.request -import zipfile from dataclasses import dataclass from pathlib import Path -from typing import Any, get_args, get_origin +from typing import Any, Callable, Sequence, get_args, get_origin def repo_root() -> Path: @@ -29,6 +26,10 @@ def sdk_root() -> Path: return repo_root() / "sdk" / "python" +def python_runtime_root() -> Path: + return repo_root() / "sdk" / "python-runtime" + + def schema_bundle_path() -> Path: return ( repo_root() @@ -48,24 +49,12 @@ def _is_windows() -> bool: return platform.system().lower().startswith("win") -def pinned_bin_path() -> Path: - name = "codex.exe" if _is_windows() else "codex" - return sdk_root() / "bin" / name +def runtime_binary_name() -> str: + return "codex.exe" if _is_windows() else "codex" -def bundled_platform_bin_path(platform_key: str) -> Path: - exe = "codex.exe" if platform_key.startswith("windows") else "codex" - return sdk_root() / "src" / "codex_app_server" / "bin" / platform_key / exe - - -PLATFORMS: dict[str, tuple[list[str], list[str]]] = { - "darwin-arm64": (["darwin", "apple-darwin", "macos"], ["aarch64", "arm64"]), - "darwin-x64": (["darwin", "apple-darwin", "macos"], ["x86_64", "amd64", "x64"]), - "linux-arm64": (["linux", "unknown-linux", "musl", "gnu"], ["aarch64", "arm64"]), - "linux-x64": (["linux", "unknown-linux", "musl", "gnu"], ["x86_64", "amd64", "x64"]), - "windows-arm64": (["windows", "pc-windows", "win", "msvc", "gnu"], ["aarch64", "arm64"]), - "windows-x64": (["windows", "pc-windows", "win", "msvc", "gnu"], ["x86_64", "amd64", "x64"]), -} +def staged_runtime_bin_path(root: Path) -> Path: + return root / "src" / "codex_cli_bin" / "bin" / runtime_binary_name() def run(cmd: list[str], cwd: Path) -> None: @@ -76,136 +65,99 @@ def run_python_module(module: str, args: list[str], cwd: Path) -> None: run([sys.executable, "-m", module, *args], cwd) -def platform_tokens() -> tuple[list[str], list[str]]: - sys_name = platform.system().lower() - machine = platform.machine().lower() - - if sys_name == "darwin": - os_tokens = ["darwin", "apple-darwin", "macos"] - elif sys_name == "linux": - os_tokens = ["linux", "unknown-linux", "musl", "gnu"] - elif sys_name.startswith("win"): - os_tokens = ["windows", "pc-windows", "win", "msvc", "gnu"] - else: - raise RuntimeError(f"Unsupported OS: {sys_name}") - - if machine in {"arm64", "aarch64"}: - arch_tokens = ["aarch64", "arm64"] - elif machine in {"x86_64", "amd64"}: - arch_tokens = ["x86_64", "amd64", "x64"] - else: - raise RuntimeError(f"Unsupported architecture: {machine}") - - return os_tokens, arch_tokens - - -def pick_release(channel: str) -> dict[str, Any]: - releases = json.loads( - subprocess.check_output(["gh", "api", "repos/openai/codex/releases?per_page=50"], text=True) +def current_sdk_version() -> str: + match = re.search( + r'^version = "([^"]+)"$', + (sdk_root() / "pyproject.toml").read_text(), + flags=re.MULTILINE, ) - if channel == "stable": - candidates = [r for r in releases if not r.get("prerelease") and not r.get("draft")] - else: - candidates = [r for r in releases if r.get("prerelease") and not r.get("draft")] - if not candidates: - raise RuntimeError(f"No {channel} release found") - return candidates[0] + if match is None: + raise RuntimeError("Could not determine Python SDK version from pyproject.toml") + return match.group(1) -def pick_asset(release: dict[str, Any], os_tokens: list[str], arch_tokens: list[str]) -> dict[str, Any]: - scored: list[tuple[int, dict[str, Any]]] = [] - for asset in release.get("assets", []): - name = (asset.get("name") or "").lower() - - # Accept only primary codex cli artifacts. - if not (name.startswith("codex-") or name == "codex"): - continue - if name.startswith("codex-responses") or name.startswith("codex-command-runner") or name.startswith("codex-windows-sandbox") or name.startswith("codex-npm"): - continue - if not (name.endswith(".tar.gz") or name.endswith(".zip")): - continue - - os_score = sum(1 for t in os_tokens if t in name) - arch_score = sum(1 for t in arch_tokens if t in name) - if os_score == 0 or arch_score == 0: - continue - - score = os_score * 10 + arch_score - scored.append((score, asset)) - - if not scored: - raise RuntimeError("Could not find matching codex CLI asset for this platform") - - scored.sort(key=lambda x: x[0], reverse=True) - return scored[0][1] - - -def download(url: str, out: Path) -> None: - req = urllib.request.Request(url, headers={"User-Agent": "codex-python-sdk-updater"}) - with urllib.request.urlopen(req) as resp, out.open("wb") as f: - shutil.copyfileobj(resp, f) - - -def extract_codex_binary(archive: Path, out_bin: Path) -> None: - with tempfile.TemporaryDirectory() as td: - tmp = Path(td) - if archive.name.endswith(".tar.gz"): - with tarfile.open(archive, "r:gz") as tar: - tar.extractall(tmp) - elif archive.name.endswith(".zip"): - with zipfile.ZipFile(archive) as zf: - zf.extractall(tmp) +def _copy_package_tree(src: Path, dst: Path) -> None: + if dst.exists(): + if dst.is_dir(): + shutil.rmtree(dst) else: - raise RuntimeError(f"Unsupported archive format: {archive}") - - preferred_names = {"codex.exe", "codex"} - candidates = [ - p for p in tmp.rglob("*") if p.is_file() and (p.name.lower() in preferred_names or p.name.lower().startswith("codex-")) - ] - if not candidates: - raise RuntimeError("No codex binary found in release archive") - - candidates.sort(key=lambda p: (p.name.lower() not in preferred_names, p.name.lower())) - - out_bin.parent.mkdir(parents=True, exist_ok=True) - shutil.copy2(candidates[0], out_bin) - if not _is_windows(): - out_bin.chmod(out_bin.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) + dst.unlink() + shutil.copytree( + src, + dst, + ignore=shutil.ignore_patterns( + ".venv", + ".venv2", + ".pytest_cache", + "__pycache__", + "build", + "dist", + "*.pyc", + ), + ) -def _download_asset_to_binary(release: dict[str, Any], os_tokens: list[str], arch_tokens: list[str], out_bin: Path) -> None: - asset = pick_asset(release, os_tokens, arch_tokens) - print(f"Asset: {asset.get('name')} -> {out_bin}") - with tempfile.TemporaryDirectory() as td: - archive = Path(td) / (asset.get("name") or "codex-release.tar.gz") - download(asset["browser_download_url"], archive) - extract_codex_binary(archive, out_bin) +def _rewrite_project_version(pyproject_text: str, version: str) -> str: + updated, count = re.subn( + r'^version = "[^"]+"$', + f'version = "{version}"', + pyproject_text, + count=1, + flags=re.MULTILINE, + ) + if count != 1: + raise RuntimeError("Could not rewrite project version in pyproject.toml") + return updated -def update_binary(channel: str) -> None: - if shutil.which("gh") is None: - raise RuntimeError("GitHub CLI (`gh`) is required to download release binaries") +def _rewrite_sdk_runtime_dependency(pyproject_text: str, runtime_version: str) -> str: + match = re.search(r"^dependencies = \[(.*?)\]$", pyproject_text, flags=re.MULTILINE) + if match is None: + raise RuntimeError( + "Could not find dependencies array in sdk/python/pyproject.toml" + ) - release = pick_release(channel) - os_tokens, arch_tokens = platform_tokens() - print(f"Release: {release.get('tag_name')} ({channel})") - - # refresh current platform in bundled runtime location - current_key = next((k for k, v in PLATFORMS.items() if v == (os_tokens, arch_tokens)), None) - out = bundled_platform_bin_path(current_key) if current_key else pinned_bin_path() - _download_asset_to_binary(release, os_tokens, arch_tokens, out) - print(f"Pinned binary updated: {out}") + raw_items = [item.strip() for item in match.group(1).split(",") if item.strip()] + raw_items = [item for item in raw_items if "codex-cli-bin" not in item] + raw_items.append(f'"codex-cli-bin=={runtime_version}"') + replacement = "dependencies = [\n " + ",\n ".join(raw_items) + ",\n]" + return pyproject_text[: match.start()] + replacement + pyproject_text[match.end() :] -def bundle_all_platform_binaries(channel: str) -> None: - if shutil.which("gh") is None: - raise RuntimeError("GitHub CLI (`gh`) is required to download release binaries") +def stage_python_sdk_package( + staging_dir: Path, sdk_version: str, runtime_version: str +) -> Path: + _copy_package_tree(sdk_root(), staging_dir) + sdk_bin_dir = staging_dir / "src" / "codex_app_server" / "bin" + if sdk_bin_dir.exists(): + shutil.rmtree(sdk_bin_dir) - release = pick_release(channel) - print(f"Release: {release.get('tag_name')} ({channel})") - for platform_key, (os_tokens, arch_tokens) in PLATFORMS.items(): - _download_asset_to_binary(release, os_tokens, arch_tokens, bundled_platform_bin_path(platform_key)) - print("Bundled all platform binaries.") + pyproject_path = staging_dir / "pyproject.toml" + pyproject_text = pyproject_path.read_text() + pyproject_text = _rewrite_project_version(pyproject_text, sdk_version) + pyproject_text = _rewrite_sdk_runtime_dependency(pyproject_text, runtime_version) + pyproject_path.write_text(pyproject_text) + return staging_dir + + +def stage_python_runtime_package( + staging_dir: Path, runtime_version: str, binary_path: Path +) -> Path: + _copy_package_tree(python_runtime_root(), staging_dir) + + pyproject_path = staging_dir / "pyproject.toml" + pyproject_path.write_text( + _rewrite_project_version(pyproject_path.read_text(), runtime_version) + ) + + out_bin = staged_runtime_bin_path(staging_dir) + out_bin.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(binary_path, out_bin) + if not _is_windows(): + out_bin.chmod( + out_bin.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH + ) + return staging_dir def _flatten_string_enum_one_of(definition: dict[str, Any]) -> bool: @@ -242,6 +194,208 @@ def _flatten_string_enum_one_of(definition: dict[str, Any]) -> bool: return True +DISCRIMINATOR_KEYS = ("type", "method", "mode", "state", "status", "role", "reason") + + +def _to_pascal_case(value: str) -> str: + parts = re.split(r"[^0-9A-Za-z]+", value) + compact = "".join(part[:1].upper() + part[1:] for part in parts if part) + return compact or "Value" + + +def _string_literal(value: Any) -> str | None: + if not isinstance(value, dict): + return None + const = value.get("const") + if isinstance(const, str): + return const + + enum = value.get("enum") + if isinstance(enum, list) and enum and len(enum) == 1 and isinstance(enum[0], str): + return enum[0] + return None + + +def _enum_literals(value: Any) -> list[str] | None: + if not isinstance(value, dict): + return None + enum = value.get("enum") + if ( + not isinstance(enum, list) + or not enum + or not all(isinstance(item, str) for item in enum) + ): + return None + return list(enum) + + +def _literal_from_property(props: dict[str, Any], key: str) -> str | None: + return _string_literal(props.get(key)) + + +def _variant_definition_name(base: str, variant: dict[str, Any]) -> str | None: + # datamodel-code-generator invents numbered helper names for inline union + # branches unless they carry a stable, unique title up front. We derive + # those titles from the branch discriminator or other identifying shape. + props = variant.get("properties") + if isinstance(props, dict): + for key in DISCRIMINATOR_KEYS: + literal = _literal_from_property(props, key) + if literal is None: + continue + pascal = _to_pascal_case(literal) + if base == "ClientRequest": + return f"{pascal}Request" + if base == "ServerRequest": + return f"{pascal}ServerRequest" + if base == "ClientNotification": + return f"{pascal}ClientNotification" + if base == "ServerNotification": + return f"{pascal}ServerNotification" + if base == "EventMsg": + return f"{pascal}EventMsg" + return f"{pascal}{base}" + + if len(props) == 1: + key = next(iter(props)) + pascal = _string_literal(props[key]) + return f"{_to_pascal_case(pascal or key)}{base}" + + required = variant.get("required") + if ( + isinstance(required, list) + and len(required) == 1 + and isinstance(required[0], str) + ): + return f"{_to_pascal_case(required[0])}{base}" + + enum_literals = _enum_literals(variant) + if enum_literals is not None: + if len(enum_literals) == 1: + return f"{_to_pascal_case(enum_literals[0])}{base}" + return f"{base}Value" + + return None + + +def _variant_collision_key( + base: str, variant: dict[str, Any], generated_name: str +) -> str: + parts = [f"base={base}", f"generated={generated_name}"] + props = variant.get("properties") + if isinstance(props, dict): + for key in DISCRIMINATOR_KEYS: + literal = _literal_from_property(props, key) + if literal is not None: + parts.append(f"{key}={literal}") + if len(props) == 1: + parts.append(f"only_property={next(iter(props))}") + + required = variant.get("required") + if ( + isinstance(required, list) + and len(required) == 1 + and isinstance(required[0], str) + ): + parts.append(f"required_only={required[0]}") + + enum_literals = _enum_literals(variant) + if enum_literals is not None: + parts.append(f"enum={'|'.join(enum_literals)}") + + return "|".join(parts) + + +def _set_discriminator_titles(props: dict[str, Any], owner: str) -> None: + for key in DISCRIMINATOR_KEYS: + prop = props.get(key) + if not isinstance(prop, dict): + continue + if _string_literal(prop) is None or "title" in prop: + continue + prop["title"] = f"{owner}{_to_pascal_case(key)}" + + +def _annotate_variant_list(variants: list[Any], base: str | None) -> None: + seen = { + variant["title"] + for variant in variants + if isinstance(variant, dict) and isinstance(variant.get("title"), str) + } + + for variant in variants: + if not isinstance(variant, dict): + continue + + variant_name = variant.get("title") + generated_name = _variant_definition_name(base, variant) if base else None + if generated_name is not None and ( + not isinstance(variant_name, str) + or "/" in variant_name + or variant_name != generated_name + ): + # Titles like `Thread/startedNotification` sanitize poorly in + # Python, and envelope titles like `ErrorNotification` collide + # with their payload model names. Rewrite them before codegen so + # we get `ThreadStartedServerNotification` instead of `...1`. + if generated_name in seen and variant_name != generated_name: + raise RuntimeError( + "Variant title naming collision detected: " + f"{_variant_collision_key(base or '', variant, generated_name)}" + ) + variant["title"] = generated_name + seen.add(generated_name) + variant_name = generated_name + + if isinstance(variant_name, str): + props = variant.get("properties") + if isinstance(props, dict): + _set_discriminator_titles(props, variant_name) + + _annotate_schema(variant, base) + + +def _annotate_schema(value: Any, base: str | None = None) -> None: + if isinstance(value, list): + for item in value: + _annotate_schema(item, base) + return + + if not isinstance(value, dict): + return + + owner = value.get("title") + props = value.get("properties") + if isinstance(owner, str) and isinstance(props, dict): + _set_discriminator_titles(props, owner) + + one_of = value.get("oneOf") + if isinstance(one_of, list): + # Walk nested unions recursively so every inline branch gets the same + # title normalization treatment before we hand the bundle to Python + # codegen. + _annotate_variant_list(one_of, base) + + any_of = value.get("anyOf") + if isinstance(any_of, list): + _annotate_variant_list(any_of, base) + + definitions = value.get("definitions") + if isinstance(definitions, dict): + for name, schema in definitions.items(): + _annotate_schema(schema, name if isinstance(name, str) else base) + + defs = value.get("$defs") + if isinstance(defs, dict): + for name, schema in defs.items(): + _annotate_schema(schema, name if isinstance(name, str) else base) + + for key, child in value.items(): + if key in {"oneOf", "anyOf", "definitions", "$defs"}: + continue + _annotate_schema(child, base) + + def _normalized_schema_bundle_text() -> str: schema = json.loads(schema_bundle_path().read_text()) definitions = schema.get("definitions", {}) @@ -249,6 +403,9 @@ def _normalized_schema_bundle_text() -> str: for definition in definitions.values(): if isinstance(definition, dict): _flatten_string_enum_one_of(definition) + # Normalize the schema into something datamodel-code-generator can map to + # stable class names instead of anonymous numbered helpers. + _annotate_schema(schema) return json.dumps(schema, indent=2, sort_keys=True) + "\n" @@ -274,20 +431,34 @@ def generate_v2_all() -> None: "--output-model-type", "pydantic_v2.BaseModel", "--target-python-version", - "3.10", + "3.11", + "--use-standard-collections", + "--enum-field-as-literal", + "one", + "--field-constraints", + "--use-default-kwarg", "--snake-case-field", "--allow-population-by-field-name", + # Once the schema prepass has assigned stable titles, tell the + # generator to prefer those titles as the emitted class names. + "--use-title-as-name", + "--use-annotated", "--use-union-operator", - "--reuse-model", "--disable-timestamp", - "--use-double-quotes", + # Keep the generated file formatted deterministically so the + # checked-in artifact only changes when the schema does. + "--formatters", + "ruff-format", ], cwd=sdk_root(), ) _normalize_generated_timestamps(out_path) + def _notification_specs() -> list[tuple[str, str]]: - server_notifications = json.loads((schema_root_dir() / "ServerNotification.json").read_text()) + server_notifications = json.loads( + (schema_root_dir() / "ServerNotification.json").read_text() + ) one_of = server_notifications.get("oneOf", []) generated_source = ( sdk_root() / "src" / "codex_app_server" / "generated" / "v2_all.py" @@ -311,7 +482,10 @@ def _notification_specs() -> list[tuple[str, str]]: if not isinstance(ref, str) or not ref.startswith("#/definitions/"): continue class_name = ref.split("/")[-1] - if f"class {class_name}(" not in generated_source and f"{class_name} =" not in generated_source: + if ( + f"class {class_name}(" not in generated_source + and f"{class_name} =" not in generated_source + ): # Skip schema variants that are not emitted into the generated v2 surface. continue specs.append((method, class_name)) @@ -321,7 +495,13 @@ def _notification_specs() -> list[tuple[str, str]]: def generate_notification_registry() -> None: - out = sdk_root() / "src" / "codex_app_server" / "generated" / "notification_registry.py" + out = ( + sdk_root() + / "src" + / "codex_app_server" + / "generated" + / "notification_registry.py" + ) specs = _notification_specs() class_names = sorted({class_name for _, class_name in specs}) @@ -359,6 +539,7 @@ def _normalize_generated_timestamps(root: Path) -> None: if normalized != content: py_file.write_text(normalized) + FIELD_ANNOTATION_OVERRIDES: dict[str, str] = { # Keep public API typed without falling back to `Any`. "config": "JsonObject", @@ -374,6 +555,14 @@ class PublicFieldSpec: required: bool +@dataclass(frozen=True) +class CliOps: + generate_types: Callable[[], None] + stage_python_sdk_package: Callable[[Path, str, str], Path] + stage_python_runtime_package: Callable[[Path, str, Path], Path] + current_sdk_version: Callable[[], str] + + def _annotation_to_source(annotation: Any) -> str: origin = get_origin(annotation) if origin is typing.Annotated: @@ -410,7 +599,9 @@ def _camel_to_snake(name: str) -> str: return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", head).lower() -def _load_public_fields(module_name: str, class_name: str, *, exclude: set[str] | None = None) -> list[PublicFieldSpec]: +def _load_public_fields( + module_name: str, class_name: str, *, exclude: set[str] | None = None +) -> list[PublicFieldSpec]: exclude = exclude or set() module = importlib.import_module(module_name) model = getattr(module, class_name) @@ -442,16 +633,16 @@ def _kw_signature_lines(fields: list[PublicFieldSpec]) -> list[str]: return lines -def _model_arg_lines(fields: list[PublicFieldSpec], *, indent: str = " ") -> list[str]: +def _model_arg_lines( + fields: list[PublicFieldSpec], *, indent: str = " " +) -> list[str]: return [f"{indent}{field.wire_name}={field.py_name}," for field in fields] def _replace_generated_block(source: str, block_name: str, body: str) -> str: start_tag = f" # BEGIN GENERATED: {block_name}" end_tag = f" # END GENERATED: {block_name}" - pattern = re.compile( - rf"(?s){re.escape(start_tag)}\n.*?\n{re.escape(end_tag)}" - ) + pattern = re.compile(rf"(?s){re.escape(start_tag)}\n.*?\n{re.escape(end_tag)}") replacement = f"{start_tag}\n{body.rstrip()}\n{end_tag}" updated, count = pattern.subn(replacement, source, count=1) if count != 1: @@ -717,23 +908,89 @@ def generate_types() -> None: generate_public_api_flat_methods() -def main() -> None: +def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="Single SDK maintenance entrypoint") - parser.add_argument("--channel", choices=["stable", "alpha"], default="stable") - parser.add_argument("--types-only", action="store_true", help="Regenerate types only (skip binary update)") - parser.add_argument( - "--bundle-all-platforms", - action="store_true", - help="Download and bundle codex binaries for all supported OS/arch targets", - ) - args = parser.parse_args() + subparsers = parser.add_subparsers(dest="command", required=True) - if not args.types_only: - if args.bundle_all_platforms: - bundle_all_platform_binaries(args.channel) - else: - update_binary(args.channel) - generate_types() + subparsers.add_parser( + "generate-types", help="Regenerate Python protocol-derived types" + ) + + stage_sdk_parser = subparsers.add_parser( + "stage-sdk", + help="Stage a releasable SDK package pinned to a runtime version", + ) + stage_sdk_parser.add_argument( + "staging_dir", + type=Path, + help="Output directory for the staged SDK package", + ) + stage_sdk_parser.add_argument( + "--runtime-version", + required=True, + help="Pinned codex-cli-bin version for the staged SDK package", + ) + stage_sdk_parser.add_argument( + "--sdk-version", + help="Version to write into the staged SDK package (defaults to sdk/python current version)", + ) + + stage_runtime_parser = subparsers.add_parser( + "stage-runtime", + help="Stage a releasable runtime package for the current platform", + ) + stage_runtime_parser.add_argument( + "staging_dir", + type=Path, + help="Output directory for the staged runtime package", + ) + stage_runtime_parser.add_argument( + "runtime_binary", + type=Path, + help="Path to the codex binary to package for this platform", + ) + stage_runtime_parser.add_argument( + "--runtime-version", + required=True, + help="Version to write into the staged runtime package", + ) + return parser + + +def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace: + return build_parser().parse_args(list(argv) if argv is not None else None) + + +def default_cli_ops() -> CliOps: + return CliOps( + generate_types=generate_types, + stage_python_sdk_package=stage_python_sdk_package, + stage_python_runtime_package=stage_python_runtime_package, + current_sdk_version=current_sdk_version, + ) + + +def run_command(args: argparse.Namespace, ops: CliOps) -> None: + if args.command == "generate-types": + ops.generate_types() + elif args.command == "stage-sdk": + ops.generate_types() + ops.stage_python_sdk_package( + args.staging_dir, + args.sdk_version or ops.current_sdk_version(), + args.runtime_version, + ) + elif args.command == "stage-runtime": + ops.stage_python_runtime_package( + args.staging_dir, + args.runtime_version, + args.runtime_binary.resolve(), + ) + + +def main(argv: Sequence[str] | None = None, ops: CliOps | None = None) -> None: + args = parse_args(argv) + run_command(args, ops or default_cli_ops()) print("Done.") diff --git a/sdk/python/src/codex_app_server/bin/darwin-arm64/codex b/sdk/python/src/codex_app_server/bin/darwin-arm64/codex deleted file mode 100755 index 70c50814c6..0000000000 Binary files a/sdk/python/src/codex_app_server/bin/darwin-arm64/codex and /dev/null differ diff --git a/sdk/python/src/codex_app_server/bin/darwin-x64/codex b/sdk/python/src/codex_app_server/bin/darwin-x64/codex deleted file mode 100755 index b7d9086c7a..0000000000 Binary files a/sdk/python/src/codex_app_server/bin/darwin-x64/codex and /dev/null differ diff --git a/sdk/python/src/codex_app_server/bin/linux-arm64/codex b/sdk/python/src/codex_app_server/bin/linux-arm64/codex deleted file mode 100755 index 6eb65043ef..0000000000 Binary files a/sdk/python/src/codex_app_server/bin/linux-arm64/codex and /dev/null differ diff --git a/sdk/python/src/codex_app_server/bin/linux-x64/codex b/sdk/python/src/codex_app_server/bin/linux-x64/codex deleted file mode 100755 index 0b2541a0ce..0000000000 Binary files a/sdk/python/src/codex_app_server/bin/linux-x64/codex and /dev/null differ diff --git a/sdk/python/src/codex_app_server/bin/windows-arm64/codex.exe b/sdk/python/src/codex_app_server/bin/windows-arm64/codex.exe deleted file mode 100755 index 457c5c9653..0000000000 Binary files a/sdk/python/src/codex_app_server/bin/windows-arm64/codex.exe and /dev/null differ diff --git a/sdk/python/src/codex_app_server/bin/windows-x64/codex.exe b/sdk/python/src/codex_app_server/bin/windows-x64/codex.exe deleted file mode 100755 index 31450cb3fd..0000000000 Binary files a/sdk/python/src/codex_app_server/bin/windows-x64/codex.exe and /dev/null differ diff --git a/sdk/python/src/codex_app_server/client.py b/sdk/python/src/codex_app_server/client.py index fa20304cf2..aa7b574a3f 100644 --- a/sdk/python/src/codex_app_server/client.py +++ b/sdk/python/src/codex_app_server/client.py @@ -47,6 +47,7 @@ from .retry import retry_on_overload ModelT = TypeVar("ModelT", bound=BaseModel) ApprovalHandler = Callable[[str, JsonObject | None], JsonObject] +RUNTIME_PKG_NAME = "codex-cli-bin" def _params_dict( @@ -76,30 +77,52 @@ def _params_dict( raise TypeError(f"Expected generated params model or dict, got {type(params).__name__}") -def _bundled_codex_path() -> Path: - import platform +def _installed_codex_path() -> Path: + try: + from codex_cli_bin import bundled_codex_path + except ImportError as exc: + raise FileNotFoundError( + "Unable to locate the pinned Codex runtime. Install the published SDK build " + f"with its {RUNTIME_PKG_NAME} dependency, or set AppServerConfig.codex_bin " + "explicitly." + ) from exc - sys_name = platform.system().lower() - machine = platform.machine().lower() + return bundled_codex_path() - if sys_name.startswith("darwin"): - platform_dir = "darwin-arm64" if machine in {"arm64", "aarch64"} else "darwin-x64" - exe = "codex" - elif sys_name.startswith("linux"): - platform_dir = "linux-arm64" if machine in {"arm64", "aarch64"} else "linux-x64" - exe = "codex" - elif sys_name.startswith("windows") or os.name == "nt": - platform_dir = "windows-arm64" if machine in {"arm64", "aarch64"} else "windows-x64" - exe = "codex.exe" - else: - raise RuntimeError(f"Unsupported OS for bundled codex binary: {sys_name}/{machine}") - return Path(__file__).resolve().parent / "bin" / platform_dir / exe +@dataclass(frozen=True) +class CodexBinResolverOps: + installed_codex_path: Callable[[], Path] + path_exists: Callable[[Path], bool] + + +def _default_codex_bin_resolver_ops() -> CodexBinResolverOps: + return CodexBinResolverOps( + installed_codex_path=_installed_codex_path, + path_exists=lambda path: path.exists(), + ) + + +def resolve_codex_bin(config: "AppServerConfig", ops: CodexBinResolverOps) -> Path: + if config.codex_bin is not None: + codex_bin = Path(config.codex_bin) + if not ops.path_exists(codex_bin): + raise FileNotFoundError( + f"Codex binary not found at {codex_bin}. Set AppServerConfig.codex_bin " + "to a valid binary path." + ) + return codex_bin + + return ops.installed_codex_path() + + +def _resolve_codex_bin(config: "AppServerConfig") -> Path: + return resolve_codex_bin(config, _default_codex_bin_resolver_ops()) @dataclass(slots=True) class AppServerConfig: - codex_bin: str = str(_bundled_codex_path()) + codex_bin: str | None = None launch_args_override: tuple[str, ...] | None = None config_overrides: tuple[str, ...] = () cwd: str | None = None @@ -142,11 +165,7 @@ class AppServerClient: if self.config.launch_args_override is not None: args = list(self.config.launch_args_override) else: - codex_bin = Path(self.config.codex_bin) - if not codex_bin.exists(): - raise FileNotFoundError( - f"Pinned codex binary not found at {codex_bin}. Run `python scripts/update_sdk_artifacts.py --channel stable` from sdk/python." - ) + codex_bin = _resolve_codex_bin(self.config) args = [str(codex_bin)] for kv in self.config.config_overrides: args.extend(["--config", kv]) diff --git a/sdk/python/src/codex_app_server/generated/v2_all.py b/sdk/python/src/codex_app_server/generated/v2_all.py index 824c86c44b..d869d430c4 100644 --- a/sdk/python/src/codex_app_server/generated/v2_all.py +++ b/sdk/python/src/codex_app_server/generated/v2_all.py @@ -2,11 +2,9 @@ # filename: codex_app_server_protocol.v2.schemas.json from __future__ import annotations - +from pydantic import BaseModel, ConfigDict, Field, RootModel +from typing import Annotated, Any, Literal from enum import Enum -from typing import Any, Dict, List - -from pydantic import BaseModel, ConfigDict, Field, RootModel, conint class CodexAppServerProtocolV2(BaseModel): @@ -20,25 +18,19 @@ class AbsolutePathBuf(RootModel[str]): model_config = ConfigDict( populate_by_name=True, ) - root: str = Field( - ..., - 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.", - ) + root: Annotated[ + str, + Field( + 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." + ), + ] -class Type(Enum): - api_key = "apiKey" - - -class Account1(BaseModel): +class ApiKeyAccount(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type = Field(..., title="ApiKeyAccountType") - - -class Type1(Enum): - chatgpt = "chatgpt" + type: Annotated[Literal["apiKey"], Field(title="ApiKeyAccountType")] class AccountLoginCompletedNotification(BaseModel): @@ -46,27 +38,23 @@ class AccountLoginCompletedNotification(BaseModel): populate_by_name=True, ) error: str | None = None - login_id: str | None = Field(None, alias="loginId") + login_id: Annotated[str | None, Field(alias="loginId")] = None success: bool -class Type2(Enum): - text = "Text" - - -class AgentMessageContent1(BaseModel): +class TextAgentMessageContent(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type2 = Field(..., title="TextAgentMessageContentType") + type: Annotated[Literal["Text"], Field(title="TextAgentMessageContentType")] -class AgentMessageContent(RootModel[AgentMessageContent1]): +class AgentMessageContent(RootModel[TextAgentMessageContent]): model_config = ConfigDict( populate_by_name=True, ) - root: AgentMessageContent1 + root: TextAgentMessageContent class AgentMessageDeltaNotification(BaseModel): @@ -74,20 +62,12 @@ class AgentMessageDeltaNotification(BaseModel): populate_by_name=True, ) delta: str - item_id: str = Field(..., alias="itemId") - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + item_id: Annotated[str, Field(alias="itemId")] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] -class AgentStatus1(Enum): - pending_init = "pending_init" - - -class AgentStatus2(Enum): - running = "running" - - -class AgentStatus3(BaseModel): +class CompletedAgentStatus(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, @@ -95,7 +75,7 @@ class AgentStatus3(BaseModel): completed: str | None = None -class AgentStatus4(BaseModel): +class ErroredAgentStatus(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, @@ -103,35 +83,28 @@ class AgentStatus4(BaseModel): errored: str -class AgentStatus5(Enum): - shutdown = "shutdown" - - -class AgentStatus6(Enum): - not_found = "not_found" - - class AgentStatus( RootModel[ - AgentStatus1 - | AgentStatus2 - | AgentStatus3 - | AgentStatus4 - | AgentStatus5 - | AgentStatus6 + Literal["pending_init"] + | Literal["running"] + | CompletedAgentStatus + | ErroredAgentStatus + | Literal["shutdown"] + | Literal["not_found"] ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - AgentStatus1 - | AgentStatus2 - | AgentStatus3 - | AgentStatus4 - | AgentStatus5 - | AgentStatus6 - ) = Field(..., description="Agent lifecycle status, derived from emitted events.") + root: Annotated[ + Literal["pending_init"] + | Literal["running"] + | CompletedAgentStatus + | ErroredAgentStatus + | Literal["shutdown"] + | Literal["not_found"], + Field(description="Agent lifecycle status, derived from emitted events."), + ] class AnalyticsConfig(BaseModel): @@ -148,9 +121,9 @@ class AppBranding(BaseModel): ) category: str | None = None developer: str | None = None - is_discoverable_app: bool = Field(..., alias="isDiscoverableApp") - privacy_policy: str | None = Field(None, alias="privacyPolicy") - terms_of_service: str | None = Field(None, alias="termsOfService") + is_discoverable_app: Annotated[bool, Field(alias="isDiscoverableApp")] + privacy_policy: Annotated[str | None, Field(alias="privacyPolicy")] = None + terms_of_service: Annotated[str | None, Field(alias="termsOfService")] = None website: str | None = None @@ -165,9 +138,9 @@ class AppScreenshot(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - file_id: str | None = Field(None, alias="fileId") + file_id: Annotated[str | None, Field(alias="fileId")] = None url: str | None = None - user_prompt: str = Field(..., alias="userPrompt") + user_prompt: Annotated[str, Field(alias="userPrompt")] class AppSummary(BaseModel): @@ -176,7 +149,7 @@ class AppSummary(BaseModel): ) description: str | None = None id: str - install_url: str | None = Field(None, alias="installUrl") + install_url: Annotated[str | None, Field(alias="installUrl")] = None name: str @@ -194,7 +167,11 @@ class AppToolConfig(BaseModel): enabled: bool | None = None -AppToolsConfig = CodexAppServerProtocolV2 +class AppToolsConfig(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) class AppsDefaultConfig(BaseModel): @@ -210,26 +187,34 @@ class AppsListParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cursor: str | None = Field( - None, description="Opaque pagination cursor returned by a previous call." - ) - force_refetch: bool | None = Field( - None, - alias="forceRefetch", - description="When true, bypass app caches and fetch the latest data from sources.", - ) - limit: conint(ge=0) | None = Field( - None, - description="Optional page size; defaults to a reasonable server-side value.", - ) - thread_id: str | None = Field( - None, - alias="threadId", - description="Optional thread id used to evaluate app feature gating from that thread's config.", - ) + cursor: Annotated[ + str | None, + Field(description="Opaque pagination cursor returned by a previous call."), + ] = None + force_refetch: Annotated[ + bool | None, + Field( + alias="forceRefetch", + description="When true, bypass app caches and fetch the latest data from sources.", + ), + ] = None + limit: Annotated[ + int | None, + Field( + description="Optional page size; defaults to a reasonable server-side value.", + ge=0, + ), + ] = None + thread_id: Annotated[ + str | None, + Field( + alias="threadId", + description="Optional thread id used to evaluate app feature gating from that thread's config.", + ), + ] = None -class AskForApproval1(Enum): +class AskForApprovalValue(Enum): untrusted = "untrusted" on_failure = "on-failure" on_request = "on-request" @@ -246,7 +231,7 @@ class Reject(BaseModel): sandbox_approval: bool -class AskForApproval2(BaseModel): +class RejectAskForApproval(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, @@ -254,11 +239,11 @@ class AskForApproval2(BaseModel): reject: Reject -class AskForApproval(RootModel[AskForApproval1 | AskForApproval2]): +class AskForApproval(RootModel[AskForApprovalValue | RejectAskForApproval]): model_config = ConfigDict( populate_by_name=True, ) - root: AskForApproval1 | AskForApproval2 + root: AskForApprovalValue | RejectAskForApproval class AuthMode(Enum): @@ -271,25 +256,25 @@ class ByteRange(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - end: conint(ge=0) - start: conint(ge=0) + end: Annotated[int, Field(ge=0)] + start: Annotated[int, Field(ge=0)] class CallToolResult(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - field_meta: Any | None = Field(None, alias="_meta") - content: List - is_error: bool | None = Field(None, alias="isError") - structured_content: Any | None = Field(None, alias="structuredContent") + field_meta: Annotated[Any | None, Field(alias="_meta")] = None + content: list + is_error: Annotated[bool | None, Field(alias="isError")] = None + structured_content: Annotated[Any | None, Field(alias="structuredContent")] = None class CancelLoginAccountParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - login_id: str = Field(..., alias="loginId") + login_id: Annotated[str, Field(alias="loginId")] class CancelLoginAccountStatus(Enum): @@ -306,203 +291,7 @@ class ClientInfo(BaseModel): version: str -class Method(Enum): - initialize = "initialize" - - -class Method1(Enum): - thread_start = "thread/start" - - -class Method2(Enum): - thread_resume = "thread/resume" - - -class Method3(Enum): - thread_fork = "thread/fork" - - -class Method4(Enum): - thread_archive = "thread/archive" - - -class Method5(Enum): - thread_unsubscribe = "thread/unsubscribe" - - -class Method6(Enum): - thread_name_set = "thread/name/set" - - -class Method7(Enum): - thread_metadata_update = "thread/metadata/update" - - -class Method8(Enum): - thread_unarchive = "thread/unarchive" - - -class Method9(Enum): - thread_compact_start = "thread/compact/start" - - -class Method10(Enum): - thread_rollback = "thread/rollback" - - -class Method11(Enum): - thread_list = "thread/list" - - -class Method12(Enum): - thread_loaded_list = "thread/loaded/list" - - -class Method13(Enum): - thread_read = "thread/read" - - -class Method14(Enum): - skills_list = "skills/list" - - -class Method15(Enum): - plugin_list = "plugin/list" - - -class Method16(Enum): - skills_remote_list = "skills/remote/list" - - -class Method17(Enum): - skills_remote_export = "skills/remote/export" - - -class Method18(Enum): - app_list = "app/list" - - -class Method19(Enum): - skills_config_write = "skills/config/write" - - -class Method20(Enum): - plugin_install = "plugin/install" - - -class Method21(Enum): - plugin_uninstall = "plugin/uninstall" - - -class Method22(Enum): - turn_start = "turn/start" - - -class Method23(Enum): - turn_steer = "turn/steer" - - -class Method24(Enum): - turn_interrupt = "turn/interrupt" - - -class Method25(Enum): - review_start = "review/start" - - -class Method26(Enum): - model_list = "model/list" - - -class Method27(Enum): - experimental_feature_list = "experimentalFeature/list" - - -class Method28(Enum): - mcp_server_oauth_login = "mcpServer/oauth/login" - - -class Method29(Enum): - config_mcp_server_reload = "config/mcpServer/reload" - - -class Method30(Enum): - mcp_server_status_list = "mcpServerStatus/list" - - -class Method31(Enum): - windows_sandbox_setup_start = "windowsSandbox/setupStart" - - -class Method32(Enum): - account_login_start = "account/login/start" - - -class Method33(Enum): - account_login_cancel = "account/login/cancel" - - -class Method34(Enum): - account_logout = "account/logout" - - -class Method35(Enum): - account_rate_limits_read = "account/rateLimits/read" - - -class Method36(Enum): - feedback_upload = "feedback/upload" - - -class Method37(Enum): - command_exec = "command/exec" - - -class Method38(Enum): - command_exec_write = "command/exec/write" - - -class Method39(Enum): - command_exec_terminate = "command/exec/terminate" - - -class Method40(Enum): - command_exec_resize = "command/exec/resize" - - -class Method41(Enum): - config_read = "config/read" - - -class Method42(Enum): - external_agent_config_detect = "externalAgentConfig/detect" - - -class Method43(Enum): - external_agent_config_import = "externalAgentConfig/import" - - -class Method44(Enum): - config_value_write = "config/value/write" - - -class Method45(Enum): - config_batch_write = "config/batchWrite" - - -class Method46(Enum): - config_requirements_read = "configRequirements/read" - - -class Method47(Enum): - account_read = "account/read" - - -class Method48(Enum): - fuzzy_file_search = "fuzzyFileSearch" - - -class CodexErrorInfo1(Enum): +class CodexErrorInfoValue(Enum): context_window_exceeded = "contextWindowExceeded" usage_limit_exceeded = "usageLimitExceeded" server_overloaded = "serverOverloaded" @@ -518,80 +307,92 @@ class HttpConnectionFailed(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - http_status_code: conint(ge=0) | None = Field(None, alias="httpStatusCode") + http_status_code: Annotated[int | None, Field(alias="httpStatusCode", ge=0)] = None -class CodexErrorInfo2(BaseModel): +class HttpConnectionFailedCodexErrorInfo(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - http_connection_failed: HttpConnectionFailed = Field( - ..., alias="httpConnectionFailed" + http_connection_failed: Annotated[ + HttpConnectionFailed, Field(alias="httpConnectionFailed") + ] + + +class ResponseStreamConnectionFailed(BaseModel): + model_config = ConfigDict( + populate_by_name=True, ) + http_status_code: Annotated[int | None, Field(alias="httpStatusCode", ge=0)] = None -ResponseStreamConnectionFailed = HttpConnectionFailed - - -class CodexErrorInfo3(BaseModel): +class ResponseStreamConnectionFailedCodexErrorInfo(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - response_stream_connection_failed: ResponseStreamConnectionFailed = Field( - ..., alias="responseStreamConnectionFailed" + response_stream_connection_failed: Annotated[ + ResponseStreamConnectionFailed, Field(alias="responseStreamConnectionFailed") + ] + + +class ResponseStreamDisconnected(BaseModel): + model_config = ConfigDict( + populate_by_name=True, ) + http_status_code: Annotated[int | None, Field(alias="httpStatusCode", ge=0)] = None -ResponseStreamDisconnected = HttpConnectionFailed - - -class CodexErrorInfo4(BaseModel): +class ResponseStreamDisconnectedCodexErrorInfo(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - response_stream_disconnected: ResponseStreamDisconnected = Field( - ..., alias="responseStreamDisconnected" + response_stream_disconnected: Annotated[ + ResponseStreamDisconnected, Field(alias="responseStreamDisconnected") + ] + + +class ResponseTooManyFailedAttempts(BaseModel): + model_config = ConfigDict( + populate_by_name=True, ) + http_status_code: Annotated[int | None, Field(alias="httpStatusCode", ge=0)] = None -ResponseTooManyFailedAttempts = HttpConnectionFailed - - -class CodexErrorInfo5(BaseModel): +class ResponseTooManyFailedAttemptsCodexErrorInfo(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - response_too_many_failed_attempts: ResponseTooManyFailedAttempts = Field( - ..., alias="responseTooManyFailedAttempts" - ) + response_too_many_failed_attempts: Annotated[ + ResponseTooManyFailedAttempts, Field(alias="responseTooManyFailedAttempts") + ] class CodexErrorInfo( RootModel[ - CodexErrorInfo1 - | CodexErrorInfo2 - | CodexErrorInfo3 - | CodexErrorInfo4 - | CodexErrorInfo5 + CodexErrorInfoValue + | HttpConnectionFailedCodexErrorInfo + | ResponseStreamConnectionFailedCodexErrorInfo + | ResponseStreamDisconnectedCodexErrorInfo + | ResponseTooManyFailedAttemptsCodexErrorInfo ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - CodexErrorInfo1 - | CodexErrorInfo2 - | CodexErrorInfo3 - | CodexErrorInfo4 - | CodexErrorInfo5 - ) = Field( - ..., - 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.", - ) + root: Annotated[ + CodexErrorInfoValue + | HttpConnectionFailedCodexErrorInfo + | ResponseStreamConnectionFailedCodexErrorInfo + | ResponseStreamDisconnectedCodexErrorInfo + | ResponseTooManyFailedAttemptsCodexErrorInfo, + Field( + 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." + ), + ] class CollabAgentStatus(Enum): @@ -617,66 +418,60 @@ class CollabAgentToolCallStatus(Enum): failed = "failed" -class Type3(Enum): - read = "read" - - -class CommandAction1(BaseModel): +class ReadCommandAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) command: str name: str path: str - type: Type3 = Field(..., title="ReadCommandActionType") + type: Annotated[Literal["read"], Field(title="ReadCommandActionType")] -class Type4(Enum): - list_files = "listFiles" - - -class CommandAction2(BaseModel): +class ListFilesCommandAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) command: str path: str | None = None - type: Type4 = Field(..., title="ListFilesCommandActionType") + type: Annotated[Literal["listFiles"], Field(title="ListFilesCommandActionType")] -class Type5(Enum): - search = "search" - - -class CommandAction3(BaseModel): +class SearchCommandAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) command: str path: str | None = None query: str | None = None - type: Type5 = Field(..., title="SearchCommandActionType") + type: Annotated[Literal["search"], Field(title="SearchCommandActionType")] -class Type6(Enum): - unknown = "unknown" - - -class CommandAction4(BaseModel): +class UnknownCommandAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) command: str - type: Type6 = Field(..., title="UnknownCommandActionType") + type: Annotated[Literal["unknown"], Field(title="UnknownCommandActionType")] class CommandAction( - RootModel[CommandAction1 | CommandAction2 | CommandAction3 | CommandAction4] + RootModel[ + ReadCommandAction + | ListFilesCommandAction + | SearchCommandAction + | UnknownCommandAction + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: CommandAction1 | CommandAction2 | CommandAction3 | CommandAction4 + root: ( + ReadCommandAction + | ListFilesCommandAction + | SearchCommandAction + | UnknownCommandAction + ) class CommandExecOutputStream(Enum): @@ -684,71 +479,102 @@ class CommandExecOutputStream(Enum): stderr = "stderr" -CommandExecResizeResponse = CodexAppServerProtocolV2 +class CommandExecResizeResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) class CommandExecResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - exit_code: int = Field(..., alias="exitCode", description="Process exit code.") - stderr: str = Field( - ..., - description="Buffered stderr capture.\n\nEmpty when stderr was streamed via `command/exec/outputDelta`.", - ) - stdout: str = Field( - ..., - description="Buffered stdout capture.\n\nEmpty when stdout was streamed via `command/exec/outputDelta`.", - ) + exit_code: Annotated[int, Field(alias="exitCode", description="Process exit code.")] + stderr: Annotated[ + str, + Field( + description="Buffered stderr capture.\n\nEmpty when stderr was streamed via `command/exec/outputDelta`." + ), + ] + stdout: Annotated[ + str, + Field( + description="Buffered stdout capture.\n\nEmpty when stdout was streamed via `command/exec/outputDelta`." + ), + ] class CommandExecTerminalSize(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cols: conint(ge=0) = Field(..., description="Terminal width in character cells.") - rows: conint(ge=0) = Field(..., description="Terminal height in character cells.") + cols: Annotated[int, Field(description="Terminal width in character cells.", ge=0)] + rows: Annotated[int, Field(description="Terminal height in character cells.", ge=0)] class CommandExecTerminateParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - process_id: str = Field( - ..., - alias="processId", - description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + process_id: Annotated[ + str, + Field( + alias="processId", + description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + ), + ] + + +class CommandExecTerminateResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, ) -CommandExecTerminateResponse = CodexAppServerProtocolV2 - - class CommandExecWriteParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - close_stdin: bool | None = Field( - None, - alias="closeStdin", - description="Close stdin after writing `deltaBase64`, if present.", - ) - delta_base64: str | None = Field( - None, - alias="deltaBase64", - description="Optional base64-encoded stdin bytes to write.", - ) - process_id: str = Field( - ..., - alias="processId", - description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + close_stdin: Annotated[ + bool | None, + Field( + alias="closeStdin", + description="Close stdin after writing `deltaBase64`, if present.", + ), + ] = None + delta_base64: Annotated[ + str | None, + Field( + alias="deltaBase64", + description="Optional base64-encoded stdin bytes to write.", + ), + ] = None + process_id: Annotated[ + str, + Field( + alias="processId", + description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + ), + ] + + +class CommandExecWriteResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, ) -CommandExecWriteResponse = CodexAppServerProtocolV2 - - -CommandExecutionOutputDeltaNotification = AgentMessageDeltaNotification +class CommandExecutionOutputDeltaNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + delta: str + item_id: Annotated[str, Field(alias="itemId")] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class CommandExecutionStatus(Enum): @@ -758,121 +584,101 @@ class CommandExecutionStatus(Enum): declined = "declined" -class Type7(Enum): - mdm = "mdm" - - -class ConfigLayerSource1(BaseModel): +class MdmConfigLayerSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) domain: str key: str - type: Type7 = Field(..., title="MdmConfigLayerSourceType") + type: Annotated[Literal["mdm"], Field(title="MdmConfigLayerSourceType")] -class Type8(Enum): - system = "system" - - -class ConfigLayerSource2(BaseModel): +class SystemConfigLayerSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - file: AbsolutePathBuf = Field( - ..., - description="This is the path to the system config.toml file, though it is not guaranteed to exist.", - ) - type: Type8 = Field(..., title="SystemConfigLayerSourceType") + file: Annotated[ + AbsolutePathBuf, + Field( + description="This is the path to the system config.toml file, though it is not guaranteed to exist." + ), + ] + type: Annotated[Literal["system"], Field(title="SystemConfigLayerSourceType")] -class Type9(Enum): - user = "user" - - -class ConfigLayerSource3(BaseModel): +class UserConfigLayerSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - file: AbsolutePathBuf = Field( - ..., - description="This is the path to the user's config.toml file, though it is not guaranteed to exist.", - ) - type: Type9 = Field(..., title="UserConfigLayerSourceType") + file: Annotated[ + AbsolutePathBuf, + Field( + description="This is the path to the user's config.toml file, though it is not guaranteed to exist." + ), + ] + type: Annotated[Literal["user"], Field(title="UserConfigLayerSourceType")] -class Type10(Enum): - project = "project" - - -class ConfigLayerSource4(BaseModel): +class ProjectConfigLayerSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - dot_codex_folder: AbsolutePathBuf = Field(..., alias="dotCodexFolder") - type: Type10 = Field(..., title="ProjectConfigLayerSourceType") + dot_codex_folder: Annotated[AbsolutePathBuf, Field(alias="dotCodexFolder")] + type: Annotated[Literal["project"], Field(title="ProjectConfigLayerSourceType")] -class Type11(Enum): - session_flags = "sessionFlags" - - -class ConfigLayerSource5(BaseModel): +class SessionFlagsConfigLayerSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type11 = Field(..., title="SessionFlagsConfigLayerSourceType") + type: Annotated[ + Literal["sessionFlags"], Field(title="SessionFlagsConfigLayerSourceType") + ] -class Type12(Enum): - legacy_managed_config_toml_from_file = "legacyManagedConfigTomlFromFile" - - -class ConfigLayerSource6(BaseModel): +class LegacyManagedConfigTomlFromFileConfigLayerSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) file: AbsolutePathBuf - type: Type12 = Field( - ..., title="LegacyManagedConfigTomlFromFileConfigLayerSourceType" - ) + type: Annotated[ + Literal["legacyManagedConfigTomlFromFile"], + Field(title="LegacyManagedConfigTomlFromFileConfigLayerSourceType"), + ] -class Type13(Enum): - legacy_managed_config_toml_from_mdm = "legacyManagedConfigTomlFromMdm" - - -class ConfigLayerSource7(BaseModel): +class LegacyManagedConfigTomlFromMdmConfigLayerSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type13 = Field( - ..., title="LegacyManagedConfigTomlFromMdmConfigLayerSourceType" - ) + type: Annotated[ + Literal["legacyManagedConfigTomlFromMdm"], + Field(title="LegacyManagedConfigTomlFromMdmConfigLayerSourceType"), + ] class ConfigLayerSource( RootModel[ - ConfigLayerSource1 - | ConfigLayerSource2 - | ConfigLayerSource3 - | ConfigLayerSource4 - | ConfigLayerSource5 - | ConfigLayerSource6 - | ConfigLayerSource7 + MdmConfigLayerSource + | SystemConfigLayerSource + | UserConfigLayerSource + | ProjectConfigLayerSource + | SessionFlagsConfigLayerSource + | LegacyManagedConfigTomlFromFileConfigLayerSource + | LegacyManagedConfigTomlFromMdmConfigLayerSource ] ): model_config = ConfigDict( populate_by_name=True, ) root: ( - ConfigLayerSource1 - | ConfigLayerSource2 - | ConfigLayerSource3 - | ConfigLayerSource4 - | ConfigLayerSource5 - | ConfigLayerSource6 - | ConfigLayerSource7 + MdmConfigLayerSource + | SystemConfigLayerSource + | UserConfigLayerSource + | ProjectConfigLayerSource + | SessionFlagsConfigLayerSource + | LegacyManagedConfigTomlFromFileConfigLayerSource + | LegacyManagedConfigTomlFromMdmConfigLayerSource ) @@ -880,62 +686,54 @@ class ConfigReadParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cwd: str | None = Field( - None, - 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).", - ) - include_layers: bool | None = Field(False, alias="includeLayers") + cwd: Annotated[ + str | None, + Field( + 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)." + ), + ] = None + include_layers: Annotated[bool | None, Field(alias="includeLayers")] = False -class Type14(Enum): - input_text = "input_text" - - -class ContentItem1(BaseModel): +class InputTextContentItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type14 = Field(..., title="InputTextContentItemType") + type: Annotated[Literal["input_text"], Field(title="InputTextContentItemType")] -class Type15(Enum): - input_image = "input_image" - - -class ContentItem2(BaseModel): +class InputImageContentItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) image_url: str - type: Type15 = Field(..., title="InputImageContentItemType") + type: Annotated[Literal["input_image"], Field(title="InputImageContentItemType")] -class Type16(Enum): - output_text = "output_text" - - -class ContentItem3(BaseModel): +class OutputTextContentItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type16 = Field(..., title="OutputTextContentItemType") + type: Annotated[Literal["output_text"], Field(title="OutputTextContentItemType")] -class ContentItem(RootModel[ContentItem1 | ContentItem2 | ContentItem3]): +class ContentItem( + RootModel[InputTextContentItem | InputImageContentItem | OutputTextContentItem] +): model_config = ConfigDict( populate_by_name=True, ) - root: ContentItem1 | ContentItem2 | ContentItem3 + root: InputTextContentItem | InputImageContentItem | OutputTextContentItem class ContextCompactedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class CreditsSnapshot(BaseModel): @@ -943,7 +741,7 @@ class CreditsSnapshot(BaseModel): populate_by_name=True, ) balance: str | None = None - has_credits: bool = Field(..., alias="hasCredits") + has_credits: Annotated[bool, Field(alias="hasCredits")] unlimited: bool @@ -962,52 +760,64 @@ class DeprecationNoticeNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - details: str | None = Field( - None, - description="Optional extra guidance, such as migration steps or rationale.", - ) - summary: str = Field(..., description="Concise summary of what is deprecated.") + details: Annotated[ + str | None, + Field( + description="Optional extra guidance, such as migration steps or rationale." + ), + ] = None + summary: Annotated[str, Field(description="Concise summary of what is deprecated.")] class Duration(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - nanos: conint(ge=0) - secs: conint(ge=0) + nanos: Annotated[int, Field(ge=0)] + secs: Annotated[int, Field(ge=0)] -class Type17(Enum): - input_text = "inputText" - - -class DynamicToolCallOutputContentItem1(BaseModel): +class InputTextDynamicToolCallOutputContentItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type17 = Field(..., title="InputTextDynamicToolCallOutputContentItemType") + type: Annotated[ + Literal["inputText"], + Field(title="InputTextDynamicToolCallOutputContentItemType"), + ] -class Type18(Enum): - input_image = "inputImage" - - -class DynamicToolCallOutputContentItem2(BaseModel): +class InputImageDynamicToolCallOutputContentItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - image_url: str = Field(..., alias="imageUrl") - type: Type18 = Field(..., title="InputImageDynamicToolCallOutputContentItemType") + image_url: Annotated[str, Field(alias="imageUrl")] + type: Annotated[ + Literal["inputImage"], + Field(title="InputImageDynamicToolCallOutputContentItemType"), + ] class DynamicToolCallOutputContentItem( - RootModel[DynamicToolCallOutputContentItem1 | DynamicToolCallOutputContentItem2] + RootModel[ + InputTextDynamicToolCallOutputContentItem + | InputImageDynamicToolCallOutputContentItem + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: DynamicToolCallOutputContentItem1 | DynamicToolCallOutputContentItem2 + root: ( + InputTextDynamicToolCallOutputContentItem + | InputImageDynamicToolCallOutputContentItem + ) + + +class DynamicToolCallStatus(Enum): + in_progress = "inProgress" + completed = "completed" + failed = "failed" class DynamicToolSpec(BaseModel): @@ -1015,287 +825,194 @@ class DynamicToolSpec(BaseModel): populate_by_name=True, ) description: str - input_schema: Any = Field(..., alias="inputSchema") + input_schema: Annotated[Any, Field(alias="inputSchema")] name: str -class Mode(Enum): - form = "form" - - -class ElicitationRequest1(BaseModel): +class FormElicitationRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - field_meta: Any | None = Field(None, alias="_meta") + field_meta: Annotated[Any | None, Field(alias="_meta")] = None message: str - mode: Mode + mode: Annotated[Literal["form"], Field(title="FormElicitationRequestMode")] requested_schema: Any -class Mode1(Enum): - url = "url" - - -class ElicitationRequest2(BaseModel): +class UrlElicitationRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - field_meta: Any | None = Field(None, alias="_meta") + field_meta: Annotated[Any | None, Field(alias="_meta")] = None elicitation_id: str message: str - mode: Mode1 + mode: Annotated[Literal["url"], Field(title="UrlElicitationRequestMode")] url: str -class ElicitationRequest(RootModel[ElicitationRequest1 | ElicitationRequest2]): +class ElicitationRequest(RootModel[FormElicitationRequest | UrlElicitationRequest]): model_config = ConfigDict( populate_by_name=True, ) - root: ElicitationRequest1 | ElicitationRequest2 + root: FormElicitationRequest | UrlElicitationRequest -class Type19(Enum): - error = "error" - - -class EventMsg1(BaseModel): +class ErrorEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) codex_error_info: CodexErrorInfo | None = None message: str - type: Type19 = Field(..., title="ErrorEventMsgType") + type: Annotated[Literal["error"], Field(title="ErrorEventMsgType")] -class Type20(Enum): - warning = "warning" - - -class EventMsg2(BaseModel): +class WarningEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) message: str - type: Type20 = Field(..., title="WarningEventMsgType") + type: Annotated[Literal["warning"], Field(title="WarningEventMsgType")] -class Type21(Enum): - realtime_conversation_started = "realtime_conversation_started" - - -class EventMsg3(BaseModel): +class RealtimeConversationStartedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) session_id: str | None = None - type: Type21 = Field(..., title="RealtimeConversationStartedEventMsgType") + type: Annotated[ + Literal["realtime_conversation_started"], + Field(title="RealtimeConversationStartedEventMsgType"), + ] -class Type22(Enum): - realtime_conversation_realtime = "realtime_conversation_realtime" - - -class Type23(Enum): - realtime_conversation_closed = "realtime_conversation_closed" - - -class EventMsg5(BaseModel): +class RealtimeConversationClosedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) reason: str | None = None - type: Type23 = Field(..., title="RealtimeConversationClosedEventMsgType") + type: Annotated[ + Literal["realtime_conversation_closed"], + Field(title="RealtimeConversationClosedEventMsgType"), + ] -class Type24(Enum): - model_reroute = "model_reroute" - - -class Type25(Enum): - context_compacted = "context_compacted" - - -class EventMsg7(BaseModel): +class ContextCompactedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type25 = Field(..., title="ContextCompactedEventMsgType") + type: Annotated[ + Literal["context_compacted"], Field(title="ContextCompactedEventMsgType") + ] -class Type26(Enum): - thread_rolled_back = "thread_rolled_back" - - -class EventMsg8(BaseModel): +class ThreadRolledBackEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - num_turns: conint(ge=0) = Field( - ..., description="Number of user turns that were removed from context." - ) - type: Type26 = Field(..., title="ThreadRolledBackEventMsgType") + num_turns: Annotated[ + int, + Field(description="Number of user turns that were removed from context.", ge=0), + ] + type: Annotated[ + Literal["thread_rolled_back"], Field(title="ThreadRolledBackEventMsgType") + ] -class Type27(Enum): - task_started = "task_started" - - -class Type28(Enum): - task_complete = "task_complete" - - -class EventMsg10(BaseModel): +class TaskCompleteEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) last_agent_message: str | None = None turn_id: str - type: Type28 = Field(..., title="TaskCompleteEventMsgType") + type: Annotated[Literal["task_complete"], Field(title="TaskCompleteEventMsgType")] -class Type29(Enum): - token_count = "token_count" - - -class Type30(Enum): - agent_message = "agent_message" - - -class Type31(Enum): - user_message = "user_message" - - -class Type32(Enum): - agent_message_delta = "agent_message_delta" - - -class EventMsg14(BaseModel): +class AgentMessageDeltaEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) delta: str - type: Type32 = Field(..., title="AgentMessageDeltaEventMsgType") + type: Annotated[ + Literal["agent_message_delta"], Field(title="AgentMessageDeltaEventMsgType") + ] -class Type33(Enum): - agent_reasoning = "agent_reasoning" - - -class EventMsg15(BaseModel): +class AgentReasoningEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type33 = Field(..., title="AgentReasoningEventMsgType") + type: Annotated[ + Literal["agent_reasoning"], Field(title="AgentReasoningEventMsgType") + ] -class Type34(Enum): - agent_reasoning_delta = "agent_reasoning_delta" - - -class EventMsg16(BaseModel): +class AgentReasoningDeltaEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) delta: str - type: Type34 = Field(..., title="AgentReasoningDeltaEventMsgType") + type: Annotated[ + Literal["agent_reasoning_delta"], Field(title="AgentReasoningDeltaEventMsgType") + ] -class Type35(Enum): - agent_reasoning_raw_content = "agent_reasoning_raw_content" - - -class EventMsg17(BaseModel): +class AgentReasoningRawContentEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type35 = Field(..., title="AgentReasoningRawContentEventMsgType") + type: Annotated[ + Literal["agent_reasoning_raw_content"], + Field(title="AgentReasoningRawContentEventMsgType"), + ] -class Type36(Enum): - agent_reasoning_raw_content_delta = "agent_reasoning_raw_content_delta" - - -class EventMsg18(BaseModel): +class AgentReasoningRawContentDeltaEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) delta: str - type: Type36 = Field(..., title="AgentReasoningRawContentDeltaEventMsgType") + type: Annotated[ + Literal["agent_reasoning_raw_content_delta"], + Field(title="AgentReasoningRawContentDeltaEventMsgType"), + ] -class Type37(Enum): - agent_reasoning_section_break = "agent_reasoning_section_break" - - -class EventMsg19(BaseModel): +class AgentReasoningSectionBreakEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) item_id: str | None = "" summary_index: int | None = 0 - type: Type37 = Field(..., title="AgentReasoningSectionBreakEventMsgType") + type: Annotated[ + Literal["agent_reasoning_section_break"], + Field(title="AgentReasoningSectionBreakEventMsgType"), + ] -class Type38(Enum): - session_configured = "session_configured" - - -class Type39(Enum): - thread_name_updated = "thread_name_updated" - - -class Type40(Enum): - mcp_startup_update = "mcp_startup_update" - - -class Type41(Enum): - mcp_startup_complete = "mcp_startup_complete" - - -class Type42(Enum): - mcp_tool_call_begin = "mcp_tool_call_begin" - - -class Type43(Enum): - mcp_tool_call_end = "mcp_tool_call_end" - - -class Type44(Enum): - web_search_begin = "web_search_begin" - - -class EventMsg26(BaseModel): +class WebSearchBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) call_id: str - type: Type44 = Field(..., title="WebSearchBeginEventMsgType") + type: Annotated[ + Literal["web_search_begin"], Field(title="WebSearchBeginEventMsgType") + ] -class Type45(Enum): - web_search_end = "web_search_end" - - -class Type46(Enum): - image_generation_begin = "image_generation_begin" - - -class EventMsg28(BaseModel): +class ImageGenerationBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) call_id: str - type: Type46 = Field(..., title="ImageGenerationBeginEventMsgType") + type: Annotated[ + Literal["image_generation_begin"], + Field(title="ImageGenerationBeginEventMsgType"), + ] -class Type47(Enum): - image_generation_end = "image_generation_end" - - -class EventMsg29(BaseModel): +class ImageGenerationEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -1304,312 +1021,202 @@ class EventMsg29(BaseModel): revised_prompt: str | None = None saved_path: str | None = None status: str - type: Type47 = Field(..., title="ImageGenerationEndEventMsgType") + type: Annotated[ + Literal["image_generation_end"], Field(title="ImageGenerationEndEventMsgType") + ] -class Type48(Enum): - exec_command_begin = "exec_command_begin" - - -class Type49(Enum): - exec_command_output_delta = "exec_command_output_delta" - - -class Type50(Enum): - terminal_interaction = "terminal_interaction" - - -class EventMsg32(BaseModel): +class TerminalInteractionEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., description="Identifier for the ExecCommandBegin that produced this chunk." - ) - process_id: str = Field( - ..., description="Process id associated with the running command." - ) - stdin: str = Field(..., description="Stdin sent to the running session.") - type: Type50 = Field(..., title="TerminalInteractionEventMsgType") + call_id: Annotated[ + str, + Field( + description="Identifier for the ExecCommandBegin that produced this chunk." + ), + ] + process_id: Annotated[ + str, Field(description="Process id associated with the running command.") + ] + stdin: Annotated[str, Field(description="Stdin sent to the running session.")] + type: Annotated[ + Literal["terminal_interaction"], Field(title="TerminalInteractionEventMsgType") + ] -class Type51(Enum): - exec_command_end = "exec_command_end" - - -class Type52(Enum): - view_image_tool_call = "view_image_tool_call" - - -class EventMsg34(BaseModel): +class ViewImageToolCallEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the originating tool call.") - path: str = Field(..., description="Local filesystem path provided to the tool.") - type: Type52 = Field(..., title="ViewImageToolCallEventMsgType") + call_id: Annotated[ + str, Field(description="Identifier for the originating tool call.") + ] + path: Annotated[ + str, Field(description="Local filesystem path provided to the tool.") + ] + type: Annotated[ + Literal["view_image_tool_call"], Field(title="ViewImageToolCallEventMsgType") + ] -class Type53(Enum): - exec_approval_request = "exec_approval_request" - - -class Type54(Enum): - request_permissions = "request_permissions" - - -class Type55(Enum): - request_user_input = "request_user_input" - - -class Type56(Enum): - dynamic_tool_call_request = "dynamic_tool_call_request" - - -class EventMsg38(BaseModel): +class DynamicToolCallRequestEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) arguments: Any - call_id: str = Field(..., alias="callId") + call_id: Annotated[str, Field(alias="callId")] tool: str - turn_id: str = Field(..., alias="turnId") - type: Type56 = Field(..., title="DynamicToolCallRequestEventMsgType") + turn_id: Annotated[str, Field(alias="turnId")] + type: Annotated[ + Literal["dynamic_tool_call_request"], + Field(title="DynamicToolCallRequestEventMsgType"), + ] -class Type57(Enum): - dynamic_tool_call_response = "dynamic_tool_call_response" - - -class EventMsg39(BaseModel): +class DynamicToolCallResponseEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - arguments: Any = Field(..., description="Dynamic tool call arguments.") - call_id: str = Field( - ..., description="Identifier for the corresponding DynamicToolCallRequest." - ) - content_items: List[DynamicToolCallOutputContentItem] = Field( - ..., description="Dynamic tool response content items." - ) - duration: Duration = Field( - ..., description="The duration of the dynamic tool call." - ) - error: str | None = Field( - None, - description="Optional error text when the tool call failed before producing a response.", - ) - success: bool = Field(..., description="Whether the tool call succeeded.") - tool: str = Field(..., description="Dynamic tool name.") - turn_id: str = Field( - ..., description="Turn ID that this dynamic tool call belongs to." - ) - type: Type57 = Field(..., title="DynamicToolCallResponseEventMsgType") + arguments: Annotated[Any, Field(description="Dynamic tool call arguments.")] + call_id: Annotated[ + str, + Field(description="Identifier for the corresponding DynamicToolCallRequest."), + ] + content_items: Annotated[ + list[DynamicToolCallOutputContentItem], + Field(description="Dynamic tool response content items."), + ] + duration: Annotated[ + Duration, Field(description="The duration of the dynamic tool call.") + ] + error: Annotated[ + str | None, + Field( + description="Optional error text when the tool call failed before producing a response." + ), + ] = None + success: Annotated[bool, Field(description="Whether the tool call succeeded.")] + tool: Annotated[str, Field(description="Dynamic tool name.")] + turn_id: Annotated[ + str, Field(description="Turn ID that this dynamic tool call belongs to.") + ] + type: Annotated[ + Literal["dynamic_tool_call_response"], + Field(title="DynamicToolCallResponseEventMsgType"), + ] -class Type58(Enum): - elicitation_request = "elicitation_request" - - -class Type59(Enum): - apply_patch_approval_request = "apply_patch_approval_request" - - -class Type60(Enum): - deprecation_notice = "deprecation_notice" - - -class EventMsg42(BaseModel): +class DeprecationNoticeEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - details: str | None = Field( - None, - description="Optional extra guidance, such as migration steps or rationale.", - ) - summary: str = Field(..., description="Concise summary of what is deprecated.") - type: Type60 = Field(..., title="DeprecationNoticeEventMsgType") + details: Annotated[ + str | None, + Field( + description="Optional extra guidance, such as migration steps or rationale." + ), + ] = None + summary: Annotated[str, Field(description="Concise summary of what is deprecated.")] + type: Annotated[ + Literal["deprecation_notice"], Field(title="DeprecationNoticeEventMsgType") + ] -class Type61(Enum): - background_event = "background_event" - - -class EventMsg43(BaseModel): +class BackgroundEventEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) message: str - type: Type61 = Field(..., title="BackgroundEventEventMsgType") + type: Annotated[ + Literal["background_event"], Field(title="BackgroundEventEventMsgType") + ] -class Type62(Enum): - undo_started = "undo_started" - - -class EventMsg44(BaseModel): +class UndoStartedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) message: str | None = None - type: Type62 = Field(..., title="UndoStartedEventMsgType") + type: Annotated[Literal["undo_started"], Field(title="UndoStartedEventMsgType")] -class Type63(Enum): - undo_completed = "undo_completed" - - -class EventMsg45(BaseModel): +class UndoCompletedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) message: str | None = None success: bool - type: Type63 = Field(..., title="UndoCompletedEventMsgType") + type: Annotated[Literal["undo_completed"], Field(title="UndoCompletedEventMsgType")] -class Type64(Enum): - stream_error = "stream_error" - - -class EventMsg46(BaseModel): +class StreamErrorEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - additional_details: str | None = Field( - None, - description="Optional details about the underlying stream failure (often the same human-readable message that is surfaced as the terminal error if retries are exhausted).", - ) + additional_details: Annotated[ + str | None, + Field( + description="Optional details about the underlying stream failure (often the same human-readable message that is surfaced as the terminal error if retries are exhausted)." + ), + ] = None codex_error_info: CodexErrorInfo | None = None message: str - type: Type64 = Field(..., title="StreamErrorEventMsgType") + type: Annotated[Literal["stream_error"], Field(title="StreamErrorEventMsgType")] -class Type65(Enum): - patch_apply_begin = "patch_apply_begin" - - -class Type66(Enum): - patch_apply_end = "patch_apply_end" - - -class Type67(Enum): - turn_diff = "turn_diff" - - -class EventMsg49(BaseModel): +class TurnDiffEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type67 = Field(..., title="TurnDiffEventMsgType") + type: Annotated[Literal["turn_diff"], Field(title="TurnDiffEventMsgType")] unified_diff: str -class Type68(Enum): - get_history_entry_response = "get_history_entry_response" - - -class Type69(Enum): - mcp_list_tools_response = "mcp_list_tools_response" - - -class Type70(Enum): - list_custom_prompts_response = "list_custom_prompts_response" - - -class EventMsg52(BaseModel): +class ListCustomPromptsResponseEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - custom_prompts: List[CustomPrompt] - type: Type70 = Field(..., title="ListCustomPromptsResponseEventMsgType") + custom_prompts: list[CustomPrompt] + type: Annotated[ + Literal["list_custom_prompts_response"], + Field(title="ListCustomPromptsResponseEventMsgType"), + ] -class Type71(Enum): - list_skills_response = "list_skills_response" - - -class Type72(Enum): - list_remote_skills_response = "list_remote_skills_response" - - -class Type73(Enum): - remote_skill_downloaded = "remote_skill_downloaded" - - -class EventMsg55(BaseModel): +class RemoteSkillDownloadedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str name: str path: str - type: Type73 = Field(..., title="RemoteSkillDownloadedEventMsgType") + type: Annotated[ + Literal["remote_skill_downloaded"], + Field(title="RemoteSkillDownloadedEventMsgType"), + ] -class Type74(Enum): - skills_update_available = "skills_update_available" - - -class EventMsg56(BaseModel): +class SkillsUpdateAvailableEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type74 = Field(..., title="SkillsUpdateAvailableEventMsgType") + type: Annotated[ + Literal["skills_update_available"], + Field(title="SkillsUpdateAvailableEventMsgType"), + ] -class Type75(Enum): - plan_update = "plan_update" - - -class Type76(Enum): - turn_aborted = "turn_aborted" - - -class Type77(Enum): - shutdown_complete = "shutdown_complete" - - -class EventMsg59(BaseModel): +class ShutdownCompleteEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type77 = Field(..., title="ShutdownCompleteEventMsgType") + type: Annotated[ + Literal["shutdown_complete"], Field(title="ShutdownCompleteEventMsgType") + ] -class Type78(Enum): - entered_review_mode = "entered_review_mode" - - -class Type79(Enum): - exited_review_mode = "exited_review_mode" - - -class Type80(Enum): - raw_response_item = "raw_response_item" - - -class Type81(Enum): - item_started = "item_started" - - -class Type82(Enum): - item_completed = "item_completed" - - -class Type83(Enum): - hook_started = "hook_started" - - -class Type84(Enum): - hook_completed = "hook_completed" - - -class Type85(Enum): - agent_message_content_delta = "agent_message_content_delta" - - -class EventMsg67(BaseModel): +class AgentMessageContentDeltaEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -1617,14 +1224,13 @@ class EventMsg67(BaseModel): item_id: str thread_id: str turn_id: str - type: Type85 = Field(..., title="AgentMessageContentDeltaEventMsgType") + type: Annotated[ + Literal["agent_message_content_delta"], + Field(title="AgentMessageContentDeltaEventMsgType"), + ] -class Type86(Enum): - plan_delta = "plan_delta" - - -class EventMsg68(BaseModel): +class PlanDeltaEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -1632,14 +1238,10 @@ class EventMsg68(BaseModel): item_id: str thread_id: str turn_id: str - type: Type86 = Field(..., title="PlanDeltaEventMsgType") + type: Annotated[Literal["plan_delta"], Field(title="PlanDeltaEventMsgType")] -class Type87(Enum): - reasoning_content_delta = "reasoning_content_delta" - - -class EventMsg69(BaseModel): +class ReasoningContentDeltaEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -1648,14 +1250,13 @@ class EventMsg69(BaseModel): summary_index: int | None = 0 thread_id: str turn_id: str - type: Type87 = Field(..., title="ReasoningContentDeltaEventMsgType") + type: Annotated[ + Literal["reasoning_content_delta"], + Field(title="ReasoningContentDeltaEventMsgType"), + ] -class Type88(Enum): - reasoning_raw_content_delta = "reasoning_raw_content_delta" - - -class EventMsg70(BaseModel): +class ReasoningRawContentDeltaEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -1664,47 +1265,10 @@ class EventMsg70(BaseModel): item_id: str thread_id: str turn_id: str - type: Type88 = Field(..., title="ReasoningRawContentDeltaEventMsgType") - - -class Type89(Enum): - collab_agent_spawn_begin = "collab_agent_spawn_begin" - - -class Type90(Enum): - collab_agent_spawn_end = "collab_agent_spawn_end" - - -class Type91(Enum): - collab_agent_interaction_begin = "collab_agent_interaction_begin" - - -class Type92(Enum): - collab_agent_interaction_end = "collab_agent_interaction_end" - - -class Type93(Enum): - collab_waiting_begin = "collab_waiting_begin" - - -class Type94(Enum): - collab_waiting_end = "collab_waiting_end" - - -class Type95(Enum): - collab_close_begin = "collab_close_begin" - - -class Type96(Enum): - collab_close_end = "collab_close_end" - - -class Type97(Enum): - collab_resume_begin = "collab_resume_begin" - - -class Type98(Enum): - collab_resume_end = "collab_resume_end" + type: Annotated[ + Literal["reasoning_raw_content_delta"], + Field(title="ReasoningRawContentDeltaEventMsgType"), + ] class ExecApprovalRequestSkillMetadata(BaseModel): @@ -1727,17 +1291,26 @@ class ExecCommandStatus(Enum): declined = "declined" +class ExecOutputStream(Enum): + stdout = "stdout" + stderr = "stderr" + + class ExperimentalFeatureListParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cursor: str | None = Field( - None, description="Opaque pagination cursor returned by a previous call." - ) - limit: conint(ge=0) | None = Field( - None, - description="Optional page size; defaults to a reasonable server-side value.", - ) + cursor: Annotated[ + str | None, + Field(description="Opaque pagination cursor returned by a previous call."), + ] = None + limit: Annotated[ + int | None, + Field( + description="Optional page size; defaults to a reasonable server-side value.", + ge=0, + ), + ] = None class ExperimentalFeatureStage(Enum): @@ -1752,18 +1325,26 @@ class ExternalAgentConfigDetectParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cwds: List[str] | None = Field( - None, - description="Zero or more working directories to include for repo-scoped detection.", - ) - include_home: bool | None = Field( - None, - alias="includeHome", - description="If true, include detection under the user's home (~/.claude, ~/.codex, etc.).", - ) + cwds: Annotated[ + list[str] | None, + Field( + description="Zero or more working directories to include for repo-scoped detection." + ), + ] = None + include_home: Annotated[ + bool | None, + Field( + alias="includeHome", + description="If true, include detection under the user's home (~/.claude, ~/.codex, etc.).", + ), + ] = None -ExternalAgentConfigImportResponse = CodexAppServerProtocolV2 +class ExternalAgentConfigImportResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) class ExternalAgentConfigMigrationItemType(Enum): @@ -1778,72 +1359,67 @@ class FeedbackUploadParams(BaseModel): populate_by_name=True, ) classification: str - extra_log_files: List[str] | None = Field(None, alias="extraLogFiles") - include_logs: bool = Field(..., alias="includeLogs") + extra_log_files: Annotated[list[str] | None, Field(alias="extraLogFiles")] = None + include_logs: Annotated[bool, Field(alias="includeLogs")] reason: str | None = None - thread_id: str | None = Field(None, alias="threadId") + thread_id: Annotated[str | None, Field(alias="threadId")] = None class FeedbackUploadResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] -class Type99(Enum): - add = "add" - - -class FileChange1(BaseModel): +class AddFileChange(BaseModel): model_config = ConfigDict( populate_by_name=True, ) content: str - type: Type99 = Field(..., title="AddFileChangeType") + type: Annotated[Literal["add"], Field(title="AddFileChangeType")] -class Type100(Enum): - delete = "delete" - - -class FileChange2(BaseModel): +class DeleteFileChange(BaseModel): model_config = ConfigDict( populate_by_name=True, ) content: str - type: Type100 = Field(..., title="DeleteFileChangeType") + type: Annotated[Literal["delete"], Field(title="DeleteFileChangeType")] -class Type101(Enum): - update = "update" - - -class FileChange3(BaseModel): +class UpdateFileChange(BaseModel): model_config = ConfigDict( populate_by_name=True, ) move_path: str | None = None - type: Type101 = Field(..., title="UpdateFileChangeType") + type: Annotated[Literal["update"], Field(title="UpdateFileChangeType")] unified_diff: str -class FileChange(RootModel[FileChange1 | FileChange2 | FileChange3]): +class FileChange(RootModel[AddFileChange | DeleteFileChange | UpdateFileChange]): model_config = ConfigDict( populate_by_name=True, ) - root: FileChange1 | FileChange2 | FileChange3 + root: AddFileChange | DeleteFileChange | UpdateFileChange -FileChangeOutputDeltaNotification = AgentMessageDeltaNotification +class FileChangeOutputDeltaNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + delta: str + item_id: Annotated[str, Field(alias="itemId")] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class FileSystemPermissions(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - read: List[AbsolutePathBuf] | None = None - write: List[AbsolutePathBuf] | None = None + read: list[AbsolutePathBuf] | None = None + write: list[AbsolutePathBuf] | None = None class ForcedLoginMethod(Enum): @@ -1851,21 +1427,30 @@ class ForcedLoginMethod(Enum): api = "api" -class FunctionCallOutputContentItem1(BaseModel): +class InputTextFunctionCallOutputContentItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type14 = Field(..., title="InputTextFunctionCallOutputContentItemType") + type: Annotated[ + Literal["input_text"], Field(title="InputTextFunctionCallOutputContentItemType") + ] class FuzzyFileSearchParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cancellation_token: str | None = Field(None, alias="cancellationToken") + cancellation_token: Annotated[str | None, Field(alias="cancellationToken")] = None query: str - roots: List[str] + roots: list[str] + + +class Indice(RootModel[int]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Annotated[int, Field(ge=0)] class FuzzyFileSearchResult(BaseModel): @@ -1873,37 +1458,39 @@ class FuzzyFileSearchResult(BaseModel): populate_by_name=True, ) file_name: str - indices: List[conint(ge=0)] | None = None + indices: list[Indice] | None = None path: str root: str - score: conint(ge=0) + score: Annotated[int, Field(ge=0)] class FuzzyFileSearchSessionCompletedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - session_id: str = Field(..., alias="sessionId") + session_id: Annotated[str, Field(alias="sessionId")] class FuzzyFileSearchSessionUpdatedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - files: List[FuzzyFileSearchResult] + files: list[FuzzyFileSearchResult] query: str - session_id: str = Field(..., alias="sessionId") + session_id: Annotated[str, Field(alias="sessionId")] class GetAccountParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - refresh_token: bool | None = Field( - False, - alias="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`.", - ) + refresh_token: Annotated[ + bool | None, + Field( + alias="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`.", + ), + ] = False class GhostCommit(BaseModel): @@ -1912,8 +1499,8 @@ class GhostCommit(BaseModel): ) id: str parent: str | None = None - preexisting_untracked_dirs: List[str] - preexisting_untracked_files: List[str] + preexisting_untracked_dirs: list[str] + preexisting_untracked_files: list[str] class GitInfo(BaseModel): @@ -1921,7 +1508,7 @@ class GitInfo(BaseModel): populate_by_name=True, ) branch: str | None = None - origin_url: str | None = Field(None, alias="originUrl") + origin_url: Annotated[str | None, Field(alias="originUrl")] = None sha: str | None = None @@ -1938,7 +1525,7 @@ class HistoryEntry(BaseModel): ) conversation_id: str text: str - ts: conint(ge=0) + ts: Annotated[int, Field(ge=0)] class HookEventName(Enum): @@ -1989,16 +1576,20 @@ class InitializeCapabilities(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - experimental_api: bool | None = Field( - False, - alias="experimentalApi", - description="Opt into receiving experimental API methods and fields.", - ) - opt_out_notification_methods: List[str] | None = Field( - None, - alias="optOutNotificationMethods", - description="Exact notification method names that should be suppressed for this connection (for example `codex/event/session_configured`).", - ) + experimental_api: Annotated[ + bool | None, + Field( + alias="experimentalApi", + description="Opt into receiving experimental API methods and fields.", + ), + ] = False + opt_out_notification_methods: Annotated[ + list[str] | None, + Field( + alias="optOutNotificationMethods", + description="Exact notification method names that should be suppressed for this connection (for example `codex/event/session_configured`).", + ), + ] = None class InitializeParams(BaseModel): @@ -2006,7 +1597,7 @@ class InitializeParams(BaseModel): populate_by_name=True, ) capabilities: InitializeCapabilities | None = None - client_info: ClientInfo = Field(..., alias="clientInfo") + client_info: Annotated[ClientInfo, Field(alias="clientInfo")] class InputModality(Enum): @@ -2018,35 +1609,35 @@ class ListMcpServerStatusParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cursor: str | None = Field( - None, description="Opaque pagination cursor returned by a previous call." - ) - limit: conint(ge=0) | None = Field( - None, description="Optional page size; defaults to a server-defined value." - ) + cursor: Annotated[ + str | None, + Field(description="Opaque pagination cursor returned by a previous call."), + ] = None + limit: Annotated[ + int | None, + Field( + description="Optional page size; defaults to a server-defined value.", ge=0 + ), + ] = None -class Type104(Enum): - exec = "exec" - - -class LocalShellAction1(BaseModel): +class ExecLocalShellAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - command: List[str] - env: Dict[str, Any] | None = None - timeout_ms: conint(ge=0) | None = None - type: Type104 = Field(..., title="ExecLocalShellActionType") + command: list[str] + env: dict[str, Any] | None = None + timeout_ms: Annotated[int | None, Field(ge=0)] = None + type: Annotated[Literal["exec"], Field(title="ExecLocalShellActionType")] user: str | None = None working_directory: str | None = None -class LocalShellAction(RootModel[LocalShellAction1]): +class LocalShellAction(RootModel[ExecLocalShellAction]): model_config = ConfigDict( populate_by_name=True, ) - root: LocalShellAction1 + root: ExecLocalShellAction class LocalShellStatus(Enum): @@ -2055,119 +1646,153 @@ class LocalShellStatus(Enum): incomplete = "incomplete" -class LoginAccountParams1(BaseModel): +class ApiKeyLoginAccountParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - api_key: str = Field(..., alias="apiKey") - type: Type = Field(..., title="ApiKeyv2::LoginAccountParamsType") + api_key: Annotated[str, Field(alias="apiKey")] + type: Annotated[Literal["apiKey"], Field(title="ApiKeyv2::LoginAccountParamsType")] -class LoginAccountParams2(BaseModel): +class ChatgptLoginAccountParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type1 = Field(..., title="Chatgptv2::LoginAccountParamsType") + type: Annotated[ + Literal["chatgpt"], Field(title="Chatgptv2::LoginAccountParamsType") + ] -class Type107(Enum): - chatgpt_auth_tokens = "chatgptAuthTokens" - - -class LoginAccountParams3(BaseModel): +class ChatgptAuthTokensLoginAccountParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - access_token: str = Field( - ..., - alias="accessToken", - description="Access token (JWT) supplied by the client. This token is used for backend API requests and email extraction.", - ) - chatgpt_account_id: str = Field( - ..., - alias="chatgptAccountId", - description="Workspace/account identifier supplied by the client.", - ) - chatgpt_plan_type: str | None = Field( - None, - alias="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: Type107 = Field(..., title="ChatgptAuthTokensv2::LoginAccountParamsType") + access_token: Annotated[ + str, + Field( + alias="accessToken", + description="Access token (JWT) supplied by the client. This token is used for backend API requests and email extraction.", + ), + ] + chatgpt_account_id: Annotated[ + str, + Field( + alias="chatgptAccountId", + description="Workspace/account identifier supplied by the client.", + ), + ] + chatgpt_plan_type: Annotated[ + str | None, + Field( + alias="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`.", + ), + ] = None + type: Annotated[ + Literal["chatgptAuthTokens"], + Field(title="ChatgptAuthTokensv2::LoginAccountParamsType"), + ] class LoginAccountParams( - RootModel[LoginAccountParams1 | LoginAccountParams2 | LoginAccountParams3] + RootModel[ + ApiKeyLoginAccountParams + | ChatgptLoginAccountParams + | ChatgptAuthTokensLoginAccountParams + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: LoginAccountParams1 | LoginAccountParams2 | LoginAccountParams3 = Field( - ..., title="LoginAccountParams" - ) + root: Annotated[ + ApiKeyLoginAccountParams + | ChatgptLoginAccountParams + | ChatgptAuthTokensLoginAccountParams, + Field(title="LoginAccountParams"), + ] -class LoginAccountResponse1(BaseModel): +class ApiKeyLoginAccountResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type = Field(..., title="ApiKeyv2::LoginAccountResponseType") + type: Annotated[ + Literal["apiKey"], Field(title="ApiKeyv2::LoginAccountResponseType") + ] -class LoginAccountResponse2(BaseModel): +class ChatgptLoginAccountResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - auth_url: str = Field( - ..., - alias="authUrl", - description="URL the client should open in a browser to initiate the OAuth flow.", - ) - login_id: str = Field(..., alias="loginId") - type: Type1 = Field(..., title="Chatgptv2::LoginAccountResponseType") + auth_url: Annotated[ + str, + Field( + alias="authUrl", + description="URL the client should open in a browser to initiate the OAuth flow.", + ), + ] + login_id: Annotated[str, Field(alias="loginId")] + type: Annotated[ + Literal["chatgpt"], Field(title="Chatgptv2::LoginAccountResponseType") + ] -class LoginAccountResponse3(BaseModel): +class ChatgptAuthTokensLoginAccountResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type107 = Field(..., title="ChatgptAuthTokensv2::LoginAccountResponseType") + type: Annotated[ + Literal["chatgptAuthTokens"], + Field(title="ChatgptAuthTokensv2::LoginAccountResponseType"), + ] class LoginAccountResponse( - RootModel[LoginAccountResponse1 | LoginAccountResponse2 | LoginAccountResponse3] + RootModel[ + ApiKeyLoginAccountResponse + | ChatgptLoginAccountResponse + | ChatgptAuthTokensLoginAccountResponse + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: LoginAccountResponse1 | LoginAccountResponse2 | LoginAccountResponse3 = Field( - ..., title="LoginAccountResponse" + root: Annotated[ + ApiKeyLoginAccountResponse + | ChatgptLoginAccountResponse + | ChatgptAuthTokensLoginAccountResponse, + Field(title="LoginAccountResponse"), + ] + + +class LogoutAccountResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, ) -LogoutAccountResponse = CodexAppServerProtocolV2 - - -class MacOsAutomationPermission1(Enum): +class MacOsAutomationPermissionValue(Enum): none = "none" all = "all" -class MacOsAutomationPermission2(BaseModel): +class BundleIdsMacOsAutomationPermission(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - bundle_ids: List[str] + bundle_ids: list[str] class MacOsAutomationPermission( - RootModel[MacOsAutomationPermission1 | MacOsAutomationPermission2] + RootModel[MacOsAutomationPermissionValue | BundleIdsMacOsAutomationPermission] ): model_config = ConfigDict( populate_by_name=True, ) - root: MacOsAutomationPermission1 | MacOsAutomationPermission2 + root: MacOsAutomationPermissionValue | BundleIdsMacOsAutomationPermission class MacOsPreferencesPermission(Enum): @@ -2181,9 +1806,7 @@ class MacOsSeatbeltProfileExtensions(BaseModel): populate_by_name=True, ) macos_accessibility: bool | None = False - macos_automation: MacOsAutomationPermission | None = Field( - default_factory=lambda: MacOsAutomationPermission.model_validate("none") - ) + macos_automation: Annotated[MacOsAutomationPermission | None, Field()] = "none" macos_calendar: bool | None = False macos_preferences: MacOsPreferencesPermission | None = "read_only" @@ -2199,11 +1822,15 @@ class McpInvocation(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - arguments: Any | None = Field(None, description="Arguments to the tool call.") - server: str = Field( - ..., description="Name of the MCP server as defined in the config." - ) - tool: str = Field(..., description="Name of the tool as given by the MCP server.") + arguments: Annotated[ + Any | None, Field(description="Arguments to the tool call.") + ] = None + server: Annotated[ + str, Field(description="Name of the MCP server as defined in the config.") + ] + tool: Annotated[ + str, Field(description="Name of the tool as given by the MCP server.") + ] class McpServerOauthLoginCompletedNotification(BaseModel): @@ -2220,18 +1847,22 @@ class McpServerOauthLoginParams(BaseModel): populate_by_name=True, ) name: str - scopes: List[str] | None = None - timeout_secs: int | None = Field(None, alias="timeoutSecs") + scopes: list[str] | None = None + timeout_secs: Annotated[int | None, Field(alias="timeoutSecs")] = None class McpServerOauthLoginResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - authorization_url: str = Field(..., alias="authorizationUrl") + authorization_url: Annotated[str, Field(alias="authorizationUrl")] -McpServerRefreshResponse = CodexAppServerProtocolV2 +class McpServerRefreshResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) class McpStartupFailure(BaseModel): @@ -2242,60 +1873,54 @@ class McpStartupFailure(BaseModel): server: str -class State(Enum): - starting = "starting" - - -class McpStartupStatus1(BaseModel): +class StartingMcpStartupStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - state: State + state: Annotated[Literal["starting"], Field(title="StartingMcpStartupStatusState")] -class State1(Enum): - ready = "ready" - - -class McpStartupStatus2(BaseModel): +class ReadyMcpStartupStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - state: State1 + state: Annotated[Literal["ready"], Field(title="ReadyMcpStartupStatusState")] -class State2(Enum): - failed = "failed" - - -class McpStartupStatus3(BaseModel): +class FailedMcpStartupStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) error: str - state: State2 + state: Annotated[Literal["failed"], Field(title="FailedMcpStartupStatusState")] -class State3(Enum): - cancelled = "cancelled" - - -class McpStartupStatus4(BaseModel): +class CancelledMcpStartupStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - state: State3 + state: Annotated[ + Literal["cancelled"], Field(title="CancelledMcpStartupStatusState") + ] class McpStartupStatus( RootModel[ - McpStartupStatus1 | McpStartupStatus2 | McpStartupStatus3 | McpStartupStatus4 + StartingMcpStartupStatus + | ReadyMcpStartupStatus + | FailedMcpStartupStatus + | CancelledMcpStartupStatus ] ): model_config = ConfigDict( populate_by_name=True, ) - root: McpStartupStatus1 | McpStartupStatus2 | McpStartupStatus3 | McpStartupStatus4 + root: ( + StartingMcpStartupStatus + | ReadyMcpStartupStatus + | FailedMcpStartupStatus + | CancelledMcpStartupStatus + ) class McpToolCallError(BaseModel): @@ -2309,18 +1934,24 @@ class McpToolCallProgressNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - item_id: str = Field(..., alias="itemId") + item_id: Annotated[str, Field(alias="itemId")] message: str - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class McpToolCallResult(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - content: List - structured_content: Any | None = Field(None, alias="structuredContent") + content: list + structured_content: Annotated[Any | None, Field(alias="structuredContent")] = None + + +class McpToolCallStatus(Enum): + in_progress = "inProgress" + completed = "completed" + failed = "failed" class MergeStrategy(Enum): @@ -2338,50 +1969,63 @@ class ModeKind(Enum): default = "default" -ModelAvailabilityNux = McpToolCallError +class ModelAvailabilityNux(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + message: str class ModelListParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cursor: str | None = Field( - None, description="Opaque pagination cursor returned by a previous call." - ) - include_hidden: bool | None = Field( - None, - alias="includeHidden", - description="When true, include models that are hidden from the default picker list.", - ) - limit: conint(ge=0) | None = Field( - None, - description="Optional page size; defaults to a reasonable server-side value.", - ) + cursor: Annotated[ + str | None, + Field(description="Opaque pagination cursor returned by a previous call."), + ] = None + include_hidden: Annotated[ + bool | None, + Field( + alias="includeHidden", + description="When true, include models that are hidden from the default picker list.", + ), + ] = None + limit: Annotated[ + int | None, + Field( + description="Optional page size; defaults to a reasonable server-side value.", + ge=0, + ), + ] = None -class ModelRerouteReason(Enum): - high_risk_cyber_activity = "highRiskCyberActivity" +class ModelRerouteReason(RootModel[Literal["highRiskCyberActivity"]]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Literal["highRiskCyberActivity"] class ModelReroutedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - from_model: str = Field(..., alias="fromModel") + from_model: Annotated[str, Field(alias="fromModel")] reason: ModelRerouteReason - thread_id: str = Field(..., alias="threadId") - to_model: str = Field(..., alias="toModel") - turn_id: str = Field(..., alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + to_model: Annotated[str, Field(alias="toModel")] + turn_id: Annotated[str, Field(alias="turnId")] class ModelUpgradeInfo(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - migration_markdown: str | None = Field(None, alias="migrationMarkdown") + migration_markdown: Annotated[str | None, Field(alias="migrationMarkdown")] = None model: str - model_link: str | None = Field(None, alias="modelLink") - upgrade_copy: str | None = Field(None, alias="upgradeCopy") + model_link: Annotated[str | None, Field(alias="modelLink")] = None + upgrade_copy: Annotated[str | None, Field(alias="upgradeCopy")] = None class NetworkAccess(Enum): @@ -2412,104 +2056,123 @@ class NetworkRequirements(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - allow_local_binding: bool | None = Field(None, alias="allowLocalBinding") - allow_unix_sockets: List[str] | None = Field(None, alias="allowUnixSockets") - allow_upstream_proxy: bool | None = Field(None, alias="allowUpstreamProxy") - allowed_domains: List[str] | None = Field(None, alias="allowedDomains") - dangerously_allow_all_unix_sockets: bool | None = Field( - None, alias="dangerouslyAllowAllUnixSockets" + allow_local_binding: Annotated[bool | None, Field(alias="allowLocalBinding")] = None + allow_unix_sockets: Annotated[list[str] | None, Field(alias="allowUnixSockets")] = ( + None ) - dangerously_allow_non_loopback_proxy: bool | None = Field( - None, alias="dangerouslyAllowNonLoopbackProxy" + allow_upstream_proxy: Annotated[bool | None, Field(alias="allowUpstreamProxy")] = ( + None ) - denied_domains: List[str] | None = Field(None, alias="deniedDomains") + allowed_domains: Annotated[list[str] | None, Field(alias="allowedDomains")] = None + dangerously_allow_all_unix_sockets: Annotated[ + bool | None, Field(alias="dangerouslyAllowAllUnixSockets") + ] = None + dangerously_allow_non_loopback_proxy: Annotated[ + bool | None, Field(alias="dangerouslyAllowNonLoopbackProxy") + ] = None + denied_domains: Annotated[list[str] | None, Field(alias="deniedDomains")] = None enabled: bool | None = None - http_port: conint(ge=0) | None = Field(None, alias="httpPort") - socks_port: conint(ge=0) | None = Field(None, alias="socksPort") + http_port: Annotated[int | None, Field(alias="httpPort", ge=0)] = None + socks_port: Annotated[int | None, Field(alias="socksPort", ge=0)] = None -class ParsedCommand1(BaseModel): +class ReadParsedCommand(BaseModel): model_config = ConfigDict( populate_by_name=True, ) cmd: str name: str - path: str = Field( - ..., - 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: Type3 = Field(..., title="ReadParsedCommandType") + path: Annotated[ + str, + Field( + 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: Annotated[Literal["read"], Field(title="ReadParsedCommandType")] -class Type112(Enum): - list_files = "list_files" - - -class ParsedCommand2(BaseModel): +class ListFilesParsedCommand(BaseModel): model_config = ConfigDict( populate_by_name=True, ) cmd: str path: str | None = None - type: Type112 = Field(..., title="ListFilesParsedCommandType") + type: Annotated[Literal["list_files"], Field(title="ListFilesParsedCommandType")] -class ParsedCommand3(BaseModel): +class SearchParsedCommand(BaseModel): model_config = ConfigDict( populate_by_name=True, ) cmd: str path: str | None = None query: str | None = None - type: Type5 = Field(..., title="SearchParsedCommandType") + type: Annotated[Literal["search"], Field(title="SearchParsedCommandType")] -class ParsedCommand4(BaseModel): +class UnknownParsedCommand(BaseModel): model_config = ConfigDict( populate_by_name=True, ) cmd: str - type: Type6 = Field(..., title="UnknownParsedCommandType") + type: Annotated[Literal["unknown"], Field(title="UnknownParsedCommandType")] class ParsedCommand( - RootModel[ParsedCommand1 | ParsedCommand2 | ParsedCommand3 | ParsedCommand4] + RootModel[ + ReadParsedCommand + | ListFilesParsedCommand + | SearchParsedCommand + | UnknownParsedCommand + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ParsedCommand1 | ParsedCommand2 | ParsedCommand3 | ParsedCommand4 + root: ( + ReadParsedCommand + | ListFilesParsedCommand + | SearchParsedCommand + | UnknownParsedCommand + ) -class PatchChangeKind1(BaseModel): +class PatchApplyStatus(Enum): + in_progress = "inProgress" + completed = "completed" + failed = "failed" + declined = "declined" + + +class AddPatchChangeKind(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type99 = Field(..., title="AddPatchChangeKindType") + type: Annotated[Literal["add"], Field(title="AddPatchChangeKindType")] -class PatchChangeKind2(BaseModel): +class DeletePatchChangeKind(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type100 = Field(..., title="DeletePatchChangeKindType") + type: Annotated[Literal["delete"], Field(title="DeletePatchChangeKindType")] -class PatchChangeKind3(BaseModel): +class UpdatePatchChangeKind(BaseModel): model_config = ConfigDict( populate_by_name=True, ) move_path: str | None = None - type: Type101 = Field(..., title="UpdatePatchChangeKindType") + type: Annotated[Literal["update"], Field(title="UpdatePatchChangeKindType")] class PatchChangeKind( - RootModel[PatchChangeKind1 | PatchChangeKind2 | PatchChangeKind3] + RootModel[AddPatchChangeKind | DeletePatchChangeKind | UpdatePatchChangeKind] ): model_config = ConfigDict( populate_by_name=True, ) - root: PatchChangeKind1 | PatchChangeKind2 | PatchChangeKind3 + root: AddPatchChangeKind | DeletePatchChangeKind | UpdatePatchChangeKind class PermissionProfile(BaseModel): @@ -2527,7 +2190,14 @@ class Personality(Enum): pragmatic = "pragmatic" -PlanDeltaNotification = AgentMessageDeltaNotification +class PlanDeltaNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + delta: str + item_id: Annotated[str, Field(alias="itemId")] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class PlanType(Enum): @@ -2546,64 +2216,62 @@ class PluginInstallParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - marketplace_path: AbsolutePathBuf = Field(..., alias="marketplacePath") - plugin_name: str = Field(..., alias="pluginName") + marketplace_path: Annotated[AbsolutePathBuf, Field(alias="marketplacePath")] + plugin_name: Annotated[str, Field(alias="pluginName")] class PluginInstallResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - apps_needing_auth: List[AppSummary] = Field(..., alias="appsNeedingAuth") + apps_needing_auth: Annotated[list[AppSummary], Field(alias="appsNeedingAuth")] class PluginInterface(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - brand_color: str | None = Field(None, alias="brandColor") - capabilities: List[str] + brand_color: Annotated[str | None, Field(alias="brandColor")] = None + capabilities: list[str] category: str | None = None - composer_icon: AbsolutePathBuf | None = Field(None, alias="composerIcon") - default_prompt: str | None = Field(None, alias="defaultPrompt") - developer_name: str | None = Field(None, alias="developerName") - display_name: str | None = Field(None, alias="displayName") + composer_icon: Annotated[AbsolutePathBuf | None, Field(alias="composerIcon")] = None + default_prompt: Annotated[str | None, Field(alias="defaultPrompt")] = None + developer_name: Annotated[str | None, Field(alias="developerName")] = None + display_name: Annotated[str | None, Field(alias="displayName")] = None logo: AbsolutePathBuf | None = None - long_description: str | None = Field(None, alias="longDescription") - privacy_policy_url: str | None = Field(None, alias="privacyPolicyUrl") - screenshots: List[AbsolutePathBuf] - short_description: str | None = Field(None, alias="shortDescription") - terms_of_service_url: str | None = Field(None, alias="termsOfServiceUrl") - website_url: str | None = Field(None, alias="websiteUrl") + long_description: Annotated[str | None, Field(alias="longDescription")] = None + privacy_policy_url: Annotated[str | None, Field(alias="privacyPolicyUrl")] = None + screenshots: list[AbsolutePathBuf] + short_description: Annotated[str | None, Field(alias="shortDescription")] = None + terms_of_service_url: Annotated[str | None, Field(alias="termsOfServiceUrl")] = None + website_url: Annotated[str | None, Field(alias="websiteUrl")] = None class PluginListParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cwds: List[AbsolutePathBuf] | None = Field( - None, - description="Optional working directories used to discover repo marketplaces. When omitted, only home-scoped marketplaces and the official curated marketplace are considered.", - ) + cwds: Annotated[ + list[AbsolutePathBuf] | None, + Field( + description="Optional working directories used to discover repo marketplaces. When omitted, only home-scoped marketplaces and the official curated marketplace are considered." + ), + ] = None -class Type118(Enum): - local = "local" - - -class PluginSource1(BaseModel): +class LocalPluginSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) path: AbsolutePathBuf - type: Type118 = Field(..., title="LocalPluginSourceType") + type: Annotated[Literal["local"], Field(title="LocalPluginSourceType")] -class PluginSource(RootModel[PluginSource1]): +class PluginSource(RootModel[LocalPluginSource]): model_config = ConfigDict( populate_by_name=True, ) - root: PluginSource1 + root: LocalPluginSource class PluginSummary(BaseModel): @@ -2622,10 +2290,14 @@ class PluginUninstallParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - plugin_id: str = Field(..., alias="pluginId") + plugin_id: Annotated[str, Field(alias="pluginId")] -PluginUninstallResponse = CodexAppServerProtocolV2 +class PluginUninstallResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) class ProductSurface(Enum): @@ -2639,42 +2311,38 @@ class RateLimitWindow(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - resets_at: int | None = Field(None, alias="resetsAt") - used_percent: int = Field(..., alias="usedPercent") - window_duration_mins: int | None = Field(None, alias="windowDurationMins") + resets_at: Annotated[int | None, Field(alias="resetsAt")] = None + used_percent: Annotated[int, Field(alias="usedPercent")] + window_duration_mins: Annotated[int | None, Field(alias="windowDurationMins")] = ( + None + ) -class Type119(Enum): - restricted = "restricted" - - -class ReadOnlyAccess1(BaseModel): +class RestrictedReadOnlyAccess(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - include_platform_defaults: bool | None = Field( - True, alias="includePlatformDefaults" - ) - readable_roots: List[AbsolutePathBuf] | None = Field([], alias="readableRoots") - type: Type119 = Field(..., title="RestrictedReadOnlyAccessType") + include_platform_defaults: Annotated[ + bool | None, Field(alias="includePlatformDefaults") + ] = True + readable_roots: Annotated[ + list[AbsolutePathBuf] | None, Field(alias="readableRoots") + ] = [] + type: Annotated[Literal["restricted"], Field(title="RestrictedReadOnlyAccessType")] -class Type120(Enum): - full_access = "fullAccess" - - -class ReadOnlyAccess2(BaseModel): +class FullAccessReadOnlyAccess(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type120 = Field(..., title="FullAccessReadOnlyAccessType") + type: Annotated[Literal["fullAccess"], Field(title="FullAccessReadOnlyAccessType")] -class ReadOnlyAccess(RootModel[ReadOnlyAccess1 | ReadOnlyAccess2]): +class ReadOnlyAccess(RootModel[RestrictedReadOnlyAccess | FullAccessReadOnlyAccess]): model_config = ConfigDict( populate_by_name=True, ) - root: ReadOnlyAccess1 | ReadOnlyAccess2 + root: RestrictedReadOnlyAccess | FullAccessReadOnlyAccess class RealtimeAudioFrame(BaseModel): @@ -2682,9 +2350,9 @@ class RealtimeAudioFrame(BaseModel): populate_by_name=True, ) data: str - num_channels: conint(ge=0) - sample_rate: conint(ge=0) - samples_per_channel: conint(ge=0) | None = None + num_channels: Annotated[int, Field(ge=0)] + sample_rate: Annotated[int, Field(ge=0)] + samples_per_channel: Annotated[int | None, Field(ge=0)] = None class SessionUpdated(BaseModel): @@ -2695,28 +2363,28 @@ class SessionUpdated(BaseModel): session_id: str -class RealtimeEvent1(BaseModel): +class SessionUpdatedRealtimeEvent(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - session_updated: SessionUpdated = Field(..., alias="SessionUpdated") + session_updated: Annotated[SessionUpdated, Field(alias="SessionUpdated")] -class RealtimeEvent4(BaseModel): +class AudioOutRealtimeEvent(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - audio_out: RealtimeAudioFrame = Field(..., alias="AudioOut") + audio_out: Annotated[RealtimeAudioFrame, Field(alias="AudioOut")] -class RealtimeEvent5(BaseModel): +class ConversationItemAddedRealtimeEvent(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - conversation_item_added: Any = Field(..., alias="ConversationItemAdded") + conversation_item_added: Annotated[Any, Field(alias="ConversationItemAdded")] class ConversationItemDone(BaseModel): @@ -2726,22 +2394,22 @@ class ConversationItemDone(BaseModel): item_id: str -class RealtimeEvent6(BaseModel): +class ConversationItemDoneRealtimeEvent(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - conversation_item_done: ConversationItemDone = Field( - ..., alias="ConversationItemDone" - ) + conversation_item_done: Annotated[ + ConversationItemDone, Field(alias="ConversationItemDone") + ] -class RealtimeEvent8(BaseModel): +class ErrorRealtimeEvent(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - error: str = Field(..., alias="Error") + error: Annotated[str, Field(alias="Error")] class RealtimeTranscriptDelta(BaseModel): @@ -2773,87 +2441,82 @@ class ReasoningEffortOption(BaseModel): populate_by_name=True, ) description: str - reasoning_effort: ReasoningEffort = Field(..., alias="reasoningEffort") + reasoning_effort: Annotated[ReasoningEffort, Field(alias="reasoningEffort")] -class Type121(Enum): - reasoning_text = "reasoning_text" - - -class ReasoningItemContent1(BaseModel): +class ReasoningTextReasoningItemContent(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type121 = Field(..., title="ReasoningTextReasoningItemContentType") + type: Annotated[ + Literal["reasoning_text"], Field(title="ReasoningTextReasoningItemContentType") + ] -class Type122(Enum): - text = "text" - - -class ReasoningItemContent2(BaseModel): +class TextReasoningItemContent(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type122 = Field(..., title="TextReasoningItemContentType") + type: Annotated[Literal["text"], Field(title="TextReasoningItemContentType")] -class ReasoningItemContent(RootModel[ReasoningItemContent1 | ReasoningItemContent2]): +class ReasoningItemContent( + RootModel[ReasoningTextReasoningItemContent | TextReasoningItemContent] +): model_config = ConfigDict( populate_by_name=True, ) - root: ReasoningItemContent1 | ReasoningItemContent2 + root: ReasoningTextReasoningItemContent | TextReasoningItemContent -class Type123(Enum): - summary_text = "summary_text" - - -class ReasoningItemReasoningSummary1(BaseModel): +class SummaryTextReasoningItemReasoningSummary(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - type: Type123 = Field(..., title="SummaryTextReasoningItemReasoningSummaryType") + type: Annotated[ + Literal["summary_text"], + Field(title="SummaryTextReasoningItemReasoningSummaryType"), + ] -class ReasoningItemReasoningSummary(RootModel[ReasoningItemReasoningSummary1]): +class ReasoningItemReasoningSummary( + RootModel[SummaryTextReasoningItemReasoningSummary] +): model_config = ConfigDict( populate_by_name=True, ) - root: ReasoningItemReasoningSummary1 + root: SummaryTextReasoningItemReasoningSummary -class ReasoningSummary1(Enum): +class ReasoningSummaryValue(Enum): auto = "auto" concise = "concise" detailed = "detailed" -class ReasoningSummary2(Enum): - none = "none" - - -class ReasoningSummary(RootModel[ReasoningSummary1 | ReasoningSummary2]): +class ReasoningSummary(RootModel[ReasoningSummaryValue | Literal["none"]]): model_config = ConfigDict( populate_by_name=True, ) - root: ReasoningSummary1 | ReasoningSummary2 = Field( - ..., - 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", - ) + root: Annotated[ + ReasoningSummaryValue | Literal["none"], + Field( + 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" + ), + ] class ReasoningSummaryPartAddedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - item_id: str = Field(..., alias="itemId") - summary_index: int = Field(..., alias="summaryIndex") - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + item_id: Annotated[str, Field(alias="itemId")] + summary_index: Annotated[int, Field(alias="summaryIndex")] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class ReasoningSummaryTextDeltaNotification(BaseModel): @@ -2861,21 +2524,21 @@ class ReasoningSummaryTextDeltaNotification(BaseModel): populate_by_name=True, ) delta: str - item_id: str = Field(..., alias="itemId") - summary_index: int = Field(..., alias="summaryIndex") - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + item_id: Annotated[str, Field(alias="itemId")] + summary_index: Annotated[int, Field(alias="summaryIndex")] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class ReasoningTextDeltaNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - content_index: int = Field(..., alias="contentIndex") + content_index: Annotated[int, Field(alias="contentIndex")] delta: str - item_id: str = Field(..., alias="itemId") - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + item_id: Annotated[str, Field(alias="itemId")] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class RemoteSkillSummary(BaseModel): @@ -2902,19 +2565,22 @@ class RequestUserInputQuestionOption(BaseModel): label: str -class ResidencyRequirement(Enum): - us = "us" +class ResidencyRequirement(RootModel[Literal["us"]]): + model_config = ConfigDict( + populate_by_name=True, + ) + root: Literal["us"] class Resource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - field_meta: Any | None = Field(None, alias="_meta") + field_meta: Annotated[Any | None, Field(alias="_meta")] = None annotations: Any | None = None description: str | None = None - icons: List | None = None - mime_type: str | None = Field(None, alias="mimeType") + icons: list | None = None + mime_type: Annotated[str | None, Field(alias="mimeType")] = None name: str size: int | None = None title: str | None = None @@ -2927,66 +2593,56 @@ class ResourceTemplate(BaseModel): ) annotations: Any | None = None description: str | None = None - mime_type: str | None = Field(None, alias="mimeType") + mime_type: Annotated[str | None, Field(alias="mimeType")] = None name: str title: str | None = None - uri_template: str = Field(..., alias="uriTemplate") + uri_template: Annotated[str, Field(alias="uriTemplate")] -class Type124(Enum): - message = "message" - - -class ResponseItem1(BaseModel): +class MessageResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - content: List[ContentItem] + content: list[ContentItem] end_turn: bool | None = None id: str | None = None phase: MessagePhase | None = None role: str - type: Type124 = Field(..., title="MessageResponseItemType") + type: Annotated[Literal["message"], Field(title="MessageResponseItemType")] -class Type125(Enum): - reasoning = "reasoning" - - -class ResponseItem2(BaseModel): +class ReasoningResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - content: List[ReasoningItemContent] | None = None + content: list[ReasoningItemContent] | None = None encrypted_content: str | None = None id: str - summary: List[ReasoningItemReasoningSummary] - type: Type125 = Field(..., title="ReasoningResponseItemType") + summary: list[ReasoningItemReasoningSummary] + type: Annotated[Literal["reasoning"], Field(title="ReasoningResponseItemType")] -class Type126(Enum): - local_shell_call = "local_shell_call" - - -class ResponseItem3(BaseModel): +class LocalShellCallResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) action: LocalShellAction - call_id: str | None = Field(None, description="Set when using the Responses API.") - id: str | None = Field( - None, - description="Legacy id field retained for compatibility with older payloads.", - ) + call_id: Annotated[ + str | None, Field(description="Set when using the Responses API.") + ] = None + id: Annotated[ + str | None, + Field( + description="Legacy id field retained for compatibility with older payloads." + ), + ] = None status: LocalShellStatus - type: Type126 = Field(..., title="LocalShellCallResponseItemType") + type: Annotated[ + Literal["local_shell_call"], Field(title="LocalShellCallResponseItemType") + ] -class Type127(Enum): - function_call = "function_call" - - -class ResponseItem4(BaseModel): +class FunctionCallResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -2994,18 +2650,12 @@ class ResponseItem4(BaseModel): call_id: str id: str | None = None name: str - type: Type127 = Field(..., title="FunctionCallResponseItemType") + type: Annotated[ + Literal["function_call"], Field(title="FunctionCallResponseItemType") + ] -class Type128(Enum): - function_call_output = "function_call_output" - - -class Type129(Enum): - custom_tool_call = "custom_tool_call" - - -class ResponseItem6(BaseModel): +class CustomToolCallResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -3014,22 +2664,12 @@ class ResponseItem6(BaseModel): input: str name: str status: str | None = None - type: Type129 = Field(..., title="CustomToolCallResponseItemType") + type: Annotated[ + Literal["custom_tool_call"], Field(title="CustomToolCallResponseItemType") + ] -class Type130(Enum): - custom_tool_call_output = "custom_tool_call_output" - - -class Type131(Enum): - web_search_call = "web_search_call" - - -class Type132(Enum): - image_generation_call = "image_generation_call" - - -class ResponseItem9(BaseModel): +class ImageGenerationCallResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -3037,139 +2677,129 @@ class ResponseItem9(BaseModel): result: str revised_prompt: str | None = None status: str - type: Type132 = Field(..., title="ImageGenerationCallResponseItemType") + type: Annotated[ + Literal["image_generation_call"], + Field(title="ImageGenerationCallResponseItemType"), + ] -class Type133(Enum): - ghost_snapshot = "ghost_snapshot" - - -class ResponseItem10(BaseModel): +class GhostSnapshotResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) ghost_commit: GhostCommit - type: Type133 = Field(..., title="GhostSnapshotResponseItemType") + type: Annotated[ + Literal["ghost_snapshot"], Field(title="GhostSnapshotResponseItemType") + ] -class Type134(Enum): - compaction = "compaction" - - -class ResponseItem11(BaseModel): +class CompactionResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) encrypted_content: str - type: Type134 = Field(..., title="CompactionResponseItemType") + type: Annotated[Literal["compaction"], Field(title="CompactionResponseItemType")] -class Type135(Enum): - other = "other" - - -class ResponseItem12(BaseModel): +class OtherResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type135 = Field(..., title="OtherResponseItemType") + type: Annotated[Literal["other"], Field(title="OtherResponseItemType")] -class ResponsesApiWebSearchAction1(BaseModel): +class SearchResponsesApiWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - queries: List[str] | None = None + queries: list[str] | None = None query: str | None = None - type: Type5 = Field(..., title="SearchResponsesApiWebSearchActionType") + type: Annotated[ + Literal["search"], Field(title="SearchResponsesApiWebSearchActionType") + ] -class Type137(Enum): - open_page = "open_page" - - -class ResponsesApiWebSearchAction2(BaseModel): +class OpenPageResponsesApiWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type137 = Field(..., title="OpenPageResponsesApiWebSearchActionType") + type: Annotated[ + Literal["open_page"], Field(title="OpenPageResponsesApiWebSearchActionType") + ] url: str | None = None -class Type138(Enum): - find_in_page = "find_in_page" - - -class ResponsesApiWebSearchAction3(BaseModel): +class FindInPageResponsesApiWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) pattern: str | None = None - type: Type138 = Field(..., title="FindInPageResponsesApiWebSearchActionType") + type: Annotated[ + Literal["find_in_page"], + Field(title="FindInPageResponsesApiWebSearchActionType"), + ] url: str | None = None -class ResponsesApiWebSearchAction4(BaseModel): +class OtherResponsesApiWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type135 = Field(..., title="OtherResponsesApiWebSearchActionType") + type: Annotated[ + Literal["other"], Field(title="OtherResponsesApiWebSearchActionType") + ] class ResponsesApiWebSearchAction( RootModel[ - ResponsesApiWebSearchAction1 - | ResponsesApiWebSearchAction2 - | ResponsesApiWebSearchAction3 - | ResponsesApiWebSearchAction4 + SearchResponsesApiWebSearchAction + | OpenPageResponsesApiWebSearchAction + | FindInPageResponsesApiWebSearchAction + | OtherResponsesApiWebSearchAction ] ): model_config = ConfigDict( populate_by_name=True, ) root: ( - ResponsesApiWebSearchAction1 - | ResponsesApiWebSearchAction2 - | ResponsesApiWebSearchAction3 - | ResponsesApiWebSearchAction4 + SearchResponsesApiWebSearchAction + | OpenPageResponsesApiWebSearchAction + | FindInPageResponsesApiWebSearchAction + | OtherResponsesApiWebSearchAction ) -class ResultOfCallToolResultOrString1(BaseModel): +class OkResultOfCallToolResultOrString(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - ok: CallToolResult = Field(..., alias="Ok") + ok: Annotated[CallToolResult, Field(alias="Ok")] -class ResultOfCallToolResultOrString2(BaseModel): +class ErrResultOfCallToolResultOrString(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - err: str = Field(..., alias="Err") + err: Annotated[str, Field(alias="Err")] class ResultOfCallToolResultOrString( - RootModel[ResultOfCallToolResultOrString1 | ResultOfCallToolResultOrString2] + RootModel[OkResultOfCallToolResultOrString | ErrResultOfCallToolResultOrString] ): model_config = ConfigDict( populate_by_name=True, ) - root: ResultOfCallToolResultOrString1 | ResultOfCallToolResultOrString2 - - -class ReviewDecision1(Enum): - approved = "approved" + root: OkResultOfCallToolResultOrString | ErrResultOfCallToolResultOrString class ApprovedExecpolicyAmendment(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - proposed_execpolicy_amendment: List[str] + proposed_execpolicy_amendment: list[str] -class ReviewDecision2(BaseModel): +class ApprovedExecpolicyAmendmentReviewDecision(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, @@ -3177,84 +2807,75 @@ class ReviewDecision2(BaseModel): approved_execpolicy_amendment: ApprovedExecpolicyAmendment -class ReviewDecision3(Enum): - approved_for_session = "approved_for_session" - - -class ReviewDecision5(Enum): - denied = "denied" - - -class ReviewDecision6(Enum): - abort = "abort" - - class ReviewDelivery(Enum): inline = "inline" detached = "detached" -ReviewLineRange = ByteRange - - -class Type140(Enum): - uncommitted_changes = "uncommittedChanges" - - -class ReviewTarget1(BaseModel): +class ReviewLineRange(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type140 = Field(..., title="UncommittedChangesReviewTargetType") + end: Annotated[int, Field(ge=0)] + start: Annotated[int, Field(ge=0)] -class Type141(Enum): - base_branch = "baseBranch" +class UncommittedChangesReviewTarget(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + type: Annotated[ + Literal["uncommittedChanges"], Field(title="UncommittedChangesReviewTargetType") + ] -class ReviewTarget2(BaseModel): +class BaseBranchReviewTarget(BaseModel): model_config = ConfigDict( populate_by_name=True, ) branch: str - type: Type141 = Field(..., title="BaseBranchReviewTargetType") + type: Annotated[Literal["baseBranch"], Field(title="BaseBranchReviewTargetType")] -class Type142(Enum): - commit = "commit" - - -class ReviewTarget3(BaseModel): +class CommitReviewTarget(BaseModel): model_config = ConfigDict( populate_by_name=True, ) sha: str - title: str | None = Field( - None, - description="Optional human-readable label (e.g., commit subject) for UIs.", - ) - type: Type142 = Field(..., title="CommitReviewTargetType") + title: Annotated[ + str | None, + Field( + description="Optional human-readable label (e.g., commit subject) for UIs." + ), + ] = None + type: Annotated[Literal["commit"], Field(title="CommitReviewTargetType")] -class Type143(Enum): - custom = "custom" - - -class ReviewTarget4(BaseModel): +class CustomReviewTarget(BaseModel): model_config = ConfigDict( populate_by_name=True, ) instructions: str - type: Type143 = Field(..., title="CustomReviewTargetType") + type: Annotated[Literal["custom"], Field(title="CustomReviewTargetType")] class ReviewTarget( - RootModel[ReviewTarget1 | ReviewTarget2 | ReviewTarget3 | ReviewTarget4] + RootModel[ + UncommittedChangesReviewTarget + | BaseBranchReviewTarget + | CommitReviewTarget + | CustomReviewTarget + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ReviewTarget1 | ReviewTarget2 | ReviewTarget3 | ReviewTarget4 + root: ( + UncommittedChangesReviewTarget + | BaseBranchReviewTarget + | CommitReviewTarget + | CustomReviewTarget + ) class SandboxMode(Enum): @@ -3263,70 +2884,73 @@ class SandboxMode(Enum): danger_full_access = "danger-full-access" -class Type144(Enum): - danger_full_access = "dangerFullAccess" - - -class SandboxPolicy1(BaseModel): +class DangerFullAccessSandboxPolicy(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type144 = Field(..., title="DangerFullAccessSandboxPolicyType") + type: Annotated[ + Literal["dangerFullAccess"], Field(title="DangerFullAccessSandboxPolicyType") + ] -class Type145(Enum): - read_only = "readOnly" - - -class SandboxPolicy2(BaseModel): +class ReadOnlySandboxPolicy(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - access: ReadOnlyAccess | None = Field( - default_factory=lambda: ReadOnlyAccess.model_validate({"type": "fullAccess"}) - ) - network_access: bool | None = Field(False, alias="networkAccess") - type: Type145 = Field(..., title="ReadOnlySandboxPolicyType") + access: Annotated[ReadOnlyAccess | None, Field()] = {"type": "fullAccess"} + network_access: Annotated[bool | None, Field(alias="networkAccess")] = False + type: Annotated[Literal["readOnly"], Field(title="ReadOnlySandboxPolicyType")] -class Type146(Enum): - external_sandbox = "externalSandbox" - - -class SandboxPolicy3(BaseModel): +class ExternalSandboxSandboxPolicy(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - network_access: NetworkAccess | None = Field("restricted", alias="networkAccess") - type: Type146 = Field(..., title="ExternalSandboxSandboxPolicyType") + network_access: Annotated[NetworkAccess | None, Field(alias="networkAccess")] = ( + "restricted" + ) + type: Annotated[ + Literal["externalSandbox"], Field(title="ExternalSandboxSandboxPolicyType") + ] -class Type147(Enum): - workspace_write = "workspaceWrite" - - -class SandboxPolicy4(BaseModel): +class WorkspaceWriteSandboxPolicy(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - exclude_slash_tmp: bool | None = Field(False, alias="excludeSlashTmp") - exclude_tmpdir_env_var: bool | None = Field(False, alias="excludeTmpdirEnvVar") - network_access: bool | None = Field(False, alias="networkAccess") - read_only_access: ReadOnlyAccess | None = Field( - default_factory=lambda: ReadOnlyAccess.model_validate({"type": "fullAccess"}), - alias="readOnlyAccess", - ) - type: Type147 = Field(..., title="WorkspaceWriteSandboxPolicyType") - writable_roots: List[AbsolutePathBuf] | None = Field([], alias="writableRoots") + exclude_slash_tmp: Annotated[bool | None, Field(alias="excludeSlashTmp")] = False + exclude_tmpdir_env_var: Annotated[ + bool | None, Field(alias="excludeTmpdirEnvVar") + ] = False + network_access: Annotated[bool | None, Field(alias="networkAccess")] = False + read_only_access: Annotated[ + ReadOnlyAccess | None, Field(alias="readOnlyAccess") + ] = {"type": "fullAccess"} + type: Annotated[ + Literal["workspaceWrite"], Field(title="WorkspaceWriteSandboxPolicyType") + ] + writable_roots: Annotated[ + list[AbsolutePathBuf] | None, Field(alias="writableRoots") + ] = [] class SandboxPolicy( - RootModel[SandboxPolicy1 | SandboxPolicy2 | SandboxPolicy3 | SandboxPolicy4] + RootModel[ + DangerFullAccessSandboxPolicy + | ReadOnlySandboxPolicy + | ExternalSandboxSandboxPolicy + | WorkspaceWriteSandboxPolicy + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: SandboxPolicy1 | SandboxPolicy2 | SandboxPolicy3 | SandboxPolicy4 + root: ( + DangerFullAccessSandboxPolicy + | ReadOnlySandboxPolicy + | ExternalSandboxSandboxPolicy + | WorkspaceWriteSandboxPolicy + ) class SandboxWorkspaceWrite(BaseModel): @@ -3336,320 +2960,167 @@ class SandboxWorkspaceWrite(BaseModel): exclude_slash_tmp: bool | None = False exclude_tmpdir_env_var: bool | None = False network_access: bool | None = False - writable_roots: List[str] | None = [] + writable_roots: list[str] | None = [] -class Method50(Enum): - thread_started = "thread/started" - - -class Method51(Enum): - thread_status_changed = "thread/status/changed" - - -class Method52(Enum): - thread_archived = "thread/archived" - - -class Method53(Enum): - thread_unarchived = "thread/unarchived" - - -class Method54(Enum): - thread_closed = "thread/closed" - - -class Method55(Enum): - skills_changed = "skills/changed" - - -class Method56(Enum): - thread_name_updated = "thread/name/updated" - - -class Method57(Enum): - thread_token_usage_updated = "thread/tokenUsage/updated" - - -class Method58(Enum): - turn_started = "turn/started" - - -class Method59(Enum): - hook_started = "hook/started" - - -class Method60(Enum): - turn_completed = "turn/completed" - - -class Method61(Enum): - hook_completed = "hook/completed" - - -class Method62(Enum): - turn_diff_updated = "turn/diff/updated" - - -class Method63(Enum): - turn_plan_updated = "turn/plan/updated" - - -class Method64(Enum): - item_started = "item/started" - - -class Method65(Enum): - item_completed = "item/completed" - - -class Method66(Enum): - item_agent_message_delta = "item/agentMessage/delta" - - -class ServerNotification18(BaseModel): +class ItemAgentMessageDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method66 = Field(..., title="Item/agentMessage/deltaNotificationMethod") + method: Annotated[ + Literal["item/agentMessage/delta"], + Field(title="Item/agentMessage/deltaNotificationMethod"), + ] params: AgentMessageDeltaNotification -class Method67(Enum): - item_plan_delta = "item/plan/delta" - - -class ServerNotification19(BaseModel): +class ItemPlanDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method67 = Field(..., title="Item/plan/deltaNotificationMethod") + method: Annotated[ + Literal["item/plan/delta"], Field(title="Item/plan/deltaNotificationMethod") + ] params: PlanDeltaNotification -class Method68(Enum): - command_exec_output_delta = "command/exec/outputDelta" - - -class Method69(Enum): - item_command_execution_output_delta = "item/commandExecution/outputDelta" - - -class ServerNotification21(BaseModel): +class ItemCommandExecutionOutputDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method69 = Field( - ..., title="Item/commandExecution/outputDeltaNotificationMethod" - ) + method: Annotated[ + Literal["item/commandExecution/outputDelta"], + Field(title="Item/commandExecution/outputDeltaNotificationMethod"), + ] params: CommandExecutionOutputDeltaNotification -class Method70(Enum): - item_command_execution_terminal_interaction = ( - "item/commandExecution/terminalInteraction" - ) - - -class Method71(Enum): - item_file_change_output_delta = "item/fileChange/outputDelta" - - -class ServerNotification23(BaseModel): +class ItemFileChangeOutputDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method71 = Field(..., title="Item/fileChange/outputDeltaNotificationMethod") + method: Annotated[ + Literal["item/fileChange/outputDelta"], + Field(title="Item/fileChange/outputDeltaNotificationMethod"), + ] params: FileChangeOutputDeltaNotification -class Method72(Enum): - server_request_resolved = "serverRequest/resolved" - - -class Method73(Enum): - item_mcp_tool_call_progress = "item/mcpToolCall/progress" - - -class ServerNotification25(BaseModel): +class ItemMcpToolCallProgressServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method73 = Field(..., title="Item/mcpToolCall/progressNotificationMethod") + method: Annotated[ + Literal["item/mcpToolCall/progress"], + Field(title="Item/mcpToolCall/progressNotificationMethod"), + ] params: McpToolCallProgressNotification -class Method74(Enum): - mcp_server_oauth_login_completed = "mcpServer/oauthLogin/completed" - - -class ServerNotification26(BaseModel): +class McpServerOauthLoginCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method74 = Field( - ..., title="McpServer/oauthLogin/completedNotificationMethod" - ) + method: Annotated[ + Literal["mcpServer/oauthLogin/completed"], + Field(title="McpServer/oauthLogin/completedNotificationMethod"), + ] params: McpServerOauthLoginCompletedNotification -class Method75(Enum): - account_updated = "account/updated" - - -class Method76(Enum): - account_rate_limits_updated = "account/rateLimits/updated" - - -class Method77(Enum): - app_list_updated = "app/list/updated" - - -class Method78(Enum): - item_reasoning_summary_text_delta = "item/reasoning/summaryTextDelta" - - -class ServerNotification30(BaseModel): +class ItemReasoningSummaryTextDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method78 = Field( - ..., title="Item/reasoning/summaryTextDeltaNotificationMethod" - ) + method: Annotated[ + Literal["item/reasoning/summaryTextDelta"], + Field(title="Item/reasoning/summaryTextDeltaNotificationMethod"), + ] params: ReasoningSummaryTextDeltaNotification -class Method79(Enum): - item_reasoning_summary_part_added = "item/reasoning/summaryPartAdded" - - -class ServerNotification31(BaseModel): +class ItemReasoningSummaryPartAddedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method79 = Field( - ..., title="Item/reasoning/summaryPartAddedNotificationMethod" - ) + method: Annotated[ + Literal["item/reasoning/summaryPartAdded"], + Field(title="Item/reasoning/summaryPartAddedNotificationMethod"), + ] params: ReasoningSummaryPartAddedNotification -class Method80(Enum): - item_reasoning_text_delta = "item/reasoning/textDelta" - - -class ServerNotification32(BaseModel): +class ItemReasoningTextDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method80 = Field(..., title="Item/reasoning/textDeltaNotificationMethod") + method: Annotated[ + Literal["item/reasoning/textDelta"], + Field(title="Item/reasoning/textDeltaNotificationMethod"), + ] params: ReasoningTextDeltaNotification -class Method81(Enum): - thread_compacted = "thread/compacted" - - -class ServerNotification33(BaseModel): +class ThreadCompactedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method81 = Field(..., title="Thread/compactedNotificationMethod") + method: Annotated[ + Literal["thread/compacted"], Field(title="Thread/compactedNotificationMethod") + ] params: ContextCompactedNotification -class Method82(Enum): - model_rerouted = "model/rerouted" - - -class ServerNotification34(BaseModel): +class ModelReroutedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method82 = Field(..., title="Model/reroutedNotificationMethod") + method: Annotated[ + Literal["model/rerouted"], Field(title="Model/reroutedNotificationMethod") + ] params: ModelReroutedNotification -class Method83(Enum): - deprecation_notice = "deprecationNotice" - - -class ServerNotification35(BaseModel): +class DeprecationNoticeServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method83 = Field(..., title="DeprecationNoticeNotificationMethod") + method: Annotated[ + Literal["deprecationNotice"], Field(title="DeprecationNoticeNotificationMethod") + ] params: DeprecationNoticeNotification -class Method84(Enum): - config_warning = "configWarning" - - -class Method85(Enum): - fuzzy_file_search_session_updated = "fuzzyFileSearch/sessionUpdated" - - -class ServerNotification37(BaseModel): +class FuzzyFileSearchSessionUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method85 = Field( - ..., title="FuzzyFileSearch/sessionUpdatedNotificationMethod" - ) + method: Annotated[ + Literal["fuzzyFileSearch/sessionUpdated"], + Field(title="FuzzyFileSearch/sessionUpdatedNotificationMethod"), + ] params: FuzzyFileSearchSessionUpdatedNotification -class Method86(Enum): - fuzzy_file_search_session_completed = "fuzzyFileSearch/sessionCompleted" - - -class ServerNotification38(BaseModel): +class FuzzyFileSearchSessionCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method86 = Field( - ..., title="FuzzyFileSearch/sessionCompletedNotificationMethod" - ) + method: Annotated[ + Literal["fuzzyFileSearch/sessionCompleted"], + Field(title="FuzzyFileSearch/sessionCompletedNotificationMethod"), + ] params: FuzzyFileSearchSessionCompletedNotification -class Method87(Enum): - thread_realtime_started = "thread/realtime/started" - - -class Method88(Enum): - thread_realtime_item_added = "thread/realtime/itemAdded" - - -class Method89(Enum): - thread_realtime_output_audio_delta = "thread/realtime/outputAudio/delta" - - -class Method90(Enum): - thread_realtime_error = "thread/realtime/error" - - -class Method91(Enum): - thread_realtime_closed = "thread/realtime/closed" - - -class Method92(Enum): - windows_world_writable_warning = "windows/worldWritableWarning" - - -class Method93(Enum): - windows_sandbox_setup_completed = "windowsSandbox/setupCompleted" - - -class Method94(Enum): - account_login_completed = "account/login/completed" - - -class ServerNotification46(BaseModel): +class AccountLoginCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method94 = Field(..., title="Account/login/completedNotificationMethod") + method: Annotated[ + Literal["account/login/completed"], + Field(title="Account/login/completedNotificationMethod"), + ] params: AccountLoginCompletedNotification @@ -3657,8 +3128,8 @@ class ServerRequestResolvedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - request_id: RequestId = Field(..., alias="requestId") - thread_id: str = Field(..., alias="threadId") + request_id: Annotated[RequestId, Field(alias="requestId")] + thread_id: Annotated[str, Field(alias="threadId")] class ServiceTier(Enum): @@ -3674,7 +3145,7 @@ class SessionNetworkProxyRuntime(BaseModel): socks_addr: str -class SessionSource1(Enum): +class SessionSourceValue(Enum): cli = "cli" vscode = "vscode" exec = "exec" @@ -3703,12 +3174,12 @@ class SkillInterface(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - brand_color: str | None = Field(None, alias="brandColor") - default_prompt: str | None = Field(None, alias="defaultPrompt") - display_name: str | None = Field(None, alias="displayName") - icon_large: str | None = Field(None, alias="iconLarge") - icon_small: str | None = Field(None, alias="iconSmall") - short_description: str | None = Field(None, alias="shortDescription") + brand_color: Annotated[str | None, Field(alias="brandColor")] = None + default_prompt: Annotated[str | None, Field(alias="defaultPrompt")] = None + display_name: Annotated[str | None, Field(alias="displayName")] = None + icon_large: Annotated[str | None, Field(alias="iconLarge")] = None + icon_small: Annotated[str | None, Field(alias="iconSmall")] = None + short_description: Annotated[str | None, Field(alias="shortDescription")] = None class SkillScope(Enum): @@ -3730,7 +3201,11 @@ class SkillToolDependency(BaseModel): value: str -SkillsChangedNotification = CodexAppServerProtocolV2 +class SkillsChangedNotification(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) class SkillsConfigWriteParams(BaseModel): @@ -3745,7 +3220,7 @@ class SkillsConfigWriteResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - effective_enabled: bool = Field(..., alias="effectiveEnabled") + effective_enabled: Annotated[bool, Field(alias="effectiveEnabled")] class SkillsListExtraRootsForCwd(BaseModel): @@ -3753,27 +3228,33 @@ class SkillsListExtraRootsForCwd(BaseModel): populate_by_name=True, ) cwd: str - extra_user_roots: List[str] = Field(..., alias="extraUserRoots") + extra_user_roots: Annotated[list[str], Field(alias="extraUserRoots")] class SkillsListParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cwds: List[str] | None = Field( - None, - description="When empty, defaults to the current session working directory.", - ) - force_reload: bool | None = Field( - None, - alias="forceReload", - description="When true, bypass the skills cache and re-scan skills from disk.", - ) - per_cwd_extra_user_roots: List[SkillsListExtraRootsForCwd] | None = Field( - None, - alias="perCwdExtraUserRoots", - description="Optional per-cwd extra roots to scan as user-scoped skills.", - ) + cwds: Annotated[ + list[str] | None, + Field( + description="When empty, defaults to the current session working directory." + ), + ] = None + force_reload: Annotated[ + bool | None, + Field( + alias="forceReload", + description="When true, bypass the skills cache and re-scan skills from disk.", + ), + ] = None + per_cwd_extra_user_roots: Annotated[ + list[SkillsListExtraRootsForCwd] | None, + Field( + alias="perCwdExtraUserRoots", + description="Optional per-cwd extra roots to scan as user-scoped skills.", + ), + ] = None class SkillsRemoteReadParams(BaseModel): @@ -3781,22 +3262,26 @@ class SkillsRemoteReadParams(BaseModel): populate_by_name=True, ) enabled: bool | None = False - hazelnut_scope: HazelnutScope | None = Field("example", alias="hazelnutScope") - product_surface: ProductSurface | None = Field("codex", alias="productSurface") + hazelnut_scope: Annotated[HazelnutScope | None, Field(alias="hazelnutScope")] = ( + "example" + ) + product_surface: Annotated[ProductSurface | None, Field(alias="productSurface")] = ( + "codex" + ) class SkillsRemoteReadResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[RemoteSkillSummary] + data: list[RemoteSkillSummary] class SkillsRemoteWriteParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - hazelnut_id: str = Field(..., alias="hazelnutId") + hazelnut_id: Annotated[str, Field(alias="hazelnutId")] class SkillsRemoteWriteResponse(BaseModel): @@ -3813,13 +3298,13 @@ class StepStatus(Enum): completed = "completed" -class SubAgentSource1(Enum): +class SubAgentSourceValue(Enum): review = "review" compact = "compact" memory_consolidation = "memory_consolidation" -class SubAgentSource3(BaseModel): +class OtherSubAgentSource(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, @@ -3831,36 +3316,41 @@ class TerminalInteractionNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - item_id: str = Field(..., alias="itemId") - process_id: str = Field(..., alias="processId") + item_id: Annotated[str, Field(alias="itemId")] + process_id: Annotated[str, Field(alias="processId")] stdin: str - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class TextElement(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - byte_range: ByteRange = Field( - ..., - alias="byteRange", - description="Byte range in the parent `text` buffer that this element occupies.", - ) - placeholder: str | None = Field( - None, - description="Optional human-readable placeholder for the element, displayed in the UI.", - ) + byte_range: Annotated[ + ByteRange, + Field( + alias="byteRange", + description="Byte range in the parent `text` buffer that this element occupies.", + ), + ] + placeholder: Annotated[ + str | None, + Field( + description="Optional human-readable placeholder for the element, displayed in the UI." + ), + ] = None class TextPosition(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - column: conint(ge=0) = Field( - ..., description="1-based column number (in Unicode scalar values)." - ) - line: conint(ge=0) = Field(..., description="1-based line number.") + column: Annotated[ + int, + Field(description="1-based column number (in Unicode scalar values).", ge=0), + ] + line: Annotated[int, Field(description="1-based line number.", ge=0)] class TextRange(BaseModel): @@ -3876,40 +3366,69 @@ class ThreadActiveFlag(Enum): waiting_on_user_input = "waitingOnUserInput" -ThreadArchiveParams = FeedbackUploadResponse +class ThreadArchiveParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread_id: Annotated[str, Field(alias="threadId")] -ThreadArchiveResponse = CodexAppServerProtocolV2 +class ThreadArchiveResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) -ThreadArchivedNotification = FeedbackUploadResponse +class ThreadArchivedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread_id: Annotated[str, Field(alias="threadId")] -ThreadClosedNotification = FeedbackUploadResponse +class ThreadClosedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread_id: Annotated[str, Field(alias="threadId")] -ThreadCompactStartParams = FeedbackUploadResponse +class ThreadCompactStartParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread_id: Annotated[str, Field(alias="threadId")] -ThreadCompactStartResponse = CodexAppServerProtocolV2 +class ThreadCompactStartResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) class ThreadForkParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: AskForApproval | None = Field(None, alias="approvalPolicy") - base_instructions: str | None = Field(None, alias="baseInstructions") - config: Dict[str, Any] | None = None - cwd: str | None = None - developer_instructions: str | None = Field(None, alias="developerInstructions") - model: str | None = Field( - None, description="Configuration overrides for the forked thread, if any." + approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = ( + None ) - model_provider: str | None = Field(None, alias="modelProvider") + base_instructions: Annotated[str | None, Field(alias="baseInstructions")] = None + config: dict[str, Any] | None = None + cwd: str | None = None + developer_instructions: Annotated[ + str | None, Field(alias="developerInstructions") + ] = None + model: Annotated[ + str | None, + Field(description="Configuration overrides for the forked thread, if any."), + ] = None + model_provider: Annotated[str | None, Field(alias="modelProvider")] = None sandbox: SandboxMode | None = None - service_tier: ServiceTier | None = Field(None, alias="serviceTier") - thread_id: str = Field(..., alias="threadId") + service_tier: Annotated[ServiceTier | None, Field(alias="serviceTier")] = None + thread_id: Annotated[str, Field(alias="threadId")] class ThreadId(RootModel[str]): @@ -3919,285 +3438,267 @@ class ThreadId(RootModel[str]): root: str -class Type148(Enum): - user_message = "userMessage" - - -class Type149(Enum): - agent_message = "agentMessage" - - -class ThreadItem2(BaseModel): +class AgentMessageThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str phase: MessagePhase | None = None text: str - type: Type149 = Field(..., title="AgentMessageThreadItemType") + type: Annotated[Literal["agentMessage"], Field(title="AgentMessageThreadItemType")] -class Type150(Enum): - plan = "plan" - - -class ThreadItem3(BaseModel): +class PlanThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str text: str - type: Type150 = Field(..., title="PlanThreadItemType") + type: Annotated[Literal["plan"], Field(title="PlanThreadItemType")] -class ThreadItem4(BaseModel): +class ReasoningThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - content: List[str] | None = [] + content: list[str] | None = [] id: str - summary: List[str] | None = [] - type: Type125 = Field(..., title="ReasoningThreadItemType") + summary: list[str] | None = [] + type: Annotated[Literal["reasoning"], Field(title="ReasoningThreadItemType")] -class Type152(Enum): - command_execution = "commandExecution" - - -class ThreadItem5(BaseModel): +class CommandExecutionThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - aggregated_output: str | None = Field( - None, - alias="aggregatedOutput", - description="The command's output, aggregated from stdout and stderr.", - ) - command: str = Field(..., description="The command to be executed.") - command_actions: List[CommandAction] = Field( - ..., - alias="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.", - ) - cwd: str = Field(..., description="The command's working directory.") - duration_ms: int | None = Field( - None, - alias="durationMs", - description="The duration of the command execution in milliseconds.", - ) - exit_code: int | None = Field( - None, alias="exitCode", description="The command's exit code." - ) + aggregated_output: Annotated[ + str | None, + Field( + alias="aggregatedOutput", + description="The command's output, aggregated from stdout and stderr.", + ), + ] = None + command: Annotated[str, Field(description="The command to be executed.")] + command_actions: Annotated[ + list[CommandAction], + Field( + alias="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.", + ), + ] + cwd: Annotated[str, Field(description="The command's working directory.")] + duration_ms: Annotated[ + int | None, + Field( + alias="durationMs", + description="The duration of the command execution in milliseconds.", + ), + ] = None + exit_code: Annotated[ + int | None, Field(alias="exitCode", description="The command's exit code.") + ] = None id: str - process_id: str | None = Field( - None, - alias="processId", - description="Identifier for the underlying PTY process (when available).", - ) + process_id: Annotated[ + str | None, + Field( + alias="processId", + description="Identifier for the underlying PTY process (when available).", + ), + ] = None status: CommandExecutionStatus - type: Type152 = Field(..., title="CommandExecutionThreadItemType") + type: Annotated[ + Literal["commandExecution"], Field(title="CommandExecutionThreadItemType") + ] -class Type153(Enum): - file_change = "fileChange" - - -class Type154(Enum): - mcp_tool_call = "mcpToolCall" - - -class ThreadItem7(BaseModel): +class McpToolCallThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) arguments: Any - duration_ms: int | None = Field( - None, - alias="durationMs", - description="The duration of the MCP tool call in milliseconds.", - ) + duration_ms: Annotated[ + int | None, + Field( + alias="durationMs", + description="The duration of the MCP tool call in milliseconds.", + ), + ] = None error: McpToolCallError | None = None id: str result: McpToolCallResult | None = None server: str - status: CollabAgentToolCallStatus + status: McpToolCallStatus tool: str - type: Type154 = Field(..., title="McpToolCallThreadItemType") + type: Annotated[Literal["mcpToolCall"], Field(title="McpToolCallThreadItemType")] -class Type155(Enum): - dynamic_tool_call = "dynamicToolCall" - - -class ThreadItem8(BaseModel): +class DynamicToolCallThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) arguments: Any - content_items: List[DynamicToolCallOutputContentItem] | None = Field( - None, alias="contentItems" - ) - duration_ms: int | None = Field( - None, - alias="durationMs", - description="The duration of the dynamic tool call in milliseconds.", - ) + content_items: Annotated[ + list[DynamicToolCallOutputContentItem] | None, Field(alias="contentItems") + ] = None + duration_ms: Annotated[ + int | None, + Field( + alias="durationMs", + description="The duration of the dynamic tool call in milliseconds.", + ), + ] = None id: str - status: CollabAgentToolCallStatus + status: DynamicToolCallStatus success: bool | None = None tool: str - type: Type155 = Field(..., title="DynamicToolCallThreadItemType") + type: Annotated[ + Literal["dynamicToolCall"], Field(title="DynamicToolCallThreadItemType") + ] -class Type156(Enum): - collab_agent_tool_call = "collabAgentToolCall" - - -class Type157(Enum): - web_search = "webSearch" - - -class Type158(Enum): - image_view = "imageView" - - -class ThreadItem11(BaseModel): +class ImageViewThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str path: str - type: Type158 = Field(..., title="ImageViewThreadItemType") + type: Annotated[Literal["imageView"], Field(title="ImageViewThreadItemType")] -class Type159(Enum): - image_generation = "imageGeneration" - - -class ThreadItem12(BaseModel): +class ImageGenerationThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str result: str - revised_prompt: str | None = Field(None, alias="revisedPrompt") + revised_prompt: Annotated[str | None, Field(alias="revisedPrompt")] = None status: str - type: Type159 = Field(..., title="ImageGenerationThreadItemType") + type: Annotated[ + Literal["imageGeneration"], Field(title="ImageGenerationThreadItemType") + ] -class Type160(Enum): - entered_review_mode = "enteredReviewMode" - - -class ThreadItem13(BaseModel): +class EnteredReviewModeThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str review: str - type: Type160 = Field(..., title="EnteredReviewModeThreadItemType") + type: Annotated[ + Literal["enteredReviewMode"], Field(title="EnteredReviewModeThreadItemType") + ] -class Type161(Enum): - exited_review_mode = "exitedReviewMode" - - -class ThreadItem14(BaseModel): +class ExitedReviewModeThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str review: str - type: Type161 = Field(..., title="ExitedReviewModeThreadItemType") + type: Annotated[ + Literal["exitedReviewMode"], Field(title="ExitedReviewModeThreadItemType") + ] -class Type162(Enum): - context_compaction = "contextCompaction" - - -class ThreadItem15(BaseModel): +class ContextCompactionThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str - type: Type162 = Field(..., title="ContextCompactionThreadItemType") + type: Annotated[ + Literal["contextCompaction"], Field(title="ContextCompactionThreadItemType") + ] class ThreadLoadedListParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cursor: str | None = Field( - None, description="Opaque pagination cursor returned by a previous call." - ) - limit: conint(ge=0) | None = Field( - None, description="Optional page size; defaults to no limit." - ) + cursor: Annotated[ + str | None, + Field(description="Opaque pagination cursor returned by a previous call."), + ] = None + limit: Annotated[ + int | None, Field(description="Optional page size; defaults to no limit.", ge=0) + ] = None class ThreadLoadedListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[str] = Field( - ..., description="Thread ids for sessions currently loaded in memory." - ) - next_cursor: str | None = Field( - None, - alias="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.", - ) + data: Annotated[ + list[str], + Field(description="Thread ids for sessions currently loaded in memory."), + ] + next_cursor: Annotated[ + str | None, + Field( + alias="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.", + ), + ] = None class ThreadMetadataGitInfoUpdateParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - branch: str | None = Field( - None, - description="Omit to leave the stored branch unchanged, set to `null` to clear it, or provide a non-empty string to replace it.", - ) - origin_url: str | None = Field( - None, - alias="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.", - ) - sha: str | None = Field( - None, - description="Omit to leave the stored commit unchanged, set to `null` to clear it, or provide a non-empty string to replace it.", - ) + branch: Annotated[ + str | None, + Field( + description="Omit to leave the stored branch unchanged, set to `null` to clear it, or provide a non-empty string to replace it." + ), + ] = None + origin_url: Annotated[ + str | None, + Field( + alias="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.", + ), + ] = None + sha: Annotated[ + str | None, + Field( + description="Omit to leave the stored commit unchanged, set to `null` to clear it, or provide a non-empty string to replace it." + ), + ] = None class ThreadMetadataUpdateParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - git_info: ThreadMetadataGitInfoUpdateParams | None = Field( - None, - alias="gitInfo", - 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.", - ) - thread_id: str = Field(..., alias="threadId") + git_info: Annotated[ + ThreadMetadataGitInfoUpdateParams | None, + Field( + alias="gitInfo", + 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.", + ), + ] = None + thread_id: Annotated[str, Field(alias="threadId")] class ThreadNameUpdatedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - thread_id: str = Field(..., alias="threadId") - thread_name: str | None = Field(None, alias="threadName") + thread_id: Annotated[str, Field(alias="threadId")] + thread_name: Annotated[str | None, Field(alias="threadName")] = None class ThreadReadParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - include_turns: bool | None = Field( - False, - alias="includeTurns", - description="When true, include turns and their items from rollout history.", - ) - thread_id: str = Field(..., alias="threadId") + include_turns: Annotated[ + bool | None, + Field( + alias="includeTurns", + description="When true, include turns and their items from rollout history.", + ), + ] = False + thread_id: Annotated[str, Field(alias="threadId")] class ThreadRealtimeAudioChunk(BaseModel): @@ -4205,9 +3706,11 @@ class ThreadRealtimeAudioChunk(BaseModel): populate_by_name=True, ) data: str - num_channels: conint(ge=0) = Field(..., alias="numChannels") - sample_rate: conint(ge=0) = Field(..., alias="sampleRate") - samples_per_channel: conint(ge=0) | None = Field(None, alias="samplesPerChannel") + num_channels: Annotated[int, Field(alias="numChannels", ge=0)] + sample_rate: Annotated[int, Field(alias="sampleRate", ge=0)] + samples_per_channel: Annotated[ + int | None, Field(alias="samplesPerChannel", ge=0) + ] = None class ThreadRealtimeClosedNotification(BaseModel): @@ -4215,7 +3718,7 @@ class ThreadRealtimeClosedNotification(BaseModel): populate_by_name=True, ) reason: str | None = None - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] class ThreadRealtimeErrorNotification(BaseModel): @@ -4223,7 +3726,7 @@ class ThreadRealtimeErrorNotification(BaseModel): populate_by_name=True, ) message: str - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] class ThreadRealtimeItemAddedNotification(BaseModel): @@ -4231,7 +3734,7 @@ class ThreadRealtimeItemAddedNotification(BaseModel): populate_by_name=True, ) item: Any - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] class ThreadRealtimeOutputAudioDeltaNotification(BaseModel): @@ -4239,46 +3742,54 @@ class ThreadRealtimeOutputAudioDeltaNotification(BaseModel): populate_by_name=True, ) audio: ThreadRealtimeAudioChunk - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] class ThreadRealtimeStartedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - session_id: str | None = Field(None, alias="sessionId") - thread_id: str = Field(..., alias="threadId") + session_id: Annotated[str | None, Field(alias="sessionId")] = None + thread_id: Annotated[str, Field(alias="threadId")] class ThreadResumeParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: AskForApproval | None = Field(None, alias="approvalPolicy") - base_instructions: str | None = Field(None, alias="baseInstructions") - config: Dict[str, Any] | None = None - cwd: str | None = None - developer_instructions: str | None = Field(None, alias="developerInstructions") - model: str | None = Field( - None, description="Configuration overrides for the resumed thread, if any." + approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = ( + None ) - model_provider: str | None = Field(None, alias="modelProvider") + base_instructions: Annotated[str | None, Field(alias="baseInstructions")] = None + config: dict[str, Any] | None = None + cwd: str | None = None + developer_instructions: Annotated[ + str | None, Field(alias="developerInstructions") + ] = None + model: Annotated[ + str | None, + Field(description="Configuration overrides for the resumed thread, if any."), + ] = None + model_provider: Annotated[str | None, Field(alias="modelProvider")] = None personality: Personality | None = None sandbox: SandboxMode | None = None - service_tier: ServiceTier | None = Field(None, alias="serviceTier") - thread_id: str = Field(..., alias="threadId") + service_tier: Annotated[ServiceTier | None, Field(alias="serviceTier")] = None + thread_id: Annotated[str, Field(alias="threadId")] class ThreadRollbackParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - num_turns: conint(ge=0) = Field( - ..., - alias="numTurns", - description="The number of turns to drop from the end of the thread. Must be >= 1.\n\nThis only modifies the thread's history and does not revert local file changes that have been made by the agent. Clients are responsible for reverting these changes.", - ) - thread_id: str = Field(..., alias="threadId") + num_turns: Annotated[ + int, + Field( + alias="numTurns", + description="The number of turns to drop from the end of the thread. Must be >= 1.\n\nThis only modifies the thread's history and does not revert local file changes that have been made by the agent. Clients are responsible for reverting these changes.", + ge=0, + ), + ] + thread_id: Annotated[str, Field(alias="threadId")] class ThreadSetNameParams(BaseModel): @@ -4286,10 +3797,14 @@ class ThreadSetNameParams(BaseModel): populate_by_name=True, ) name: str - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] -ThreadSetNameResponse = CodexAppServerProtocolV2 +class ThreadSetNameResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, + ) class ThreadSortKey(Enum): @@ -4314,72 +3829,70 @@ class ThreadStartParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: AskForApproval | None = Field(None, alias="approvalPolicy") - base_instructions: str | None = Field(None, alias="baseInstructions") - config: Dict[str, Any] | None = None + approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = ( + None + ) + base_instructions: Annotated[str | None, Field(alias="baseInstructions")] = None + config: dict[str, Any] | None = None cwd: str | None = None - developer_instructions: str | None = Field(None, alias="developerInstructions") + developer_instructions: Annotated[ + str | None, Field(alias="developerInstructions") + ] = None ephemeral: bool | None = None model: str | None = None - model_provider: str | None = Field(None, alias="modelProvider") + model_provider: Annotated[str | None, Field(alias="modelProvider")] = None personality: Personality | None = None sandbox: SandboxMode | None = None - service_name: str | None = Field(None, alias="serviceName") - service_tier: ServiceTier | None = Field(None, alias="serviceTier") + service_name: Annotated[str | None, Field(alias="serviceName")] = None + service_tier: Annotated[ServiceTier | None, Field(alias="serviceTier")] = None -class Type163(Enum): - not_loaded = "notLoaded" - - -class ThreadStatus1(BaseModel): +class NotLoadedThreadStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type163 = Field(..., title="NotLoadedThreadStatusType") + type: Annotated[Literal["notLoaded"], Field(title="NotLoadedThreadStatusType")] -class Type164(Enum): - idle = "idle" - - -class ThreadStatus2(BaseModel): +class IdleThreadStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type164 = Field(..., title="IdleThreadStatusType") + type: Annotated[Literal["idle"], Field(title="IdleThreadStatusType")] -class Type165(Enum): - system_error = "systemError" - - -class ThreadStatus3(BaseModel): +class SystemErrorThreadStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type165 = Field(..., title="SystemErrorThreadStatusType") + type: Annotated[Literal["systemError"], Field(title="SystemErrorThreadStatusType")] -class Type166(Enum): - active = "active" - - -class ThreadStatus4(BaseModel): +class ActiveThreadStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - active_flags: List[ThreadActiveFlag] = Field(..., alias="activeFlags") - type: Type166 = Field(..., title="ActiveThreadStatusType") + active_flags: Annotated[list[ThreadActiveFlag], Field(alias="activeFlags")] + type: Annotated[Literal["active"], Field(title="ActiveThreadStatusType")] class ThreadStatus( - RootModel[ThreadStatus1 | ThreadStatus2 | ThreadStatus3 | ThreadStatus4] + RootModel[ + NotLoadedThreadStatus + | IdleThreadStatus + | SystemErrorThreadStatus + | ActiveThreadStatus + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ThreadStatus1 | ThreadStatus2 | ThreadStatus3 | ThreadStatus4 + root: ( + NotLoadedThreadStatus + | IdleThreadStatus + | SystemErrorThreadStatus + | ActiveThreadStatus + ) class ThreadStatusChangedNotification(BaseModel): @@ -4387,16 +3900,28 @@ class ThreadStatusChangedNotification(BaseModel): populate_by_name=True, ) status: ThreadStatus - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] -ThreadUnarchiveParams = FeedbackUploadResponse +class ThreadUnarchiveParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread_id: Annotated[str, Field(alias="threadId")] -ThreadUnarchivedNotification = FeedbackUploadResponse +class ThreadUnarchivedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread_id: Annotated[str, Field(alias="threadId")] -ThreadUnsubscribeParams = FeedbackUploadResponse +class ThreadUnsubscribeParams(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread_id: Annotated[str, Field(alias="threadId")] class ThreadUnsubscribeStatus(Enum): @@ -4420,11 +3945,11 @@ class TokenUsageBreakdown(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cached_input_tokens: int = Field(..., alias="cachedInputTokens") - input_tokens: int = Field(..., alias="inputTokens") - output_tokens: int = Field(..., alias="outputTokens") - reasoning_output_tokens: int = Field(..., alias="reasoningOutputTokens") - total_tokens: int = Field(..., alias="totalTokens") + cached_input_tokens: Annotated[int, Field(alias="cachedInputTokens")] + input_tokens: Annotated[int, Field(alias="inputTokens")] + output_tokens: Annotated[int, Field(alias="outputTokens")] + reasoning_output_tokens: Annotated[int, Field(alias="reasoningOutputTokens")] + total_tokens: Annotated[int, Field(alias="totalTokens")] class TokenUsageInfo(BaseModel): @@ -4440,13 +3965,13 @@ class Tool(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - field_meta: Any | None = Field(None, alias="_meta") + field_meta: Annotated[Any | None, Field(alias="_meta")] = None annotations: Any | None = None description: str | None = None - icons: List | None = None - input_schema: Any = Field(..., alias="inputSchema") + icons: list | None = None + input_schema: Annotated[Any, Field(alias="inputSchema")] name: str - output_schema: Any | None = Field(None, alias="outputSchema") + output_schema: Annotated[Any | None, Field(alias="outputSchema")] = None title: str | None = None @@ -4461,92 +3986,81 @@ class TurnDiffUpdatedNotification(BaseModel): populate_by_name=True, ) diff: str - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class TurnError(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - additional_details: str | None = Field(None, alias="additionalDetails") - codex_error_info: CodexErrorInfo | None = Field(None, alias="codexErrorInfo") + additional_details: Annotated[str | None, Field(alias="additionalDetails")] = None + codex_error_info: Annotated[ + CodexErrorInfo | None, Field(alias="codexErrorInfo") + ] = None message: str -TurnInterruptParams = ContextCompactedNotification - - -TurnInterruptResponse = CodexAppServerProtocolV2 - - -class Type167(Enum): - user_message = "UserMessage" - - -class Type168(Enum): - agent_message = "AgentMessage" - - -class TurnItem2(BaseModel): +class TurnInterruptParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - content: List[AgentMessageContent] - id: str - phase: MessagePhase | None = Field( - None, - description="Optional phase metadata carried through from `ResponseItem::Message`.\n\nThis is currently used by TUI rendering to distinguish mid-turn commentary from a final answer and avoid status-indicator jitter.", + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] + + +class TurnInterruptResponse(BaseModel): + pass + model_config = ConfigDict( + populate_by_name=True, ) - type: Type168 = Field(..., title="AgentMessageTurnItemType") -class Type169(Enum): - plan = "Plan" +class AgentMessageTurnItem(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + content: list[AgentMessageContent] + id: str + phase: Annotated[ + MessagePhase | None, + Field( + description="Optional phase metadata carried through from `ResponseItem::Message`.\n\nThis is currently used by TUI rendering to distinguish mid-turn commentary from a final answer and avoid status-indicator jitter." + ), + ] = None + type: Annotated[Literal["AgentMessage"], Field(title="AgentMessageTurnItemType")] -class TurnItem3(BaseModel): +class PlanTurnItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str text: str - type: Type169 = Field(..., title="PlanTurnItemType") + type: Annotated[Literal["Plan"], Field(title="PlanTurnItemType")] -class Type170(Enum): - reasoning = "Reasoning" - - -class TurnItem4(BaseModel): +class ReasoningTurnItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str - raw_content: List[str] | None = [] - summary_text: List[str] - type: Type170 = Field(..., title="ReasoningTurnItemType") + raw_content: list[str] | None = [] + summary_text: list[str] + type: Annotated[Literal["Reasoning"], Field(title="ReasoningTurnItemType")] -class Type171(Enum): - web_search = "WebSearch" - - -class TurnItem5(BaseModel): +class WebSearchTurnItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) action: ResponsesApiWebSearchAction id: str query: str - type: Type171 = Field(..., title="WebSearchTurnItemType") + type: Annotated[Literal["WebSearch"], Field(title="WebSearchTurnItemType")] -class Type172(Enum): - image_generation = "ImageGeneration" - - -class TurnItem6(BaseModel): +class ImageGenerationTurnItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) @@ -4555,19 +4069,19 @@ class TurnItem6(BaseModel): revised_prompt: str | None = None saved_path: str | None = None status: str - type: Type172 = Field(..., title="ImageGenerationTurnItemType") + type: Annotated[ + Literal["ImageGeneration"], Field(title="ImageGenerationTurnItemType") + ] -class Type173(Enum): - context_compaction = "ContextCompaction" - - -class TurnItem7(BaseModel): +class ContextCompactionTurnItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: str - type: Type173 = Field(..., title="ContextCompactionTurnItemType") + type: Annotated[ + Literal["ContextCompaction"], Field(title="ContextCompactionTurnItemType") + ] class TurnPlanStepStatus(Enum): @@ -4587,78 +4101,76 @@ class TurnSteerResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - turn_id: str = Field(..., alias="turnId") + turn_id: Annotated[str, Field(alias="turnId")] -class UserInput1(BaseModel): +class TextUserInput(BaseModel): model_config = ConfigDict( populate_by_name=True, ) text: str - text_elements: List[TextElement] | None = Field( - [], - description="UI-defined spans within `text` used to render or persist special elements.", - ) - type: Type122 = Field(..., title="TextUserInputType") + text_elements: Annotated[ + list[TextElement] | None, + Field( + description="UI-defined spans within `text` used to render or persist special elements." + ), + ] = [] + type: Annotated[Literal["text"], Field(title="TextUserInputType")] -class Type175(Enum): - image = "image" - - -class UserInput2(BaseModel): +class ImageUserInput(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type175 = Field(..., title="ImageUserInputType") + type: Annotated[Literal["image"], Field(title="ImageUserInputType")] url: str -class Type176(Enum): - local_image = "localImage" - - -class UserInput3(BaseModel): +class LocalImageUserInput(BaseModel): model_config = ConfigDict( populate_by_name=True, ) path: str - type: Type176 = Field(..., title="LocalImageUserInputType") + type: Annotated[Literal["localImage"], Field(title="LocalImageUserInputType")] -class Type177(Enum): - skill = "skill" - - -class UserInput4(BaseModel): +class SkillUserInput(BaseModel): model_config = ConfigDict( populate_by_name=True, ) name: str path: str - type: Type177 = Field(..., title="SkillUserInputType") + type: Annotated[Literal["skill"], Field(title="SkillUserInputType")] -class Type178(Enum): - mention = "mention" - - -class UserInput5(BaseModel): +class MentionUserInput(BaseModel): model_config = ConfigDict( populate_by_name=True, ) name: str path: str - type: Type178 = Field(..., title="MentionUserInputType") + type: Annotated[Literal["mention"], Field(title="MentionUserInputType")] class UserInput( - RootModel[UserInput1 | UserInput2 | UserInput3 | UserInput4 | UserInput5] + RootModel[ + TextUserInput + | ImageUserInput + | LocalImageUserInput + | SkillUserInput + | MentionUserInput + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: UserInput1 | UserInput2 | UserInput3 | UserInput4 | UserInput5 + root: ( + TextUserInput + | ImageUserInput + | LocalImageUserInput + | SkillUserInput + | MentionUserInput + ) class Verbosity(Enum): @@ -4667,54 +4179,62 @@ class Verbosity(Enum): high = "high" -class WebSearchAction1(BaseModel): +class SearchWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - queries: List[str] | None = None + queries: list[str] | None = None query: str | None = None - type: Type5 = Field(..., title="SearchWebSearchActionType") + type: Annotated[Literal["search"], Field(title="SearchWebSearchActionType")] -class Type180(Enum): - open_page = "openPage" - - -class WebSearchAction2(BaseModel): +class OpenPageWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type180 = Field(..., title="OpenPageWebSearchActionType") + type: Annotated[Literal["openPage"], Field(title="OpenPageWebSearchActionType")] url: str | None = None -class Type181(Enum): - find_in_page = "findInPage" - - -class WebSearchAction3(BaseModel): +class FindInPageWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) pattern: str | None = None - type: Type181 = Field(..., title="FindInPageWebSearchActionType") + type: Annotated[Literal["findInPage"], Field(title="FindInPageWebSearchActionType")] url: str | None = None -class WebSearchAction4(BaseModel): +class OtherWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Type135 = Field(..., title="OtherWebSearchActionType") + type: Annotated[Literal["other"], Field(title="OtherWebSearchActionType")] class WebSearchAction( - RootModel[WebSearchAction1 | WebSearchAction2 | WebSearchAction3 | WebSearchAction4] + RootModel[ + SearchWebSearchAction + | OpenPageWebSearchAction + | FindInPageWebSearchAction + | OtherWebSearchAction + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: WebSearchAction1 | WebSearchAction2 | WebSearchAction3 | WebSearchAction4 + root: ( + SearchWebSearchAction + | OpenPageWebSearchAction + | FindInPageWebSearchAction + | OtherWebSearchAction + ) + + +class WebSearchContextSize(Enum): + low = "low" + medium = "medium" + high = "high" class WebSearchLocation(BaseModel): @@ -4739,8 +4259,8 @@ class WebSearchToolConfig(BaseModel): extra="forbid", populate_by_name=True, ) - allowed_domains: List[str] | None = None - context_size: Verbosity | None = None + allowed_domains: list[str] | None = None + context_size: WebSearchContextSize | None = None location: WebSearchLocation | None = None @@ -4768,9 +4288,9 @@ class WindowsWorldWritableWarningNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - extra_count: conint(ge=0) = Field(..., alias="extraCount") - failed_scan: bool = Field(..., alias="failedScan") - sample_paths: List[str] = Field(..., alias="samplePaths") + extra_count: Annotated[int, Field(alias="extraCount", ge=0)] + failed_scan: Annotated[bool, Field(alias="failedScan")] + sample_paths: Annotated[list[str], Field(alias="samplePaths")] class WriteStatus(Enum): @@ -4778,28 +4298,28 @@ class WriteStatus(Enum): ok_overridden = "okOverridden" -class Account2(BaseModel): +class ChatgptAccount(BaseModel): model_config = ConfigDict( populate_by_name=True, ) email: str - plan_type: PlanType = Field(..., alias="planType") - type: Type1 = Field(..., title="ChatgptAccountType") + plan_type: Annotated[PlanType, Field(alias="planType")] + type: Annotated[Literal["chatgpt"], Field(title="ChatgptAccountType")] -class Account(RootModel[Account1 | Account2]): +class Account(RootModel[ApiKeyAccount | ChatgptAccount]): model_config = ConfigDict( populate_by_name=True, ) - root: Account1 | Account2 + root: ApiKeyAccount | ChatgptAccount class AccountUpdatedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - auth_mode: AuthMode | None = Field(None, alias="authMode") - plan_type: PlanType | None = Field(None, alias="planType") + auth_mode: Annotated[AuthMode | None, Field(alias="authMode")] = None + plan_type: Annotated[PlanType | None, Field(alias="planType")] = None class AppConfig(BaseModel): @@ -4818,29 +4338,29 @@ class AppMetadata(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - categories: List[str] | None = None + categories: list[str] | None = None developer: str | None = None - first_party_requires_install: bool | None = Field( - None, alias="firstPartyRequiresInstall" - ) - first_party_type: str | None = Field(None, alias="firstPartyType") + first_party_requires_install: Annotated[ + bool | None, Field(alias="firstPartyRequiresInstall") + ] = None + first_party_type: Annotated[str | None, Field(alias="firstPartyType")] = None review: AppReview | None = None - screenshots: List[AppScreenshot] | None = None - seo_description: str | None = Field(None, alias="seoDescription") - show_in_composer_when_unlinked: bool | None = Field( - None, alias="showInComposerWhenUnlinked" - ) - sub_categories: List[str] | None = Field(None, alias="subCategories") + screenshots: list[AppScreenshot] | None = None + seo_description: Annotated[str | None, Field(alias="seoDescription")] = None + show_in_composer_when_unlinked: Annotated[ + bool | None, Field(alias="showInComposerWhenUnlinked") + ] = None + sub_categories: Annotated[list[str] | None, Field(alias="subCategories")] = None version: str | None = None - version_id: str | None = Field(None, alias="versionId") - version_notes: str | None = Field(None, alias="versionNotes") + version_id: Annotated[str | None, Field(alias="versionId")] = None + version_notes: Annotated[str | None, Field(alias="versionNotes")] = None class AppsConfig(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - field_default: AppsDefaultConfig | None = Field(None, alias="_default") + field_default: Annotated[AppsDefaultConfig | None, Field(alias="_default")] = None class CancelLoginAccountResponse(BaseModel): @@ -4850,363 +4370,436 @@ class CancelLoginAccountResponse(BaseModel): status: CancelLoginAccountStatus -class ClientRequest1(BaseModel): +class InitializeRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method = Field(..., title="InitializeRequestMethod") + method: Annotated[Literal["initialize"], Field(title="InitializeRequestMethod")] params: InitializeParams -class ClientRequest2(BaseModel): +class ThreadStartRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method1 = Field(..., title="Thread/startRequestMethod") + method: Annotated[Literal["thread/start"], Field(title="Thread/startRequestMethod")] params: ThreadStartParams -class ClientRequest3(BaseModel): +class ThreadResumeRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method2 = Field(..., title="Thread/resumeRequestMethod") + method: Annotated[ + Literal["thread/resume"], Field(title="Thread/resumeRequestMethod") + ] params: ThreadResumeParams -class ClientRequest4(BaseModel): +class ThreadForkRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method3 = Field(..., title="Thread/forkRequestMethod") + method: Annotated[Literal["thread/fork"], Field(title="Thread/forkRequestMethod")] params: ThreadForkParams -class ClientRequest5(BaseModel): +class ThreadArchiveRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method4 = Field(..., title="Thread/archiveRequestMethod") + method: Annotated[ + Literal["thread/archive"], Field(title="Thread/archiveRequestMethod") + ] params: ThreadArchiveParams -class ClientRequest6(BaseModel): +class ThreadUnsubscribeRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method5 = Field(..., title="Thread/unsubscribeRequestMethod") + method: Annotated[ + Literal["thread/unsubscribe"], Field(title="Thread/unsubscribeRequestMethod") + ] params: ThreadUnsubscribeParams -class ClientRequest7(BaseModel): +class ThreadNameSetRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method6 = Field(..., title="Thread/name/setRequestMethod") + method: Annotated[ + Literal["thread/name/set"], Field(title="Thread/name/setRequestMethod") + ] params: ThreadSetNameParams -class ClientRequest8(BaseModel): +class ThreadMetadataUpdateRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method7 = Field(..., title="Thread/metadata/updateRequestMethod") + method: Annotated[ + Literal["thread/metadata/update"], + Field(title="Thread/metadata/updateRequestMethod"), + ] params: ThreadMetadataUpdateParams -class ClientRequest9(BaseModel): +class ThreadUnarchiveRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method8 = Field(..., title="Thread/unarchiveRequestMethod") + method: Annotated[ + Literal["thread/unarchive"], Field(title="Thread/unarchiveRequestMethod") + ] params: ThreadUnarchiveParams -class ClientRequest10(BaseModel): +class ThreadCompactStartRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method9 = Field(..., title="Thread/compact/startRequestMethod") + method: Annotated[ + Literal["thread/compact/start"], + Field(title="Thread/compact/startRequestMethod"), + ] params: ThreadCompactStartParams -class ClientRequest11(BaseModel): +class ThreadRollbackRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method10 = Field(..., title="Thread/rollbackRequestMethod") + method: Annotated[ + Literal["thread/rollback"], Field(title="Thread/rollbackRequestMethod") + ] params: ThreadRollbackParams -class ClientRequest13(BaseModel): +class ThreadLoadedListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method12 = Field(..., title="Thread/loaded/listRequestMethod") + method: Annotated[ + Literal["thread/loaded/list"], Field(title="Thread/loaded/listRequestMethod") + ] params: ThreadLoadedListParams -class ClientRequest14(BaseModel): +class ThreadReadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method13 = Field(..., title="Thread/readRequestMethod") + method: Annotated[Literal["thread/read"], Field(title="Thread/readRequestMethod")] params: ThreadReadParams -class ClientRequest15(BaseModel): +class SkillsListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method14 = Field(..., title="Skills/listRequestMethod") + method: Annotated[Literal["skills/list"], Field(title="Skills/listRequestMethod")] params: SkillsListParams -class ClientRequest16(BaseModel): +class PluginListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method15 = Field(..., title="Plugin/listRequestMethod") + method: Annotated[Literal["plugin/list"], Field(title="Plugin/listRequestMethod")] params: PluginListParams -class ClientRequest17(BaseModel): +class SkillsRemoteListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method16 = Field(..., title="Skills/remote/listRequestMethod") + method: Annotated[ + Literal["skills/remote/list"], Field(title="Skills/remote/listRequestMethod") + ] params: SkillsRemoteReadParams -class ClientRequest18(BaseModel): +class SkillsRemoteExportRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method17 = Field(..., title="Skills/remote/exportRequestMethod") + method: Annotated[ + Literal["skills/remote/export"], + Field(title="Skills/remote/exportRequestMethod"), + ] params: SkillsRemoteWriteParams -class ClientRequest19(BaseModel): +class AppListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method18 = Field(..., title="App/listRequestMethod") + method: Annotated[Literal["app/list"], Field(title="App/listRequestMethod")] params: AppsListParams -class ClientRequest20(BaseModel): +class SkillsConfigWriteRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method19 = Field(..., title="Skills/config/writeRequestMethod") + method: Annotated[ + Literal["skills/config/write"], Field(title="Skills/config/writeRequestMethod") + ] params: SkillsConfigWriteParams -class ClientRequest21(BaseModel): +class PluginInstallRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method20 = Field(..., title="Plugin/installRequestMethod") + method: Annotated[ + Literal["plugin/install"], Field(title="Plugin/installRequestMethod") + ] params: PluginInstallParams -class ClientRequest22(BaseModel): +class PluginUninstallRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method21 = Field(..., title="Plugin/uninstallRequestMethod") + method: Annotated[ + Literal["plugin/uninstall"], Field(title="Plugin/uninstallRequestMethod") + ] params: PluginUninstallParams -class ClientRequest25(BaseModel): +class TurnInterruptRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method24 = Field(..., title="Turn/interruptRequestMethod") + method: Annotated[ + Literal["turn/interrupt"], Field(title="Turn/interruptRequestMethod") + ] params: TurnInterruptParams -class ClientRequest27(BaseModel): +class ModelListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method26 = Field(..., title="Model/listRequestMethod") + method: Annotated[Literal["model/list"], Field(title="Model/listRequestMethod")] params: ModelListParams -class ClientRequest28(BaseModel): +class ExperimentalFeatureListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method27 = Field(..., title="ExperimentalFeature/listRequestMethod") + method: Annotated[ + Literal["experimentalFeature/list"], + Field(title="ExperimentalFeature/listRequestMethod"), + ] params: ExperimentalFeatureListParams -class ClientRequest29(BaseModel): +class McpServerOauthLoginRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method28 = Field(..., title="McpServer/oauth/loginRequestMethod") + method: Annotated[ + Literal["mcpServer/oauth/login"], + Field(title="McpServer/oauth/loginRequestMethod"), + ] params: McpServerOauthLoginParams -class ClientRequest30(BaseModel): +class ConfigMcpServerReloadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method29 = Field(..., title="Config/mcpServer/reloadRequestMethod") + method: Annotated[ + Literal["config/mcpServer/reload"], + Field(title="Config/mcpServer/reloadRequestMethod"), + ] params: None = None -class ClientRequest31(BaseModel): +class McpServerStatusListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method30 = Field(..., title="McpServerStatus/listRequestMethod") + method: Annotated[ + Literal["mcpServerStatus/list"], + Field(title="McpServerStatus/listRequestMethod"), + ] params: ListMcpServerStatusParams -class ClientRequest32(BaseModel): +class WindowsSandboxSetupStartRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method31 = Field(..., title="WindowsSandbox/setupStartRequestMethod") + method: Annotated[ + Literal["windowsSandbox/setupStart"], + Field(title="WindowsSandbox/setupStartRequestMethod"), + ] params: WindowsSandboxSetupStartParams -class ClientRequest33(BaseModel): +class AccountLoginStartRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method32 = Field(..., title="Account/login/startRequestMethod") + method: Annotated[ + Literal["account/login/start"], Field(title="Account/login/startRequestMethod") + ] params: LoginAccountParams -class ClientRequest34(BaseModel): +class AccountLoginCancelRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method33 = Field(..., title="Account/login/cancelRequestMethod") + method: Annotated[ + Literal["account/login/cancel"], + Field(title="Account/login/cancelRequestMethod"), + ] params: CancelLoginAccountParams -class ClientRequest35(BaseModel): +class AccountLogoutRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method34 = Field(..., title="Account/logoutRequestMethod") + method: Annotated[ + Literal["account/logout"], Field(title="Account/logoutRequestMethod") + ] params: None = None -class ClientRequest36(BaseModel): +class AccountRateLimitsReadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method35 = Field(..., title="Account/rateLimits/readRequestMethod") + method: Annotated[ + Literal["account/rateLimits/read"], + Field(title="Account/rateLimits/readRequestMethod"), + ] params: None = None -class ClientRequest37(BaseModel): +class FeedbackUploadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method36 = Field(..., title="Feedback/uploadRequestMethod") + method: Annotated[ + Literal["feedback/upload"], Field(title="Feedback/uploadRequestMethod") + ] params: FeedbackUploadParams -class ClientRequest39(BaseModel): +class CommandExecWriteRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method38 = Field(..., title="Command/exec/writeRequestMethod") + method: Annotated[ + Literal["command/exec/write"], Field(title="Command/exec/writeRequestMethod") + ] params: CommandExecWriteParams -class ClientRequest40(BaseModel): +class CommandExecTerminateRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method39 = Field(..., title="Command/exec/terminateRequestMethod") + method: Annotated[ + Literal["command/exec/terminate"], + Field(title="Command/exec/terminateRequestMethod"), + ] params: CommandExecTerminateParams -class ClientRequest42(BaseModel): +class ConfigReadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method41 = Field(..., title="Config/readRequestMethod") + method: Annotated[Literal["config/read"], Field(title="Config/readRequestMethod")] params: ConfigReadParams -class ClientRequest43(BaseModel): +class ExternalAgentConfigDetectRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method42 = Field(..., title="ExternalAgentConfig/detectRequestMethod") + method: Annotated[ + Literal["externalAgentConfig/detect"], + Field(title="ExternalAgentConfig/detectRequestMethod"), + ] params: ExternalAgentConfigDetectParams -class ClientRequest47(BaseModel): +class ConfigRequirementsReadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method46 = Field(..., title="ConfigRequirements/readRequestMethod") + method: Annotated[ + Literal["configRequirements/read"], + Field(title="ConfigRequirements/readRequestMethod"), + ] params: None = None -class ClientRequest48(BaseModel): +class AccountReadRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method47 = Field(..., title="Account/readRequestMethod") + method: Annotated[Literal["account/read"], Field(title="Account/readRequestMethod")] params: GetAccountParams -class ClientRequest49(BaseModel): +class FuzzyFileSearchRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method48 = Field(..., title="FuzzyFileSearchRequestMethod") + method: Annotated[ + Literal["fuzzyFileSearch"], Field(title="FuzzyFileSearchRequestMethod") + ] params: FuzzyFileSearchParams @@ -5214,15 +4807,21 @@ class CollabAgentRef(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - agent_nickname: str | None = Field( - None, - description="Optional nickname assigned to an AgentControl-spawned sub-agent.", - ) - agent_role: str | None = Field( - None, - description="Optional role (agent_role) assigned to an AgentControl-spawned sub-agent.", - ) - thread_id: ThreadId = Field(..., description="Thread ID of the receiver/new agent.") + agent_nickname: Annotated[ + str | None, + Field( + description="Optional nickname assigned to an AgentControl-spawned sub-agent." + ), + ] = None + agent_role: Annotated[ + str | None, + Field( + description="Optional role (agent_role) assigned to an AgentControl-spawned sub-agent." + ), + ] = None + thread_id: Annotated[ + ThreadId, Field(description="Thread ID of the receiver/new agent.") + ] class CollabAgentState(BaseModel): @@ -5237,16 +4836,22 @@ class CollabAgentStatusEntry(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - agent_nickname: str | None = Field( - None, - description="Optional nickname assigned to an AgentControl-spawned sub-agent.", - ) - agent_role: str | None = Field( - None, - description="Optional role (agent_role) assigned to an AgentControl-spawned sub-agent.", - ) - status: AgentStatus = Field(..., description="Last known status of the agent.") - thread_id: ThreadId = Field(..., description="Thread ID of the receiver/new agent.") + agent_nickname: Annotated[ + str | None, + Field( + description="Optional nickname assigned to an AgentControl-spawned sub-agent." + ), + ] = None + agent_role: Annotated[ + str | None, + Field( + description="Optional role (agent_role) assigned to an AgentControl-spawned sub-agent." + ), + ] = None + status: Annotated[AgentStatus, Field(description="Last known status of the agent.")] + thread_id: Annotated[ + ThreadId, Field(description="Thread ID of the receiver/new agent.") + ] class CollaborationMode(BaseModel): @@ -5271,108 +4876,138 @@ class CommandExecOutputDeltaNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cap_reached: bool = Field( - ..., - alias="capReached", - description="`true` on the final streamed chunk for a stream when `outputBytesCap` truncated later output on that stream.", - ) - delta_base64: str = Field( - ..., alias="deltaBase64", description="Base64-encoded output bytes." - ) - process_id: str = Field( - ..., - alias="processId", - description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", - ) - stream: CommandExecOutputStream = Field( - ..., description="Output stream for this chunk." - ) + cap_reached: Annotated[ + bool, + Field( + alias="capReached", + description="`true` on the final streamed chunk for a stream when `outputBytesCap` truncated later output on that stream.", + ), + ] + delta_base64: Annotated[ + str, Field(alias="deltaBase64", description="Base64-encoded output bytes.") + ] + process_id: Annotated[ + str, + Field( + alias="processId", + description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + ), + ] + stream: Annotated[ + CommandExecOutputStream, Field(description="Output stream for this chunk.") + ] class CommandExecParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - command: List[str] = Field( - ..., description="Command argv vector. Empty arrays are rejected." - ) - cwd: str | None = Field( - None, description="Optional working directory. Defaults to the server cwd." - ) - disable_output_cap: bool | None = Field( - None, - alias="disableOutputCap", - description="Disable stdout/stderr capture truncation for this request.\n\nCannot be combined with `outputBytesCap`.", - ) - disable_timeout: bool | None = Field( - None, - alias="disableTimeout", - description="Disable the timeout entirely for this request.\n\nCannot be combined with `timeoutMs`.", - ) - env: Dict[str, Any] | None = Field( - None, - 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.", - ) - output_bytes_cap: conint(ge=0) | None = Field( - None, - alias="outputBytesCap", - description="Optional per-stream stdout/stderr capture cap in bytes.\n\nWhen omitted, the server default applies. Cannot be combined with `disableOutputCap`.", - ) - process_id: str | None = Field( - None, - alias="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.", - ) - sandbox_policy: SandboxPolicy | None = Field( - None, - alias="sandboxPolicy", - 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.", - ) - size: CommandExecTerminalSize | None = Field( - None, - description="Optional initial PTY size in character cells. Only valid when `tty` is true.", - ) - stream_stdin: bool | None = Field( - None, - alias="streamStdin", - description="Allow follow-up `command/exec/write` requests to write stdin bytes.\n\nRequires a client-supplied `processId`.", - ) - stream_stdout_stderr: bool | None = Field( - None, - alias="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`.", - ) - timeout_ms: int | None = Field( - None, - alias="timeoutMs", - description="Optional timeout in milliseconds.\n\nWhen omitted, the server default applies. Cannot be combined with `disableTimeout`.", - ) - tty: bool | None = Field( - None, - description="Enable PTY mode.\n\nThis implies `streamStdin` and `streamStdoutStderr`.", - ) + command: Annotated[ + list[str], Field(description="Command argv vector. Empty arrays are rejected.") + ] + cwd: Annotated[ + str | None, + Field(description="Optional working directory. Defaults to the server cwd."), + ] = None + disable_output_cap: Annotated[ + bool | None, + Field( + alias="disableOutputCap", + description="Disable stdout/stderr capture truncation for this request.\n\nCannot be combined with `outputBytesCap`.", + ), + ] = None + disable_timeout: Annotated[ + bool | None, + Field( + alias="disableTimeout", + description="Disable the timeout entirely for this request.\n\nCannot be combined with `timeoutMs`.", + ), + ] = None + env: Annotated[ + dict[str, Any] | None, + Field( + 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." + ), + ] = None + output_bytes_cap: Annotated[ + int | None, + Field( + alias="outputBytesCap", + description="Optional per-stream stdout/stderr capture cap in bytes.\n\nWhen omitted, the server default applies. Cannot be combined with `disableOutputCap`.", + ge=0, + ), + ] = None + process_id: Annotated[ + str | None, + Field( + alias="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.", + ), + ] = None + sandbox_policy: Annotated[ + SandboxPolicy | None, + Field( + alias="sandboxPolicy", + 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.", + ), + ] = None + size: Annotated[ + CommandExecTerminalSize | None, + Field( + description="Optional initial PTY size in character cells. Only valid when `tty` is true." + ), + ] = None + stream_stdin: Annotated[ + bool | None, + Field( + alias="streamStdin", + description="Allow follow-up `command/exec/write` requests to write stdin bytes.\n\nRequires a client-supplied `processId`.", + ), + ] = None + stream_stdout_stderr: Annotated[ + bool | None, + Field( + alias="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`.", + ), + ] = None + timeout_ms: Annotated[ + int | None, + Field( + alias="timeoutMs", + description="Optional timeout in milliseconds.\n\nWhen omitted, the server default applies. Cannot be combined with `disableTimeout`.", + ), + ] = None + tty: Annotated[ + bool | None, + Field( + description="Enable PTY mode.\n\nThis implies `streamStdin` and `streamStdoutStderr`." + ), + ] = None class CommandExecResizeParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - process_id: str = Field( - ..., - alias="processId", - description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", - ) - size: CommandExecTerminalSize = Field( - ..., description="New PTY size in character cells." - ) + process_id: Annotated[ + str, + Field( + alias="processId", + description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", + ), + ] + size: Annotated[ + CommandExecTerminalSize, Field(description="New PTY size in character cells.") + ] class ConfigEdit(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - key_path: str = Field(..., alias="keyPath") - merge_strategy: MergeStrategy = Field(..., alias="mergeStrategy") + key_path: Annotated[str, Field(alias="keyPath")] + merge_strategy: Annotated[MergeStrategy, Field(alias="mergeStrategy")] value: Any @@ -5381,7 +5016,7 @@ class ConfigLayer(BaseModel): populate_by_name=True, ) config: Any - disabled_reason: str | None = Field(None, alias="disabledReason") + disabled_reason: Annotated[str | None, Field(alias="disabledReason")] = None name: ConfigLayerSource version: str @@ -5398,45 +5033,49 @@ class ConfigRequirements(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - allowed_approval_policies: List[AskForApproval] | None = Field( - None, alias="allowedApprovalPolicies" - ) - allowed_sandbox_modes: List[SandboxMode] | None = Field( - None, alias="allowedSandboxModes" - ) - allowed_web_search_modes: List[WebSearchMode] | None = Field( - None, alias="allowedWebSearchModes" - ) - enforce_residency: ResidencyRequirement | None = Field( - None, alias="enforceResidency" - ) - feature_requirements: Dict[str, Any] | None = Field( - None, alias="featureRequirements" - ) + allowed_approval_policies: Annotated[ + list[AskForApproval] | None, Field(alias="allowedApprovalPolicies") + ] = None + allowed_sandbox_modes: Annotated[ + list[SandboxMode] | None, Field(alias="allowedSandboxModes") + ] = None + allowed_web_search_modes: Annotated[ + list[WebSearchMode] | None, Field(alias="allowedWebSearchModes") + ] = None + enforce_residency: Annotated[ + ResidencyRequirement | None, Field(alias="enforceResidency") + ] = None + feature_requirements: Annotated[ + dict[str, Any] | None, Field(alias="featureRequirements") + ] = None class ConfigRequirementsReadResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - requirements: ConfigRequirements | None = Field( - None, - description="Null if no requirements are configured (e.g. no requirements.toml/MDM entries).", - ) + requirements: Annotated[ + ConfigRequirements | None, + Field( + description="Null if no requirements are configured (e.g. no requirements.toml/MDM entries)." + ), + ] = None class ConfigValueWriteParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - expected_version: str | None = Field(None, alias="expectedVersion") - file_path: str | None = Field( - None, - alias="filePath", - description="Path to the config file to write; defaults to the user's `config.toml` when omitted.", - ) - key_path: str = Field(..., alias="keyPath") - merge_strategy: MergeStrategy = Field(..., alias="mergeStrategy") + expected_version: Annotated[str | None, Field(alias="expectedVersion")] = None + file_path: Annotated[ + str | None, + Field( + alias="filePath", + description="Path to the config file to write; defaults to the user's `config.toml` when omitted.", + ), + ] = None + key_path: Annotated[str, Field(alias="keyPath")] + merge_strategy: Annotated[MergeStrategy, Field(alias="mergeStrategy")] value: Any @@ -5444,17 +5083,22 @@ class ConfigWarningNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - details: str | None = Field( - None, description="Optional extra guidance or error details." - ) - path: str | None = Field( - None, description="Optional path to the config file that triggered the warning." - ) - range: TextRange | None = Field( - None, - description="Optional range for the error location inside the config file.", - ) - summary: str = Field(..., description="Concise summary of the warning.") + details: Annotated[ + str | None, Field(description="Optional extra guidance or error details.") + ] = None + path: Annotated[ + str | None, + Field( + description="Optional path to the config file that triggered the warning." + ), + ] = None + range: Annotated[ + TextRange | None, + Field( + description="Optional range for the error location inside the config file." + ), + ] = None + summary: Annotated[str, Field(description="Concise summary of the warning.")] class ErrorNotification(BaseModel): @@ -5462,606 +5106,789 @@ class ErrorNotification(BaseModel): populate_by_name=True, ) error: TurnError - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") - will_retry: bool = Field(..., alias="willRetry") + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] + will_retry: Annotated[bool, Field(alias="willRetry")] -class EventMsg6(BaseModel): +class ModelRerouteEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) from_model: str reason: ModelRerouteReason to_model: str - type: Type24 = Field(..., title="ModelRerouteEventMsgType") + type: Annotated[Literal["model_reroute"], Field(title="ModelRerouteEventMsgType")] -class EventMsg9(BaseModel): +class TaskStartedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) collaboration_mode_kind: ModeKind | None = "default" model_context_window: int | None = None turn_id: str - type: Type27 = Field(..., title="TaskStartedEventMsgType") + type: Annotated[Literal["task_started"], Field(title="TaskStartedEventMsgType")] -class EventMsg12(BaseModel): +class AgentMessageEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) message: str phase: MessagePhase | None = None - type: Type30 = Field(..., title="AgentMessageEventMsgType") + type: Annotated[Literal["agent_message"], Field(title="AgentMessageEventMsgType")] -class EventMsg13(BaseModel): +class UserMessageEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - images: List[str] | None = Field( - None, - description="Image URLs sourced from `UserInput::Image`. These are safe to replay in legacy UI history events and correspond to images sent to the model.", - ) - local_images: List[str] | None = Field( - [], - description="Local file paths sourced from `UserInput::LocalImage`. These are kept so the UI can reattach images when editing history, and should not be sent to the model or treated as API-ready URLs.", - ) + images: Annotated[ + list[str] | None, + Field( + description="Image URLs sourced from `UserInput::Image`. These are safe to replay in legacy UI history events and correspond to images sent to the model." + ), + ] = None + local_images: Annotated[ + list[str] | None, + Field( + description="Local file paths sourced from `UserInput::LocalImage`. These are kept so the UI can reattach images when editing history, and should not be sent to the model or treated as API-ready URLs." + ), + ] = [] message: str - text_elements: List[TextElement] | None = Field( - [], - description="UI-defined spans within `message` used to render or persist special elements.", - ) - type: Type31 = Field(..., title="UserMessageEventMsgType") + text_elements: Annotated[ + list[TextElement] | None, + Field( + description="UI-defined spans within `message` used to render or persist special elements." + ), + ] = [] + type: Annotated[Literal["user_message"], Field(title="UserMessageEventMsgType")] -class EventMsg21(BaseModel): +class ThreadNameUpdatedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) thread_id: ThreadId thread_name: str | None = None - type: Type39 = Field(..., title="ThreadNameUpdatedEventMsgType") + type: Annotated[ + Literal["thread_name_updated"], Field(title="ThreadNameUpdatedEventMsgType") + ] -class EventMsg22(BaseModel): +class McpStartupUpdateEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - server: str = Field(..., description="Server name being started.") - status: McpStartupStatus = Field(..., description="Current startup status.") - type: Type40 = Field(..., title="McpStartupUpdateEventMsgType") + server: Annotated[str, Field(description="Server name being started.")] + status: Annotated[McpStartupStatus, Field(description="Current startup status.")] + type: Annotated[ + Literal["mcp_startup_update"], Field(title="McpStartupUpdateEventMsgType") + ] -class EventMsg23(BaseModel): +class McpStartupCompleteEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cancelled: List[str] - failed: List[McpStartupFailure] - ready: List[str] - type: Type41 = Field(..., title="McpStartupCompleteEventMsgType") + cancelled: list[str] + failed: list[McpStartupFailure] + ready: list[str] + type: Annotated[ + Literal["mcp_startup_complete"], Field(title="McpStartupCompleteEventMsgType") + ] -class EventMsg24(BaseModel): +class McpToolCallBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., - description="Identifier so this can be paired with the McpToolCallEnd event.", - ) + call_id: Annotated[ + str, + Field( + description="Identifier so this can be paired with the McpToolCallEnd event." + ), + ] invocation: McpInvocation - type: Type42 = Field(..., title="McpToolCallBeginEventMsgType") + type: Annotated[ + Literal["mcp_tool_call_begin"], Field(title="McpToolCallBeginEventMsgType") + ] -class EventMsg25(BaseModel): +class McpToolCallEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., - description="Identifier for the corresponding McpToolCallBegin that finished.", - ) + call_id: Annotated[ + str, + Field( + description="Identifier for the corresponding McpToolCallBegin that finished." + ), + ] duration: Duration invocation: McpInvocation - result: ResultOfCallToolResultOrString = Field( - ..., description="Result of the tool call. Note this could be an error." - ) - type: Type43 = Field(..., title="McpToolCallEndEventMsgType") + result: Annotated[ + ResultOfCallToolResultOrString, + Field(description="Result of the tool call. Note this could be an error."), + ] + type: Annotated[ + Literal["mcp_tool_call_end"], Field(title="McpToolCallEndEventMsgType") + ] -class EventMsg27(BaseModel): +class WebSearchEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) action: ResponsesApiWebSearchAction call_id: str query: str - type: Type45 = Field(..., title="WebSearchEndEventMsgType") + type: Annotated[Literal["web_search_end"], Field(title="WebSearchEndEventMsgType")] -class EventMsg30(BaseModel): +class ExecCommandBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., - description="Identifier so this can be paired with the ExecCommandEnd event.", - ) - command: List[str] = Field(..., description="The command to be executed.") - cwd: str = Field( - ..., - description="The command's working directory if not the default cwd for the agent.", - ) - interaction_input: str | None = Field( - None, - description="Raw input sent to a unified exec session (if this is an interaction event).", - ) - parsed_cmd: List[ParsedCommand] - process_id: str | None = Field( - None, description="Identifier for the underlying PTY process (when available)." - ) - source: ExecCommandSource | None = Field( - "agent", - description="Where the command originated. Defaults to Agent for backward compatibility.", - ) - turn_id: str = Field(..., description="Turn ID that this command belongs to.") - type: Type48 = Field(..., title="ExecCommandBeginEventMsgType") + call_id: Annotated[ + str, + Field( + description="Identifier so this can be paired with the ExecCommandEnd event." + ), + ] + command: Annotated[list[str], Field(description="The command to be executed.")] + cwd: Annotated[ + str, + Field( + description="The command's working directory if not the default cwd for the agent." + ), + ] + interaction_input: Annotated[ + str | None, + Field( + description="Raw input sent to a unified exec session (if this is an interaction event)." + ), + ] = None + parsed_cmd: list[ParsedCommand] + process_id: Annotated[ + str | None, + Field( + description="Identifier for the underlying PTY process (when available)." + ), + ] = None + source: Annotated[ + ExecCommandSource | None, + Field( + description="Where the command originated. Defaults to Agent for backward compatibility." + ), + ] = "agent" + turn_id: Annotated[str, Field(description="Turn ID that this command belongs to.")] + type: Annotated[ + Literal["exec_command_begin"], Field(title="ExecCommandBeginEventMsgType") + ] -class EventMsg31(BaseModel): +class ExecCommandOutputDeltaEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., description="Identifier for the ExecCommandBegin that produced this chunk." - ) - chunk: str = Field( - ..., description="Raw bytes from the stream (may not be valid UTF-8)." - ) - stream: CommandExecOutputStream = Field( - ..., description="Which stream produced this chunk." - ) - type: Type49 = Field(..., title="ExecCommandOutputDeltaEventMsgType") + call_id: Annotated[ + str, + Field( + description="Identifier for the ExecCommandBegin that produced this chunk." + ), + ] + chunk: Annotated[ + str, Field(description="Raw bytes from the stream (may not be valid UTF-8).") + ] + stream: Annotated[ + ExecOutputStream, Field(description="Which stream produced this chunk.") + ] + type: Annotated[ + Literal["exec_command_output_delta"], + Field(title="ExecCommandOutputDeltaEventMsgType"), + ] -class EventMsg33(BaseModel): +class ExecCommandEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - aggregated_output: str | None = Field("", description="Captured aggregated output") - call_id: str = Field( - ..., description="Identifier for the ExecCommandBegin that finished." - ) - command: List[str] = Field(..., description="The command that was executed.") - cwd: str = Field( - ..., - description="The command's working directory if not the default cwd for the agent.", - ) - duration: Duration = Field( - ..., description="The duration of the command execution." - ) - exit_code: int = Field(..., description="The command's exit code.") - formatted_output: str = Field( - ..., description="Formatted output from the command, as seen by the model." - ) - interaction_input: str | None = Field( - None, - description="Raw input sent to a unified exec session (if this is an interaction event).", - ) - parsed_cmd: List[ParsedCommand] - process_id: str | None = Field( - None, description="Identifier for the underlying PTY process (when available)." - ) - source: ExecCommandSource | None = Field( - "agent", - description="Where the command originated. Defaults to Agent for backward compatibility.", - ) - status: ExecCommandStatus = Field( - ..., description="Completion status for this command execution." - ) - stderr: str = Field(..., description="Captured stderr") - stdout: str = Field(..., description="Captured stdout") - turn_id: str = Field(..., description="Turn ID that this command belongs to.") - type: Type51 = Field(..., title="ExecCommandEndEventMsgType") + aggregated_output: Annotated[ + str | None, Field(description="Captured aggregated output") + ] = "" + call_id: Annotated[ + str, Field(description="Identifier for the ExecCommandBegin that finished.") + ] + command: Annotated[list[str], Field(description="The command that was executed.")] + cwd: Annotated[ + str, + Field( + description="The command's working directory if not the default cwd for the agent." + ), + ] + duration: Annotated[ + Duration, Field(description="The duration of the command execution.") + ] + exit_code: Annotated[int, Field(description="The command's exit code.")] + formatted_output: Annotated[ + str, + Field(description="Formatted output from the command, as seen by the model."), + ] + interaction_input: Annotated[ + str | None, + Field( + description="Raw input sent to a unified exec session (if this is an interaction event)." + ), + ] = None + parsed_cmd: list[ParsedCommand] + process_id: Annotated[ + str | None, + Field( + description="Identifier for the underlying PTY process (when available)." + ), + ] = None + source: Annotated[ + ExecCommandSource | None, + Field( + description="Where the command originated. Defaults to Agent for backward compatibility." + ), + ] = "agent" + status: Annotated[ + ExecCommandStatus, + Field(description="Completion status for this command execution."), + ] + stderr: Annotated[str, Field(description="Captured stderr")] + stdout: Annotated[str, Field(description="Captured stdout")] + turn_id: Annotated[str, Field(description="Turn ID that this command belongs to.")] + type: Annotated[ + Literal["exec_command_end"], Field(title="ExecCommandEndEventMsgType") + ] -class EventMsg36(BaseModel): +class RequestPermissionsEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., - description="Responses API call id for the associated tool call, if available.", - ) + call_id: Annotated[ + str, + Field( + description="Responses API call id for the associated tool call, if available." + ), + ] permissions: PermissionProfile reason: str | None = None - turn_id: str | None = Field( - "", - description="Turn ID that this request belongs to. Uses `#[serde(default)]` for backwards compatibility.", - ) - type: Type54 = Field(..., title="RequestPermissionsEventMsgType") + turn_id: Annotated[ + str | None, + Field( + description="Turn ID that this request belongs to. Uses `#[serde(default)]` for backwards compatibility." + ), + ] = "" + type: Annotated[ + Literal["request_permissions"], Field(title="RequestPermissionsEventMsgType") + ] -class EventMsg40(BaseModel): +class ElicitationRequestEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId request: ElicitationRequest server_name: str - turn_id: str | None = Field( - None, description="Turn ID that this elicitation belongs to, when known." - ) - type: Type58 = Field(..., title="ElicitationRequestEventMsgType") + turn_id: Annotated[ + str | None, + Field(description="Turn ID that this elicitation belongs to, when known."), + ] = None + type: Annotated[ + Literal["elicitation_request"], Field(title="ElicitationRequestEventMsgType") + ] -class EventMsg41(BaseModel): +class ApplyPatchApprovalRequestEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., - description="Responses API call id for the associated patch apply call, if available.", - ) - changes: Dict[str, FileChange] - grant_root: str | None = Field( - None, - description="When set, the agent is asking the user to allow writes under this root for the remainder of the session.", - ) - reason: str | None = Field( - None, - description="Optional explanatory reason (e.g. request for extra write access).", - ) - turn_id: str | None = Field( - "", - description="Turn ID that this patch belongs to. Uses `#[serde(default)]` for backwards compatibility with older senders.", - ) - type: Type59 = Field(..., title="ApplyPatchApprovalRequestEventMsgType") + call_id: Annotated[ + str, + Field( + description="Responses API call id for the associated patch apply call, if available." + ), + ] + changes: dict[str, FileChange] + grant_root: Annotated[ + str | None, + Field( + description="When set, the agent is asking the user to allow writes under this root for the remainder of the session." + ), + ] = None + reason: Annotated[ + str | None, + Field( + description="Optional explanatory reason (e.g. request for extra write access)." + ), + ] = None + turn_id: Annotated[ + str | None, + Field( + description="Turn ID that this patch belongs to. Uses `#[serde(default)]` for backwards compatibility with older senders." + ), + ] = "" + type: Annotated[ + Literal["apply_patch_approval_request"], + Field(title="ApplyPatchApprovalRequestEventMsgType"), + ] -class EventMsg47(BaseModel): +class PatchApplyBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - auto_approved: bool = Field( - ..., - description="If true, there was no ApplyPatchApprovalRequest for this patch.", - ) - call_id: str = Field( - ..., - description="Identifier so this can be paired with the PatchApplyEnd event.", - ) - changes: Dict[str, FileChange] = Field( - ..., description="The changes to be applied." - ) - turn_id: str | None = Field( - "", - description="Turn ID that this patch belongs to. Uses `#[serde(default)]` for backwards compatibility.", - ) - type: Type65 = Field(..., title="PatchApplyBeginEventMsgType") + auto_approved: Annotated[ + bool, + Field( + description="If true, there was no ApplyPatchApprovalRequest for this patch." + ), + ] + call_id: Annotated[ + str, + Field( + description="Identifier so this can be paired with the PatchApplyEnd event." + ), + ] + changes: Annotated[ + dict[str, FileChange], Field(description="The changes to be applied.") + ] + turn_id: Annotated[ + str | None, + Field( + description="Turn ID that this patch belongs to. Uses `#[serde(default)]` for backwards compatibility." + ), + ] = "" + type: Annotated[ + Literal["patch_apply_begin"], Field(title="PatchApplyBeginEventMsgType") + ] -class EventMsg48(BaseModel): +class PatchApplyEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., description="Identifier for the PatchApplyBegin that finished." - ) - changes: Dict[str, FileChange] | None = Field( - {}, - description="The changes that were applied (mirrors PatchApplyBeginEvent::changes).", - ) - status: CommandExecutionStatus = Field( - ..., description="Completion status for this patch application." - ) - stderr: str = Field( - ..., description="Captured stderr (parser errors, IO failures, etc.)." - ) - stdout: str = Field( - ..., description="Captured stdout (summary printed by apply_patch)." - ) - success: bool = Field( - ..., description="Whether the patch was applied successfully." - ) - turn_id: str | None = Field( - "", - description="Turn ID that this patch belongs to. Uses `#[serde(default)]` for backwards compatibility.", - ) - type: Type66 = Field(..., title="PatchApplyEndEventMsgType") + call_id: Annotated[ + str, Field(description="Identifier for the PatchApplyBegin that finished.") + ] + changes: Annotated[ + dict[str, FileChange] | None, + Field( + description="The changes that were applied (mirrors PatchApplyBeginEvent::changes)." + ), + ] = {} + status: Annotated[ + PatchApplyStatus, + Field(description="Completion status for this patch application."), + ] + stderr: Annotated[ + str, Field(description="Captured stderr (parser errors, IO failures, etc.).") + ] + stdout: Annotated[ + str, Field(description="Captured stdout (summary printed by apply_patch).") + ] + success: Annotated[ + bool, Field(description="Whether the patch was applied successfully.") + ] + turn_id: Annotated[ + str | None, + Field( + description="Turn ID that this patch belongs to. Uses `#[serde(default)]` for backwards compatibility." + ), + ] = "" + type: Annotated[ + Literal["patch_apply_end"], Field(title="PatchApplyEndEventMsgType") + ] -class EventMsg50(BaseModel): +class GetHistoryEntryResponseEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - entry: HistoryEntry | None = Field( - None, - description="The entry at the requested offset, if available and parseable.", - ) - log_id: conint(ge=0) - offset: conint(ge=0) - type: Type68 = Field(..., title="GetHistoryEntryResponseEventMsgType") + entry: Annotated[ + HistoryEntry | None, + Field( + description="The entry at the requested offset, if available and parseable." + ), + ] = None + log_id: Annotated[int, Field(ge=0)] + offset: Annotated[int, Field(ge=0)] + type: Annotated[ + Literal["get_history_entry_response"], + Field(title="GetHistoryEntryResponseEventMsgType"), + ] -class EventMsg51(BaseModel): +class McpListToolsResponseEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - auth_statuses: Dict[str, McpAuthStatus] = Field( - ..., description="Authentication status for each configured MCP server." - ) - resource_templates: Dict[str, List[ResourceTemplate]] = Field( - ..., description="Known resource templates grouped by server name." - ) - resources: Dict[str, List[Resource]] = Field( - ..., description="Known resources grouped by server name." - ) - tools: Dict[str, Tool] = Field( - ..., description="Fully qualified tool name -> tool definition." - ) - type: Type69 = Field(..., title="McpListToolsResponseEventMsgType") + auth_statuses: Annotated[ + dict[str, McpAuthStatus], + Field(description="Authentication status for each configured MCP server."), + ] + resource_templates: Annotated[ + dict[str, list[ResourceTemplate]], + Field(description="Known resource templates grouped by server name."), + ] + resources: Annotated[ + dict[str, list[Resource]], + Field(description="Known resources grouped by server name."), + ] + tools: Annotated[ + dict[str, Tool], + Field(description="Fully qualified tool name -> tool definition."), + ] + type: Annotated[ + Literal["mcp_list_tools_response"], + Field(title="McpListToolsResponseEventMsgType"), + ] -class EventMsg54(BaseModel): +class ListRemoteSkillsResponseEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - skills: List[RemoteSkillSummary] - type: Type72 = Field(..., title="ListRemoteSkillsResponseEventMsgType") + skills: list[RemoteSkillSummary] + type: Annotated[ + Literal["list_remote_skills_response"], + Field(title="ListRemoteSkillsResponseEventMsgType"), + ] -class EventMsg58(BaseModel): +class TurnAbortedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) reason: TurnAbortReason turn_id: str | None = None - type: Type76 = Field(..., title="TurnAbortedEventMsgType") + type: Annotated[Literal["turn_aborted"], Field(title="TurnAbortedEventMsgType")] -class EventMsg60(BaseModel): +class EnteredReviewModeEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) target: ReviewTarget - type: Type78 = Field(..., title="EnteredReviewModeEventMsgType") + type: Annotated[ + Literal["entered_review_mode"], Field(title="EnteredReviewModeEventMsgType") + ] user_facing_hint: str | None = None -class EventMsg71(BaseModel): +class CollabAgentSpawnBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the collab tool call.") - prompt: str = Field( - ..., - description="Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the beginning.", - ) - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - type: Type89 = Field(..., title="CollabAgentSpawnBeginEventMsgType") + call_id: Annotated[str, Field(description="Identifier for the collab tool call.")] + prompt: Annotated[ + str, + Field( + description="Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the beginning." + ), + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + type: Annotated[ + Literal["collab_agent_spawn_begin"], + Field(title="CollabAgentSpawnBeginEventMsgType"), + ] -class EventMsg72(BaseModel): +class CollabAgentSpawnEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the collab tool call.") - new_agent_nickname: str | None = Field( - None, description="Optional nickname assigned to the new agent." - ) - new_agent_role: str | None = Field( - None, description="Optional role assigned to the new agent." - ) - new_thread_id: ThreadId | None = Field( - None, description="Thread ID of the newly spawned agent, if it was created." - ) - prompt: str = Field( - ..., - description="Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the beginning.", - ) - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - status: AgentStatus = Field( - ..., - description="Last known status of the new agent reported to the sender agent.", - ) - type: Type90 = Field(..., title="CollabAgentSpawnEndEventMsgType") + call_id: Annotated[str, Field(description="Identifier for the collab tool call.")] + new_agent_nickname: Annotated[ + str | None, Field(description="Optional nickname assigned to the new agent.") + ] = None + new_agent_role: Annotated[ + str | None, Field(description="Optional role assigned to the new agent.") + ] = None + new_thread_id: Annotated[ + ThreadId | None, + Field(description="Thread ID of the newly spawned agent, if it was created."), + ] = None + prompt: Annotated[ + str, + Field( + description="Initial prompt sent to the agent. Can be empty to prevent CoT leaking at the beginning." + ), + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + status: Annotated[ + AgentStatus, + Field( + description="Last known status of the new agent reported to the sender agent." + ), + ] + type: Annotated[ + Literal["collab_agent_spawn_end"], + Field(title="CollabAgentSpawnEndEventMsgType"), + ] -class EventMsg73(BaseModel): +class CollabAgentInteractionBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the collab tool call.") - prompt: str = Field( - ..., - description="Prompt sent from the sender to the receiver. Can be empty to prevent CoT leaking at the beginning.", - ) - receiver_thread_id: ThreadId = Field(..., description="Thread ID of the receiver.") - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - type: Type91 = Field(..., title="CollabAgentInteractionBeginEventMsgType") + call_id: Annotated[str, Field(description="Identifier for the collab tool call.")] + prompt: Annotated[ + str, + Field( + description="Prompt sent from the sender to the receiver. Can be empty to prevent CoT leaking at the beginning." + ), + ] + receiver_thread_id: Annotated[ + ThreadId, Field(description="Thread ID of the receiver.") + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + type: Annotated[ + Literal["collab_agent_interaction_begin"], + Field(title="CollabAgentInteractionBeginEventMsgType"), + ] -class EventMsg74(BaseModel): +class CollabAgentInteractionEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the collab tool call.") - prompt: str = Field( - ..., - description="Prompt sent from the sender to the receiver. Can be empty to prevent CoT leaking at the beginning.", - ) - receiver_agent_nickname: str | None = Field( - None, description="Optional nickname assigned to the receiver agent." - ) - receiver_agent_role: str | None = Field( - None, description="Optional role assigned to the receiver agent." - ) - receiver_thread_id: ThreadId = Field(..., description="Thread ID of the receiver.") - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - status: AgentStatus = Field( - ..., - description="Last known status of the receiver agent reported to the sender agent.", - ) - type: Type92 = Field(..., title="CollabAgentInteractionEndEventMsgType") + call_id: Annotated[str, Field(description="Identifier for the collab tool call.")] + prompt: Annotated[ + str, + Field( + description="Prompt sent from the sender to the receiver. Can be empty to prevent CoT leaking at the beginning." + ), + ] + receiver_agent_nickname: Annotated[ + str | None, + Field(description="Optional nickname assigned to the receiver agent."), + ] = None + receiver_agent_role: Annotated[ + str | None, Field(description="Optional role assigned to the receiver agent.") + ] = None + receiver_thread_id: Annotated[ + ThreadId, Field(description="Thread ID of the receiver.") + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + status: Annotated[ + AgentStatus, + Field( + description="Last known status of the receiver agent reported to the sender agent." + ), + ] + type: Annotated[ + Literal["collab_agent_interaction_end"], + Field(title="CollabAgentInteractionEndEventMsgType"), + ] -class EventMsg75(BaseModel): +class CollabWaitingBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="ID of the waiting call.") - receiver_agents: List[CollabAgentRef] | None = Field( - None, description="Optional nicknames/roles for receivers." - ) - receiver_thread_ids: List[ThreadId] = Field( - ..., description="Thread ID of the receivers." - ) - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - type: Type93 = Field(..., title="CollabWaitingBeginEventMsgType") + call_id: Annotated[str, Field(description="ID of the waiting call.")] + receiver_agents: Annotated[ + list[CollabAgentRef] | None, + Field(description="Optional nicknames/roles for receivers."), + ] = None + receiver_thread_ids: Annotated[ + list[ThreadId], Field(description="Thread ID of the receivers.") + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + type: Annotated[ + Literal["collab_waiting_begin"], Field(title="CollabWaitingBeginEventMsgType") + ] -class EventMsg76(BaseModel): +class CollabWaitingEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - agent_statuses: List[CollabAgentStatusEntry] | None = Field( - None, description="Optional receiver metadata paired with final statuses." - ) - call_id: str = Field(..., description="ID of the waiting call.") - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - statuses: Dict[str, AgentStatus] = Field( - ..., - description="Last known status of the receiver agents reported to the sender agent.", - ) - type: Type94 = Field(..., title="CollabWaitingEndEventMsgType") + agent_statuses: Annotated[ + list[CollabAgentStatusEntry] | None, + Field(description="Optional receiver metadata paired with final statuses."), + ] = None + call_id: Annotated[str, Field(description="ID of the waiting call.")] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + statuses: Annotated[ + dict[str, AgentStatus], + Field( + description="Last known status of the receiver agents reported to the sender agent." + ), + ] + type: Annotated[ + Literal["collab_waiting_end"], Field(title="CollabWaitingEndEventMsgType") + ] -class EventMsg77(BaseModel): +class CollabCloseBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the collab tool call.") - receiver_thread_id: ThreadId = Field(..., description="Thread ID of the receiver.") - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - type: Type95 = Field(..., title="CollabCloseBeginEventMsgType") + call_id: Annotated[str, Field(description="Identifier for the collab tool call.")] + receiver_thread_id: Annotated[ + ThreadId, Field(description="Thread ID of the receiver.") + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + type: Annotated[ + Literal["collab_close_begin"], Field(title="CollabCloseBeginEventMsgType") + ] -class EventMsg78(BaseModel): +class CollabCloseEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the collab tool call.") - receiver_agent_nickname: str | None = Field( - None, description="Optional nickname assigned to the receiver agent." - ) - receiver_agent_role: str | None = Field( - None, description="Optional role assigned to the receiver agent." - ) - receiver_thread_id: ThreadId = Field(..., description="Thread ID of the receiver.") - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - status: AgentStatus = Field( - ..., - description="Last known status of the receiver agent reported to the sender agent before the close.", - ) - type: Type96 = Field(..., title="CollabCloseEndEventMsgType") + call_id: Annotated[str, Field(description="Identifier for the collab tool call.")] + receiver_agent_nickname: Annotated[ + str | None, + Field(description="Optional nickname assigned to the receiver agent."), + ] = None + receiver_agent_role: Annotated[ + str | None, Field(description="Optional role assigned to the receiver agent.") + ] = None + receiver_thread_id: Annotated[ + ThreadId, Field(description="Thread ID of the receiver.") + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + status: Annotated[ + AgentStatus, + Field( + description="Last known status of the receiver agent reported to the sender agent before the close." + ), + ] + type: Annotated[ + Literal["collab_close_end"], Field(title="CollabCloseEndEventMsgType") + ] -class EventMsg79(BaseModel): +class CollabResumeBeginEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the collab tool call.") - receiver_agent_nickname: str | None = Field( - None, description="Optional nickname assigned to the receiver agent." - ) - receiver_agent_role: str | None = Field( - None, description="Optional role assigned to the receiver agent." - ) - receiver_thread_id: ThreadId = Field(..., description="Thread ID of the receiver.") - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - type: Type97 = Field(..., title="CollabResumeBeginEventMsgType") + call_id: Annotated[str, Field(description="Identifier for the collab tool call.")] + receiver_agent_nickname: Annotated[ + str | None, + Field(description="Optional nickname assigned to the receiver agent."), + ] = None + receiver_agent_role: Annotated[ + str | None, Field(description="Optional role assigned to the receiver agent.") + ] = None + receiver_thread_id: Annotated[ + ThreadId, Field(description="Thread ID of the receiver.") + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + type: Annotated[ + Literal["collab_resume_begin"], Field(title="CollabResumeBeginEventMsgType") + ] -class EventMsg80(BaseModel): +class CollabResumeEndEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field(..., description="Identifier for the collab tool call.") - receiver_agent_nickname: str | None = Field( - None, description="Optional nickname assigned to the receiver agent." - ) - receiver_agent_role: str | None = Field( - None, description="Optional role assigned to the receiver agent." - ) - receiver_thread_id: ThreadId = Field(..., description="Thread ID of the receiver.") - sender_thread_id: ThreadId = Field(..., description="Thread ID of the sender.") - status: AgentStatus = Field( - ..., - description="Last known status of the receiver agent reported to the sender agent after resume.", - ) - type: Type98 = Field(..., title="CollabResumeEndEventMsgType") + call_id: Annotated[str, Field(description="Identifier for the collab tool call.")] + receiver_agent_nickname: Annotated[ + str | None, + Field(description="Optional nickname assigned to the receiver agent."), + ] = None + receiver_agent_role: Annotated[ + str | None, Field(description="Optional role assigned to the receiver agent.") + ] = None + receiver_thread_id: Annotated[ + ThreadId, Field(description="Thread ID of the receiver.") + ] + sender_thread_id: Annotated[ThreadId, Field(description="Thread ID of the sender.")] + status: Annotated[ + AgentStatus, + Field( + description="Last known status of the receiver agent reported to the sender agent after resume." + ), + ] + type: Annotated[ + Literal["collab_resume_end"], Field(title="CollabResumeEndEventMsgType") + ] class ExperimentalFeature(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - announcement: str | None = Field( - None, - description="Announcement copy shown to users when the feature is introduced. Null when this feature is not in beta.", - ) - default_enabled: bool = Field( - ..., - alias="defaultEnabled", - description="Whether this feature is enabled by default.", - ) - description: str | None = Field( - None, - description="Short summary describing what the feature does. Null when this feature is not in beta.", - ) - display_name: str | None = Field( - None, - alias="displayName", - description="User-facing display name shown in the experimental features UI. Null when this feature is not in beta.", - ) - enabled: bool = Field( - ..., - description="Whether this feature is currently enabled in the loaded config.", - ) - name: str = Field( - ..., description="Stable key used in config.toml and CLI flag toggles." - ) - stage: ExperimentalFeatureStage = Field( - ..., description="Lifecycle stage of this feature flag." - ) + announcement: Annotated[ + str | None, + Field( + description="Announcement copy shown to users when the feature is introduced. Null when this feature is not in beta." + ), + ] = None + default_enabled: Annotated[ + bool, + Field( + alias="defaultEnabled", + description="Whether this feature is enabled by default.", + ), + ] + description: Annotated[ + str | None, + Field( + description="Short summary describing what the feature does. Null when this feature is not in beta." + ), + ] = None + display_name: Annotated[ + str | None, + Field( + alias="displayName", + description="User-facing display name shown in the experimental features UI. Null when this feature is not in beta.", + ), + ] = None + enabled: Annotated[ + bool, + Field( + description="Whether this feature is currently enabled in the loaded config." + ), + ] + name: Annotated[ + str, Field(description="Stable key used in config.toml and CLI flag toggles.") + ] + stage: Annotated[ + ExperimentalFeatureStage, + Field(description="Lifecycle stage of this feature flag."), + ] class ExperimentalFeatureListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[ExperimentalFeature] - next_cursor: str | None = Field( - None, - alias="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.", - ) + data: list[ExperimentalFeature] + next_cursor: Annotated[ + str | None, + Field( + alias="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.", + ), + ] = None class ExternalAgentConfigMigrationItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - cwd: str | None = Field( - None, - description="Null or empty means home-scoped migration; non-empty means repo-scoped migration.", - ) + cwd: Annotated[ + str | None, + Field( + description="Null or empty means home-scoped migration; non-empty means repo-scoped migration." + ), + ] = None description: str - item_type: ExternalAgentConfigMigrationItemType = Field(..., alias="itemType") + item_type: Annotated[ExternalAgentConfigMigrationItemType, Field(alias="itemType")] class FileUpdateChange(BaseModel): @@ -6073,25 +5900,33 @@ class FileUpdateChange(BaseModel): path: str -class FunctionCallOutputContentItem2(BaseModel): +class InputImageFunctionCallOutputContentItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) detail: ImageDetail | None = None image_url: str - type: Type15 = Field(..., title="InputImageFunctionCallOutputContentItemType") + type: Annotated[ + Literal["input_image"], + Field(title="InputImageFunctionCallOutputContentItemType"), + ] class FunctionCallOutputContentItem( - RootModel[FunctionCallOutputContentItem1 | FunctionCallOutputContentItem2] + RootModel[ + InputTextFunctionCallOutputContentItem | InputImageFunctionCallOutputContentItem + ] ): model_config = ConfigDict( populate_by_name=True, ) - root: FunctionCallOutputContentItem1 | FunctionCallOutputContentItem2 = Field( - ..., - 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.", - ) + root: Annotated[ + InputTextFunctionCallOutputContentItem + | InputImageFunctionCallOutputContentItem, + Field( + 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." + ), + ] class GetAccountResponse(BaseModel): @@ -6099,7 +5934,7 @@ class GetAccountResponse(BaseModel): populate_by_name=True, ) account: Account | None = None - requires_openai_auth: bool = Field(..., alias="requiresOpenaiAuth") + requires_openai_auth: Annotated[bool, Field(alias="requiresOpenaiAuth")] class HookOutputEntry(BaseModel): @@ -6114,19 +5949,19 @@ class HookRunSummary(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - completed_at: int | None = Field(None, alias="completedAt") - display_order: int = Field(..., alias="displayOrder") - duration_ms: int | None = Field(None, alias="durationMs") - entries: List[HookOutputEntry] - event_name: HookEventName = Field(..., alias="eventName") - execution_mode: HookExecutionMode = Field(..., alias="executionMode") - handler_type: HookHandlerType = Field(..., alias="handlerType") + completed_at: Annotated[int | None, Field(alias="completedAt")] = None + display_order: Annotated[int, Field(alias="displayOrder")] + duration_ms: Annotated[int | None, Field(alias="durationMs")] = None + entries: list[HookOutputEntry] + event_name: Annotated[HookEventName, Field(alias="eventName")] + execution_mode: Annotated[HookExecutionMode, Field(alias="executionMode")] + handler_type: Annotated[HookHandlerType, Field(alias="handlerType")] id: str scope: HookScope - source_path: str = Field(..., alias="sourcePath") - started_at: int = Field(..., alias="startedAt") + source_path: Annotated[str, Field(alias="sourcePath")] + started_at: Annotated[int, Field(alias="startedAt")] status: HookRunStatus - status_message: str | None = Field(None, alias="statusMessage") + status_message: Annotated[str | None, Field(alias="statusMessage")] = None class HookStartedNotification(BaseModel): @@ -6134,56 +5969,64 @@ class HookStartedNotification(BaseModel): populate_by_name=True, ) run: HookRunSummary - thread_id: str = Field(..., alias="threadId") - turn_id: str | None = Field(None, alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str | None, Field(alias="turnId")] = None class McpServerStatus(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - auth_status: McpAuthStatus = Field(..., alias="authStatus") + auth_status: Annotated[McpAuthStatus, Field(alias="authStatus")] name: str - resource_templates: List[ResourceTemplate] = Field(..., alias="resourceTemplates") - resources: List[Resource] - tools: Dict[str, Tool] + resource_templates: Annotated[ + list[ResourceTemplate], Field(alias="resourceTemplates") + ] + resources: list[Resource] + tools: dict[str, Tool] class Model(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - availability_nux: ModelAvailabilityNux | None = Field(None, alias="availabilityNux") - default_reasoning_effort: ReasoningEffort = Field( - ..., alias="defaultReasoningEffort" - ) + availability_nux: Annotated[ + ModelAvailabilityNux | None, Field(alias="availabilityNux") + ] = None + default_reasoning_effort: Annotated[ + ReasoningEffort, Field(alias="defaultReasoningEffort") + ] description: str - display_name: str = Field(..., alias="displayName") + display_name: Annotated[str, Field(alias="displayName")] hidden: bool id: str - input_modalities: List[InputModality] | None = Field( - ["text", "image"], alias="inputModalities" - ) - is_default: bool = Field(..., alias="isDefault") + input_modalities: Annotated[ + list[InputModality] | None, Field(alias="inputModalities") + ] = ["text", "image"] + is_default: Annotated[bool, Field(alias="isDefault")] model: str - supported_reasoning_efforts: List[ReasoningEffortOption] = Field( - ..., alias="supportedReasoningEfforts" + supported_reasoning_efforts: Annotated[ + list[ReasoningEffortOption], Field(alias="supportedReasoningEfforts") + ] + supports_personality: Annotated[bool | None, Field(alias="supportsPersonality")] = ( + False ) - supports_personality: bool | None = Field(False, alias="supportsPersonality") upgrade: str | None = None - upgrade_info: ModelUpgradeInfo | None = Field(None, alias="upgradeInfo") + upgrade_info: Annotated[ModelUpgradeInfo | None, Field(alias="upgradeInfo")] = None class ModelListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[Model] - next_cursor: str | None = Field( - None, - alias="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.", - ) + data: list[Model] + next_cursor: Annotated[ + str | None, + Field( + alias="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.", + ), + ] = None class NetworkApprovalContext(BaseModel): @@ -6206,9 +6049,9 @@ class OverriddenMetadata(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - effective_value: Any = Field(..., alias="effectiveValue") + effective_value: Annotated[Any, Field(alias="effectiveValue")] message: str - overriding_layer: ConfigLayerMetadata = Field(..., alias="overridingLayer") + overriding_layer: Annotated[ConfigLayerMetadata, Field(alias="overridingLayer")] class PlanItemArg(BaseModel): @@ -6226,7 +6069,7 @@ class PluginMarketplaceEntry(BaseModel): ) name: str path: AbsolutePathBuf - plugins: List[PluginSummary] + plugins: list[PluginSummary] class RateLimitSnapshot(BaseModel): @@ -6234,38 +6077,38 @@ class RateLimitSnapshot(BaseModel): populate_by_name=True, ) credits: CreditsSnapshot | None = None - limit_id: str | None = Field(None, alias="limitId") - limit_name: str | None = Field(None, alias="limitName") - plan_type: PlanType | None = Field(None, alias="planType") + limit_id: Annotated[str | None, Field(alias="limitId")] = None + limit_name: Annotated[str | None, Field(alias="limitName")] = None + plan_type: Annotated[PlanType | None, Field(alias="planType")] = None primary: RateLimitWindow | None = None secondary: RateLimitWindow | None = None -class RealtimeEvent2(BaseModel): +class InputTranscriptDeltaRealtimeEvent(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - input_transcript_delta: RealtimeTranscriptDelta = Field( - ..., alias="InputTranscriptDelta" - ) + input_transcript_delta: Annotated[ + RealtimeTranscriptDelta, Field(alias="InputTranscriptDelta") + ] -class RealtimeEvent3(BaseModel): +class OutputTranscriptDeltaRealtimeEvent(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - output_transcript_delta: RealtimeTranscriptDelta = Field( - ..., alias="OutputTranscriptDelta" - ) + output_transcript_delta: Annotated[ + RealtimeTranscriptDelta, Field(alias="OutputTranscriptDelta") + ] class RealtimeHandoffRequested(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - active_transcript: List[RealtimeTranscriptEntry] + active_transcript: list[RealtimeTranscriptEntry] handoff_id: str input_transcript: str item_id: str @@ -6277,20 +6120,22 @@ class RequestUserInputQuestion(BaseModel): ) header: str id: str - is_other: bool | None = Field(False, alias="isOther") - is_secret: bool | None = Field(False, alias="isSecret") - options: List[RequestUserInputQuestionOption] | None = None + is_other: Annotated[bool | None, Field(alias="isOther")] = False + is_secret: Annotated[bool | None, Field(alias="isSecret")] = False + options: list[RequestUserInputQuestionOption] | None = None question: str -class ResponseItem8(BaseModel): +class WebSearchCallResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) action: ResponsesApiWebSearchAction | None = None id: str | None = None status: str | None = None - type: Type131 = Field(..., title="WebSearchCallResponseItemType") + type: Annotated[ + Literal["web_search_call"], Field(title="WebSearchCallResponseItemType") + ] class ReviewCodeLocation(BaseModel): @@ -6308,7 +6153,7 @@ class NetworkPolicyAmendment1(BaseModel): network_policy_amendment: NetworkPolicyAmendment -class ReviewDecision4(BaseModel): +class NetworkPolicyAmendmentReviewDecision(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, @@ -6318,25 +6163,26 @@ class ReviewDecision4(BaseModel): class ReviewDecision( RootModel[ - ReviewDecision1 - | ReviewDecision2 - | ReviewDecision3 - | ReviewDecision4 - | ReviewDecision5 - | ReviewDecision6 + Literal["approved"] + | ApprovedExecpolicyAmendmentReviewDecision + | Literal["approved_for_session"] + | NetworkPolicyAmendmentReviewDecision + | Literal["denied"] + | Literal["abort"] ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - ReviewDecision1 - | ReviewDecision2 - | ReviewDecision3 - | ReviewDecision4 - | ReviewDecision5 - | ReviewDecision6 - ) = Field(..., description="User's decision in response to an ExecApprovalRequest.") + root: Annotated[ + Literal["approved"] + | ApprovedExecpolicyAmendmentReviewDecision + | Literal["approved_for_session"] + | NetworkPolicyAmendmentReviewDecision + | Literal["denied"] + | Literal["abort"], + Field(description="User's decision in response to an ExecApprovalRequest."), + ] class ReviewFinding(BaseModel): @@ -6354,7 +6200,7 @@ class ReviewOutputEvent(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - findings: List[ReviewFinding] + findings: list[ReviewFinding] overall_confidence_score: float overall_correctness: str overall_explanation: str @@ -6364,177 +6210,222 @@ class ReviewStartParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - delivery: ReviewDelivery | None = Field( - None, - description="Where to run the review: inline (default) on the current thread or detached on a new thread (returned in `reviewThreadId`).", - ) + delivery: Annotated[ + ReviewDelivery | None, + Field( + description="Where to run the review: inline (default) on the current thread or detached on a new thread (returned in `reviewThreadId`)." + ), + ] = None target: ReviewTarget - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] -class ServerNotification1(BaseModel): +class ErrorServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Type19 = Field(..., title="ErrorNotificationMethod") + method: Annotated[Literal["error"], Field(title="ErrorNotificationMethod")] params: ErrorNotification -class ServerNotification3(BaseModel): +class ThreadStatusChangedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method51 = Field(..., title="Thread/status/changedNotificationMethod") + method: Annotated[ + Literal["thread/status/changed"], + Field(title="Thread/status/changedNotificationMethod"), + ] params: ThreadStatusChangedNotification -class ServerNotification4(BaseModel): +class ThreadArchivedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method52 = Field(..., title="Thread/archivedNotificationMethod") + method: Annotated[ + Literal["thread/archived"], Field(title="Thread/archivedNotificationMethod") + ] params: ThreadArchivedNotification -class ServerNotification5(BaseModel): +class ThreadUnarchivedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method53 = Field(..., title="Thread/unarchivedNotificationMethod") + method: Annotated[ + Literal["thread/unarchived"], Field(title="Thread/unarchivedNotificationMethod") + ] params: ThreadUnarchivedNotification -class ServerNotification6(BaseModel): +class ThreadClosedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method54 = Field(..., title="Thread/closedNotificationMethod") + method: Annotated[ + Literal["thread/closed"], Field(title="Thread/closedNotificationMethod") + ] params: ThreadClosedNotification -class ServerNotification7(BaseModel): +class SkillsChangedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method55 = Field(..., title="Skills/changedNotificationMethod") + method: Annotated[ + Literal["skills/changed"], Field(title="Skills/changedNotificationMethod") + ] params: SkillsChangedNotification -class ServerNotification8(BaseModel): +class ThreadNameUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method56 = Field(..., title="Thread/name/updatedNotificationMethod") + method: Annotated[ + Literal["thread/name/updated"], + Field(title="Thread/name/updatedNotificationMethod"), + ] params: ThreadNameUpdatedNotification -class ServerNotification11(BaseModel): +class HookStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method59 = Field(..., title="Hook/startedNotificationMethod") + method: Annotated[ + Literal["hook/started"], Field(title="Hook/startedNotificationMethod") + ] params: HookStartedNotification -class ServerNotification14(BaseModel): +class TurnDiffUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method62 = Field(..., title="Turn/diff/updatedNotificationMethod") + method: Annotated[ + Literal["turn/diff/updated"], Field(title="Turn/diff/updatedNotificationMethod") + ] params: TurnDiffUpdatedNotification -class ServerNotification20(BaseModel): +class CommandExecOutputDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method68 = Field(..., title="Command/exec/outputDeltaNotificationMethod") + method: Annotated[ + Literal["command/exec/outputDelta"], + Field(title="Command/exec/outputDeltaNotificationMethod"), + ] params: CommandExecOutputDeltaNotification -class ServerNotification22(BaseModel): +class ItemCommandExecutionTerminalInteractionServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method70 = Field( - ..., title="Item/commandExecution/terminalInteractionNotificationMethod" - ) + method: Annotated[ + Literal["item/commandExecution/terminalInteraction"], + Field(title="Item/commandExecution/terminalInteractionNotificationMethod"), + ] params: TerminalInteractionNotification -class ServerNotification24(BaseModel): +class ServerRequestResolvedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method72 = Field(..., title="ServerRequest/resolvedNotificationMethod") + method: Annotated[ + Literal["serverRequest/resolved"], + Field(title="ServerRequest/resolvedNotificationMethod"), + ] params: ServerRequestResolvedNotification -class ServerNotification27(BaseModel): +class AccountUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method75 = Field(..., title="Account/updatedNotificationMethod") + method: Annotated[ + Literal["account/updated"], Field(title="Account/updatedNotificationMethod") + ] params: AccountUpdatedNotification -class ServerNotification36(BaseModel): +class ConfigWarningServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method84 = Field(..., title="ConfigWarningNotificationMethod") + method: Annotated[ + Literal["configWarning"], Field(title="ConfigWarningNotificationMethod") + ] params: ConfigWarningNotification -class ServerNotification39(BaseModel): +class ThreadRealtimeStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method87 = Field(..., title="Thread/realtime/startedNotificationMethod") + method: Annotated[ + Literal["thread/realtime/started"], + Field(title="Thread/realtime/startedNotificationMethod"), + ] params: ThreadRealtimeStartedNotification -class ServerNotification40(BaseModel): +class ThreadRealtimeItemAddedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method88 = Field(..., title="Thread/realtime/itemAddedNotificationMethod") + method: Annotated[ + Literal["thread/realtime/itemAdded"], + Field(title="Thread/realtime/itemAddedNotificationMethod"), + ] params: ThreadRealtimeItemAddedNotification -class ServerNotification41(BaseModel): +class ThreadRealtimeOutputAudioDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method89 = Field( - ..., title="Thread/realtime/outputAudio/deltaNotificationMethod" - ) + method: Annotated[ + Literal["thread/realtime/outputAudio/delta"], + Field(title="Thread/realtime/outputAudio/deltaNotificationMethod"), + ] params: ThreadRealtimeOutputAudioDeltaNotification -class ServerNotification42(BaseModel): +class ThreadRealtimeErrorServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method90 = Field(..., title="Thread/realtime/errorNotificationMethod") + method: Annotated[ + Literal["thread/realtime/error"], + Field(title="Thread/realtime/errorNotificationMethod"), + ] params: ThreadRealtimeErrorNotification -class ServerNotification43(BaseModel): +class ThreadRealtimeClosedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method91 = Field(..., title="Thread/realtime/closedNotificationMethod") + method: Annotated[ + Literal["thread/realtime/closed"], + Field(title="Thread/realtime/closedNotificationMethod"), + ] params: ThreadRealtimeClosedNotification -class ServerNotification44(BaseModel): +class WindowsWorldWritableWarningServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method92 = Field( - ..., title="Windows/worldWritableWarningNotificationMethod" - ) + method: Annotated[ + Literal["windows/worldWritableWarning"], + Field(title="Windows/worldWritableWarningNotificationMethod"), + ] params: WindowsWorldWritableWarningNotification @@ -6542,7 +6433,7 @@ class SkillDependencies(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - tools: List[SkillToolDependency] + tools: list[SkillToolDependency] class SkillMetadata(BaseModel): @@ -6556,11 +6447,13 @@ class SkillMetadata(BaseModel): name: str path: str scope: SkillScope - short_description: str | None = Field( - None, - alias="shortDescription", - description="Legacy short_description from SKILL.md. Prefer SKILL.json interface.short_description.", - ) + short_description: Annotated[ + str | None, + Field( + alias="shortDescription", + description="Legacy short_description from SKILL.md. Prefer SKILL.json interface.short_description.", + ), + ] = None class SkillsListEntry(BaseModel): @@ -6568,15 +6461,15 @@ class SkillsListEntry(BaseModel): populate_by_name=True, ) cwd: str - errors: List[SkillErrorInfo] - skills: List[SkillMetadata] + errors: list[SkillErrorInfo] + skills: list[SkillMetadata] class SkillsListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[SkillsListEntry] + data: list[SkillsListEntry] class ThreadSpawn(BaseModel): @@ -6589,7 +6482,7 @@ class ThreadSpawn(BaseModel): parent_thread_id: ThreadId -class SubAgentSource2(BaseModel): +class ThreadSpawnSubAgentSource(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, @@ -6597,113 +6490,128 @@ class SubAgentSource2(BaseModel): thread_spawn: ThreadSpawn -class SubAgentSource(RootModel[SubAgentSource1 | SubAgentSource2 | SubAgentSource3]): +class SubAgentSource( + RootModel[SubAgentSourceValue | ThreadSpawnSubAgentSource | OtherSubAgentSource] +): model_config = ConfigDict( populate_by_name=True, ) - root: SubAgentSource1 | SubAgentSource2 | SubAgentSource3 + root: SubAgentSourceValue | ThreadSpawnSubAgentSource | OtherSubAgentSource -class ThreadItem1(BaseModel): +class UserMessageThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - content: List[UserInput] + content: list[UserInput] id: str - type: Type148 = Field(..., title="UserMessageThreadItemType") + type: Annotated[Literal["userMessage"], Field(title="UserMessageThreadItemType")] -class ThreadItem6(BaseModel): +class FileChangeThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - changes: List[FileUpdateChange] + changes: list[FileUpdateChange] id: str - status: CommandExecutionStatus - type: Type153 = Field(..., title="FileChangeThreadItemType") + status: PatchApplyStatus + type: Annotated[Literal["fileChange"], Field(title="FileChangeThreadItemType")] -class ThreadItem9(BaseModel): +class CollabAgentToolCallThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - agents_states: Dict[str, CollabAgentState] = Field( - ..., - alias="agentsStates", - description="Last known status of the target agents, when available.", - ) - id: str = Field(..., description="Unique identifier for this collab tool call.") - prompt: str | None = Field( - None, - description="Prompt text sent as part of the collab tool call, when available.", - ) - receiver_thread_ids: List[str] = Field( - ..., - alias="receiverThreadIds", - description="Thread ID of the receiving agent, when applicable. In case of spawn operation, this corresponds to the newly spawned agent.", - ) - sender_thread_id: str = Field( - ..., - alias="senderThreadId", - description="Thread ID of the agent issuing the collab request.", - ) - status: CollabAgentToolCallStatus = Field( - ..., description="Current status of the collab tool call." - ) - tool: CollabAgentTool = Field( - ..., description="Name of the collab tool that was invoked." - ) - type: Type156 = Field(..., title="CollabAgentToolCallThreadItemType") + agents_states: Annotated[ + dict[str, CollabAgentState], + Field( + alias="agentsStates", + description="Last known status of the target agents, when available.", + ), + ] + id: Annotated[ + str, Field(description="Unique identifier for this collab tool call.") + ] + prompt: Annotated[ + str | None, + Field( + description="Prompt text sent as part of the collab tool call, when available." + ), + ] = None + receiver_thread_ids: Annotated[ + list[str], + Field( + alias="receiverThreadIds", + description="Thread ID of the receiving agent, when applicable. In case of spawn operation, this corresponds to the newly spawned agent.", + ), + ] + sender_thread_id: Annotated[ + str, + Field( + alias="senderThreadId", + description="Thread ID of the agent issuing the collab request.", + ), + ] + status: Annotated[ + CollabAgentToolCallStatus, + Field(description="Current status of the collab tool call."), + ] + tool: Annotated[ + CollabAgentTool, Field(description="Name of the collab tool that was invoked.") + ] + type: Annotated[ + Literal["collabAgentToolCall"], Field(title="CollabAgentToolCallThreadItemType") + ] -class ThreadItem10(BaseModel): +class WebSearchThreadItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) action: WebSearchAction | None = None id: str query: str - type: Type157 = Field(..., title="WebSearchThreadItemType") + type: Annotated[Literal["webSearch"], Field(title="WebSearchThreadItemType")] class ThreadItem( RootModel[ - ThreadItem1 - | ThreadItem2 - | ThreadItem3 - | ThreadItem4 - | ThreadItem5 - | ThreadItem6 - | ThreadItem7 - | ThreadItem8 - | ThreadItem9 - | ThreadItem10 - | ThreadItem11 - | ThreadItem12 - | ThreadItem13 - | ThreadItem14 - | ThreadItem15 + UserMessageThreadItem + | AgentMessageThreadItem + | PlanThreadItem + | ReasoningThreadItem + | CommandExecutionThreadItem + | FileChangeThreadItem + | McpToolCallThreadItem + | DynamicToolCallThreadItem + | CollabAgentToolCallThreadItem + | WebSearchThreadItem + | ImageViewThreadItem + | ImageGenerationThreadItem + | EnteredReviewModeThreadItem + | ExitedReviewModeThreadItem + | ContextCompactionThreadItem ] ): model_config = ConfigDict( populate_by_name=True, ) root: ( - ThreadItem1 - | ThreadItem2 - | ThreadItem3 - | ThreadItem4 - | ThreadItem5 - | ThreadItem6 - | ThreadItem7 - | ThreadItem8 - | ThreadItem9 - | ThreadItem10 - | ThreadItem11 - | ThreadItem12 - | ThreadItem13 - | ThreadItem14 - | ThreadItem15 + UserMessageThreadItem + | AgentMessageThreadItem + | PlanThreadItem + | ReasoningThreadItem + | CommandExecutionThreadItem + | FileChangeThreadItem + | McpToolCallThreadItem + | DynamicToolCallThreadItem + | CollabAgentToolCallThreadItem + | WebSearchThreadItem + | ImageViewThreadItem + | ImageGenerationThreadItem + | EnteredReviewModeThreadItem + | ExitedReviewModeThreadItem + | ContextCompactionThreadItem ) @@ -6711,39 +6619,56 @@ class ThreadListParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - archived: bool | None = Field( - None, - description="Optional archived filter; when set to true, only archived threads are returned. If false or null, only non-archived threads are returned.", - ) - cursor: str | None = Field( - None, description="Opaque pagination cursor returned by a previous call." - ) - cwd: str | None = Field( - None, - description="Optional cwd filter; when set, only threads whose session cwd exactly matches this path are returned.", - ) - limit: conint(ge=0) | None = Field( - None, - description="Optional page size; defaults to a reasonable server-side value.", - ) - model_providers: List[str] | None = Field( - None, - alias="modelProviders", - description="Optional provider filter; when set, only sessions recorded under these providers are returned. When present but empty, includes all providers.", - ) - search_term: str | None = Field( - None, - alias="searchTerm", - description="Optional substring filter for the extracted thread title.", - ) - sort_key: ThreadSortKey | None = Field( - None, alias="sortKey", description="Optional sort key; defaults to created_at." - ) - source_kinds: List[ThreadSourceKind] | None = Field( - None, - alias="sourceKinds", - description="Optional source filter; when set, only sessions from these source kinds are returned. When omitted or empty, defaults to interactive sources.", - ) + archived: Annotated[ + bool | None, + Field( + description="Optional archived filter; when set to true, only archived threads are returned. If false or null, only non-archived threads are returned." + ), + ] = None + cursor: Annotated[ + str | None, + Field(description="Opaque pagination cursor returned by a previous call."), + ] = None + cwd: Annotated[ + str | None, + Field( + description="Optional cwd filter; when set, only threads whose session cwd exactly matches this path are returned." + ), + ] = None + limit: Annotated[ + int | None, + Field( + description="Optional page size; defaults to a reasonable server-side value.", + ge=0, + ), + ] = None + model_providers: Annotated[ + list[str] | None, + Field( + alias="modelProviders", + description="Optional provider filter; when set, only sessions recorded under these providers are returned. When present but empty, includes all providers.", + ), + ] = None + search_term: Annotated[ + str | None, + Field( + alias="searchTerm", + description="Optional substring filter for the extracted thread title.", + ), + ] = None + sort_key: Annotated[ + ThreadSortKey | None, + Field( + alias="sortKey", description="Optional sort key; defaults to created_at." + ), + ] = None + source_kinds: Annotated[ + list[ThreadSourceKind] | None, + Field( + alias="sourceKinds", + description="Optional source filter; when set, only sessions from these source kinds are returned. When omitted or empty, defaults to interactive sources.", + ), + ] = None class ThreadTokenUsage(BaseModel): @@ -6751,7 +6676,9 @@ class ThreadTokenUsage(BaseModel): populate_by_name=True, ) last: TokenUsageBreakdown - model_context_window: int | None = Field(None, alias="modelContextWindow") + model_context_window: Annotated[int | None, Field(alias="modelContextWindow")] = ( + None + ) total: TokenUsageBreakdown @@ -6759,9 +6686,9 @@ class ThreadTokenUsageUpdatedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - thread_id: str = Field(..., alias="threadId") - token_usage: ThreadTokenUsage = Field(..., alias="tokenUsage") - turn_id: str = Field(..., alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + token_usage: Annotated[ThreadTokenUsage, Field(alias="tokenUsage")] + turn_id: Annotated[str, Field(alias="turnId")] class ThreadUnsubscribeResponse(BaseModel): @@ -6783,14 +6710,17 @@ class Turn(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - error: TurnError | None = Field( - None, description="Only populated when the Turn's status is failed." - ) + error: Annotated[ + TurnError | None, + Field(description="Only populated when the Turn's status is failed."), + ] = None id: str - items: List[ThreadItem] = Field( - ..., - description="Only populated on a `thread/resume` or `thread/fork` response. For all other responses and notifications returning a Turn, the items field will be an empty list.", - ) + items: Annotated[ + list[ThreadItem], + Field( + description="Only populated on a `thread/resume` or `thread/fork` response. For all other responses and notifications returning a Turn, the items field will be an empty list." + ), + ] status: TurnStatus @@ -6798,41 +6728,41 @@ class TurnCompletedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - thread_id: str = Field(..., alias="threadId") + thread_id: Annotated[str, Field(alias="threadId")] turn: Turn -class TurnItem1(BaseModel): +class UserMessageTurnItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - content: List[UserInput] + content: list[UserInput] id: str - type: Type167 = Field(..., title="UserMessageTurnItemType") + type: Annotated[Literal["UserMessage"], Field(title="UserMessageTurnItemType")] class TurnItem( RootModel[ - TurnItem1 - | TurnItem2 - | TurnItem3 - | TurnItem4 - | TurnItem5 - | TurnItem6 - | TurnItem7 + UserMessageTurnItem + | AgentMessageTurnItem + | PlanTurnItem + | ReasoningTurnItem + | WebSearchTurnItem + | ImageGenerationTurnItem + | ContextCompactionTurnItem ] ): model_config = ConfigDict( populate_by_name=True, ) root: ( - TurnItem1 - | TurnItem2 - | TurnItem3 - | TurnItem4 - | TurnItem5 - | TurnItem6 - | TurnItem7 + UserMessageTurnItem + | AgentMessageTurnItem + | PlanTurnItem + | ReasoningTurnItem + | WebSearchTurnItem + | ImageGenerationTurnItem + | ContextCompactionTurnItem ) @@ -6849,55 +6779,73 @@ class TurnPlanUpdatedNotification(BaseModel): populate_by_name=True, ) explanation: str | None = None - plan: List[TurnPlanStep] - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + plan: list[TurnPlanStep] + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class TurnStartParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: AskForApproval | None = Field( - None, - alias="approvalPolicy", - description="Override the approval policy for this turn and subsequent turns.", - ) - cwd: str | None = Field( - None, - description="Override the working directory for this turn and subsequent turns.", - ) - effort: ReasoningEffort | None = Field( - None, - description="Override the reasoning effort for this turn and subsequent turns.", - ) - input: List[UserInput] - model: str | None = Field( - None, description="Override the model for this turn and subsequent turns." - ) - output_schema: Any | None = Field( - None, - alias="outputSchema", - description="Optional JSON Schema used to constrain the final assistant message for this turn.", - ) - personality: Personality | None = Field( - None, description="Override the personality for this turn and subsequent turns." - ) - sandbox_policy: SandboxPolicy | None = Field( - None, - alias="sandboxPolicy", - description="Override the sandbox policy for this turn and subsequent turns.", - ) - service_tier: ServiceTier | None = Field( - None, - alias="serviceTier", - description="Override the service tier for this turn and subsequent turns.", - ) - summary: ReasoningSummary | None = Field( - None, - description="Override the reasoning summary for this turn and subsequent turns.", - ) - thread_id: str = Field(..., alias="threadId") + approval_policy: Annotated[ + AskForApproval | None, + Field( + alias="approvalPolicy", + description="Override the approval policy for this turn and subsequent turns.", + ), + ] = None + cwd: Annotated[ + str | None, + Field( + description="Override the working directory for this turn and subsequent turns." + ), + ] = None + effort: Annotated[ + ReasoningEffort | None, + Field( + description="Override the reasoning effort for this turn and subsequent turns." + ), + ] = None + input: list[UserInput] + model: Annotated[ + str | None, + Field(description="Override the model for this turn and subsequent turns."), + ] = None + output_schema: Annotated[ + Any | None, + Field( + alias="outputSchema", + description="Optional JSON Schema used to constrain the final assistant message for this turn.", + ), + ] = None + personality: Annotated[ + Personality | None, + Field( + description="Override the personality for this turn and subsequent turns." + ), + ] = None + sandbox_policy: Annotated[ + SandboxPolicy | None, + Field( + alias="sandboxPolicy", + description="Override the sandbox policy for this turn and subsequent turns.", + ), + ] = None + service_tier: Annotated[ + ServiceTier | None, + Field( + alias="serviceTier", + description="Override the service tier for this turn and subsequent turns.", + ), + ] = None + summary: Annotated[ + ReasoningSummary | None, + Field( + description="Override the reasoning summary for this turn and subsequent turns." + ), + ] = None + thread_id: Annotated[str, Field(alias="threadId")] class TurnStartResponse(BaseModel): @@ -6907,20 +6855,27 @@ class TurnStartResponse(BaseModel): turn: Turn -TurnStartedNotification = TurnCompletedNotification +class TurnStartedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread_id: Annotated[str, Field(alias="threadId")] + turn: Turn class TurnSteerParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - expected_turn_id: str = Field( - ..., - alias="expectedTurnId", - description="Required active turn id precondition. The request fails when it does not match the currently active turn.", - ) - input: List[UserInput] - thread_id: str = Field(..., alias="threadId") + expected_turn_id: Annotated[ + str, + Field( + alias="expectedTurnId", + description="Required active turn id precondition. The request fails when it does not match the currently active turn.", + ), + ] + input: list[UserInput] + thread_id: Annotated[str, Field(alias="threadId")] class WindowsSandboxSetupCompletedNotification(BaseModel): @@ -6936,111 +6891,123 @@ class AccountRateLimitsUpdatedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - rate_limits: RateLimitSnapshot = Field(..., alias="rateLimits") + rate_limits: Annotated[RateLimitSnapshot, Field(alias="rateLimits")] class AppInfo(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - app_metadata: AppMetadata | None = Field(None, alias="appMetadata") + app_metadata: Annotated[AppMetadata | None, Field(alias="appMetadata")] = None branding: AppBranding | None = None description: str | None = None - distribution_channel: str | None = Field(None, alias="distributionChannel") - id: str - install_url: str | None = Field(None, alias="installUrl") - is_accessible: bool | None = Field(False, alias="isAccessible") - is_enabled: bool | None = Field( - True, - alias="isEnabled", - description="Whether this app is enabled in config.toml. Example: ```toml [apps.bad_app] enabled = false ```", + distribution_channel: Annotated[str | None, Field(alias="distributionChannel")] = ( + None ) - labels: Dict[str, Any] | None = None - logo_url: str | None = Field(None, alias="logoUrl") - logo_url_dark: str | None = Field(None, alias="logoUrlDark") + id: str + install_url: Annotated[str | None, Field(alias="installUrl")] = None + is_accessible: Annotated[bool | None, Field(alias="isAccessible")] = False + is_enabled: Annotated[ + bool | None, + Field( + alias="isEnabled", + description="Whether this app is enabled in config.toml. Example: ```toml [apps.bad_app] enabled = false ```", + ), + ] = True + labels: dict[str, Any] | None = None + logo_url: Annotated[str | None, Field(alias="logoUrl")] = None + logo_url_dark: Annotated[str | None, Field(alias="logoUrlDark")] = None name: str - plugin_display_names: List[str] | None = Field([], alias="pluginDisplayNames") + plugin_display_names: Annotated[ + list[str] | None, Field(alias="pluginDisplayNames") + ] = [] class AppListUpdatedNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[AppInfo] + data: list[AppInfo] class AppsListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[AppInfo] - next_cursor: str | None = Field( - None, - alias="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.", - ) + data: list[AppInfo] + next_cursor: Annotated[ + str | None, + Field( + alias="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.", + ), + ] = None -class ClientRequest12(BaseModel): +class ThreadListRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method11 = Field(..., title="Thread/listRequestMethod") + method: Annotated[Literal["thread/list"], Field(title="Thread/listRequestMethod")] params: ThreadListParams -class ClientRequest23(BaseModel): +class TurnStartRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method22 = Field(..., title="Turn/startRequestMethod") + method: Annotated[Literal["turn/start"], Field(title="Turn/startRequestMethod")] params: TurnStartParams -class ClientRequest24(BaseModel): +class TurnSteerRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method23 = Field(..., title="Turn/steerRequestMethod") + method: Annotated[Literal["turn/steer"], Field(title="Turn/steerRequestMethod")] params: TurnSteerParams -class ClientRequest26(BaseModel): +class ReviewStartRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method25 = Field(..., title="Review/startRequestMethod") + method: Annotated[Literal["review/start"], Field(title="Review/startRequestMethod")] params: ReviewStartParams -class ClientRequest38(BaseModel): +class CommandExecRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method37 = Field(..., title="Command/execRequestMethod") + method: Annotated[Literal["command/exec"], Field(title="Command/execRequestMethod")] params: CommandExecParams -class ClientRequest41(BaseModel): +class CommandExecResizeRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method40 = Field(..., title="Command/exec/resizeRequestMethod") + method: Annotated[ + Literal["command/exec/resize"], Field(title="Command/exec/resizeRequestMethod") + ] params: CommandExecResizeParams -class ClientRequest45(BaseModel): +class ConfigValueWriteRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method44 = Field(..., title="Config/value/writeRequestMethod") + method: Annotated[ + Literal["config/value/write"], Field(title="Config/value/writeRequestMethod") + ] params: ConfigValueWriteParams @@ -7048,197 +7015,235 @@ class ConfigBatchWriteParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - edits: List[ConfigEdit] - expected_version: str | None = Field(None, alias="expectedVersion") - file_path: str | None = Field( - None, - alias="filePath", - description="Path to the config file to write; defaults to the user's `config.toml` when omitted.", - ) - reload_user_config: bool | None = Field( - None, - alias="reloadUserConfig", - description="When true, hot-reload the updated user config into all loaded threads after writing.", - ) + edits: list[ConfigEdit] + expected_version: Annotated[str | None, Field(alias="expectedVersion")] = None + file_path: Annotated[ + str | None, + Field( + alias="filePath", + description="Path to the config file to write; defaults to the user's `config.toml` when omitted.", + ), + ] = None + reload_user_config: Annotated[ + bool | None, + Field( + alias="reloadUserConfig", + description="When true, hot-reload the updated user config into all loaded threads after writing.", + ), + ] = None class ConfigWriteResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - file_path: AbsolutePathBuf = Field( - ..., - alias="filePath", - description="Canonical path to the config file that was written.", - ) - overridden_metadata: OverriddenMetadata | None = Field( - None, alias="overriddenMetadata" - ) + file_path: Annotated[ + AbsolutePathBuf, + Field( + alias="filePath", + description="Canonical path to the config file that was written.", + ), + ] + overridden_metadata: Annotated[ + OverriddenMetadata | None, Field(alias="overriddenMetadata") + ] = None status: WriteStatus version: str -class EventMsg11(BaseModel): +class TokenCountEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) info: TokenUsageInfo | None = None rate_limits: RateLimitSnapshot | None = None - type: Type29 = Field(..., title="TokenCountEventMsgType") + type: Annotated[Literal["token_count"], Field(title="TokenCountEventMsgType")] -class EventMsg35(BaseModel): +class ExecApprovalRequestEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - additional_permissions: PermissionProfile | None = Field( - None, - description="Optional additional filesystem permissions requested for this command.", - ) - approval_id: str | None = Field( - None, - description="Identifier for this specific approval callback.\n\nWhen absent, the approval is for the command item itself (`call_id`). This is present for subcommand approvals (via execve intercept).", - ) - available_decisions: List[ReviewDecision] | None = Field( - None, - description="Ordered list of decisions the client may present for this prompt.\n\nWhen absent, clients should derive the legacy default set from the other fields on this request.", - ) - call_id: str = Field( - ..., description="Identifier for the associated command execution item." - ) - command: List[str] = Field(..., description="The command to be executed.") - cwd: str = Field(..., description="The command's working directory.") - network_approval_context: NetworkApprovalContext | None = Field( - None, - description="Optional network context for a blocked request that can be approved.", - ) - parsed_cmd: List[ParsedCommand] - proposed_execpolicy_amendment: List[str] | None = Field( - None, - description="Proposed execpolicy amendment that can be applied to allow future runs.", - ) - proposed_network_policy_amendments: List[NetworkPolicyAmendment] | None = Field( - None, - description="Proposed network policy amendments (for example allow/deny this host in future).", - ) - reason: str | None = Field( - None, - description="Optional human-readable reason for the approval (e.g. retry without sandbox).", - ) - skill_metadata: ExecApprovalRequestSkillMetadata | None = Field( - None, - description="Optional skill metadata when the approval was triggered by a skill script.", - ) - turn_id: str | None = Field( - "", - description="Turn ID that this command belongs to. Uses `#[serde(default)]` for backwards compatibility.", - ) - type: Type53 = Field(..., title="ExecApprovalRequestEventMsgType") + additional_permissions: Annotated[ + PermissionProfile | None, + Field( + description="Optional additional filesystem permissions requested for this command." + ), + ] = None + approval_id: Annotated[ + str | None, + Field( + description="Identifier for this specific approval callback.\n\nWhen absent, the approval is for the command item itself (`call_id`). This is present for subcommand approvals (via execve intercept)." + ), + ] = None + available_decisions: Annotated[ + list[ReviewDecision] | None, + Field( + description="Ordered list of decisions the client may present for this prompt.\n\nWhen absent, clients should derive the legacy default set from the other fields on this request." + ), + ] = None + call_id: Annotated[ + str, Field(description="Identifier for the associated command execution item.") + ] + command: Annotated[list[str], Field(description="The command to be executed.")] + cwd: Annotated[str, Field(description="The command's working directory.")] + network_approval_context: Annotated[ + NetworkApprovalContext | None, + Field( + description="Optional network context for a blocked request that can be approved." + ), + ] = None + parsed_cmd: list[ParsedCommand] + proposed_execpolicy_amendment: Annotated[ + list[str] | None, + Field( + description="Proposed execpolicy amendment that can be applied to allow future runs." + ), + ] = None + proposed_network_policy_amendments: Annotated[ + list[NetworkPolicyAmendment] | None, + Field( + description="Proposed network policy amendments (for example allow/deny this host in future)." + ), + ] = None + reason: Annotated[ + str | None, + Field( + description="Optional human-readable reason for the approval (e.g. retry without sandbox)." + ), + ] = None + skill_metadata: Annotated[ + ExecApprovalRequestSkillMetadata | None, + Field( + description="Optional skill metadata when the approval was triggered by a skill script." + ), + ] = None + turn_id: Annotated[ + str | None, + Field( + description="Turn ID that this command belongs to. Uses `#[serde(default)]` for backwards compatibility." + ), + ] = "" + type: Annotated[ + Literal["exec_approval_request"], Field(title="ExecApprovalRequestEventMsgType") + ] -class EventMsg37(BaseModel): +class RequestUserInputEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - call_id: str = Field( - ..., - description="Responses API call id for the associated tool call, if available.", - ) - questions: List[RequestUserInputQuestion] - turn_id: str | None = Field( - "", - description="Turn ID that this request belongs to. Uses `#[serde(default)]` for backwards compatibility.", - ) - type: Type55 = Field(..., title="RequestUserInputEventMsgType") + call_id: Annotated[ + str, + Field( + description="Responses API call id for the associated tool call, if available." + ), + ] + questions: list[RequestUserInputQuestion] + turn_id: Annotated[ + str | None, + Field( + description="Turn ID that this request belongs to. Uses `#[serde(default)]` for backwards compatibility." + ), + ] = "" + type: Annotated[ + Literal["request_user_input"], Field(title="RequestUserInputEventMsgType") + ] -class EventMsg53(BaseModel): +class ListSkillsResponseEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - skills: List[SkillsListEntry] - type: Type71 = Field(..., title="ListSkillsResponseEventMsgType") + skills: list[SkillsListEntry] + type: Annotated[ + Literal["list_skills_response"], Field(title="ListSkillsResponseEventMsgType") + ] -class EventMsg57(BaseModel): +class PlanUpdateEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - explanation: str | None = Field( - None, - description="Arguments for the `update_plan` todo/checklist tool (not plan mode).", - ) - plan: List[PlanItemArg] - type: Type75 = Field(..., title="PlanUpdateEventMsgType") + explanation: Annotated[ + str | None, + Field( + description="Arguments for the `update_plan` todo/checklist tool (not plan mode)." + ), + ] = None + plan: list[PlanItemArg] + type: Annotated[Literal["plan_update"], Field(title="PlanUpdateEventMsgType")] -class EventMsg61(BaseModel): +class ExitedReviewModeEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) review_output: ReviewOutputEvent | None = None - type: Type79 = Field(..., title="ExitedReviewModeEventMsgType") + type: Annotated[ + Literal["exited_review_mode"], Field(title="ExitedReviewModeEventMsgType") + ] -class EventMsg63(BaseModel): +class ItemStartedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) item: TurnItem thread_id: ThreadId turn_id: str - type: Type81 = Field(..., title="ItemStartedEventMsgType") + type: Annotated[Literal["item_started"], Field(title="ItemStartedEventMsgType")] -class EventMsg64(BaseModel): +class ItemCompletedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) item: TurnItem thread_id: ThreadId turn_id: str - type: Type82 = Field(..., title="ItemCompletedEventMsgType") + type: Annotated[Literal["item_completed"], Field(title="ItemCompletedEventMsgType")] -class EventMsg65(BaseModel): +class HookStartedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) run: HookRunSummary turn_id: str | None = None - type: Type83 = Field(..., title="HookStartedEventMsgType") + type: Annotated[Literal["hook_started"], Field(title="HookStartedEventMsgType")] -class EventMsg66(BaseModel): +class HookCompletedEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) run: HookRunSummary turn_id: str | None = None - type: Type84 = Field(..., title="HookCompletedEventMsgType") + type: Annotated[Literal["hook_completed"], Field(title="HookCompletedEventMsgType")] class ExternalAgentConfigDetectResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - items: List[ExternalAgentConfigMigrationItem] + items: list[ExternalAgentConfigMigrationItem] class ExternalAgentConfigImportParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - migration_items: List[ExternalAgentConfigMigrationItem] = Field( - ..., alias="migrationItems" - ) + migration_items: Annotated[ + list[ExternalAgentConfigMigrationItem], Field(alias="migrationItems") + ] -class FunctionCallOutputBody(RootModel[str | List[FunctionCallOutputContentItem]]): +class FunctionCallOutputBody(RootModel[str | list[FunctionCallOutputContentItem]]): model_config = ConfigDict( populate_by_name=True, ) - root: str | List[FunctionCallOutputContentItem] + root: str | list[FunctionCallOutputContentItem] class FunctionCallOutputPayload(BaseModel): @@ -7253,19 +7258,29 @@ class GetAccountRateLimitsResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - rate_limits: RateLimitSnapshot = Field( - ..., - alias="rateLimits", - description="Backward-compatible single-bucket view; mirrors the historical payload.", - ) - rate_limits_by_limit_id: Dict[str, Any] | None = Field( - None, - alias="rateLimitsByLimitId", - description="Multi-bucket view keyed by metered `limit_id` (for example, `codex`).", - ) + rate_limits: Annotated[ + RateLimitSnapshot, + Field( + alias="rateLimits", + description="Backward-compatible single-bucket view; mirrors the historical payload.", + ), + ] + rate_limits_by_limit_id: Annotated[ + dict[str, Any] | None, + Field( + alias="rateLimitsByLimitId", + description="Multi-bucket view keyed by metered `limit_id` (for example, `codex`).", + ), + ] = None -HookCompletedNotification = HookStartedNotification +class HookCompletedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + run: HookRunSummary + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str | None, Field(alias="turnId")] = None class ItemCompletedNotification(BaseModel): @@ -7273,30 +7288,38 @@ class ItemCompletedNotification(BaseModel): populate_by_name=True, ) item: ThreadItem - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] -ItemStartedNotification = ItemCompletedNotification +class ItemStartedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + item: ThreadItem + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] class ListMcpServerStatusResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[McpServerStatus] - next_cursor: str | None = Field( - None, - alias="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.", - ) + data: list[McpServerStatus] + next_cursor: Annotated[ + str | None, + Field( + alias="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.", + ), + ] = None class PluginListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - marketplaces: List[PluginMarketplaceEntry] + marketplaces: list[PluginMarketplaceEntry] class ProfileV2(BaseModel): @@ -7316,91 +7339,99 @@ class ProfileV2(BaseModel): web_search: WebSearchMode | None = None -class RealtimeEvent7(BaseModel): +class HandoffRequestedRealtimeEvent(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - handoff_requested: RealtimeHandoffRequested = Field(..., alias="HandoffRequested") + handoff_requested: Annotated[ + RealtimeHandoffRequested, Field(alias="HandoffRequested") + ] class RealtimeEvent( RootModel[ - RealtimeEvent1 - | RealtimeEvent2 - | RealtimeEvent3 - | RealtimeEvent4 - | RealtimeEvent5 - | RealtimeEvent6 - | RealtimeEvent7 - | RealtimeEvent8 + SessionUpdatedRealtimeEvent + | InputTranscriptDeltaRealtimeEvent + | OutputTranscriptDeltaRealtimeEvent + | AudioOutRealtimeEvent + | ConversationItemAddedRealtimeEvent + | ConversationItemDoneRealtimeEvent + | HandoffRequestedRealtimeEvent + | ErrorRealtimeEvent ] ): model_config = ConfigDict( populate_by_name=True, ) root: ( - RealtimeEvent1 - | RealtimeEvent2 - | RealtimeEvent3 - | RealtimeEvent4 - | RealtimeEvent5 - | RealtimeEvent6 - | RealtimeEvent7 - | RealtimeEvent8 + SessionUpdatedRealtimeEvent + | InputTranscriptDeltaRealtimeEvent + | OutputTranscriptDeltaRealtimeEvent + | AudioOutRealtimeEvent + | ConversationItemAddedRealtimeEvent + | ConversationItemDoneRealtimeEvent + | HandoffRequestedRealtimeEvent + | ErrorRealtimeEvent ) -class ResponseItem5(BaseModel): +class FunctionCallOutputResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) call_id: str output: FunctionCallOutputPayload - type: Type128 = Field(..., title="FunctionCallOutputResponseItemType") + type: Annotated[ + Literal["function_call_output"], + Field(title="FunctionCallOutputResponseItemType"), + ] -class ResponseItem7(BaseModel): +class CustomToolCallOutputResponseItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) call_id: str output: FunctionCallOutputPayload - type: Type130 = Field(..., title="CustomToolCallOutputResponseItemType") + type: Annotated[ + Literal["custom_tool_call_output"], + Field(title="CustomToolCallOutputResponseItemType"), + ] class ResponseItem( RootModel[ - ResponseItem1 - | ResponseItem2 - | ResponseItem3 - | ResponseItem4 - | ResponseItem5 - | ResponseItem6 - | ResponseItem7 - | ResponseItem8 - | ResponseItem9 - | ResponseItem10 - | ResponseItem11 - | ResponseItem12 + MessageResponseItem + | ReasoningResponseItem + | LocalShellCallResponseItem + | FunctionCallResponseItem + | FunctionCallOutputResponseItem + | CustomToolCallResponseItem + | CustomToolCallOutputResponseItem + | WebSearchCallResponseItem + | ImageGenerationCallResponseItem + | GhostSnapshotResponseItem + | CompactionResponseItem + | OtherResponseItem ] ): model_config = ConfigDict( populate_by_name=True, ) root: ( - ResponseItem1 - | ResponseItem2 - | ResponseItem3 - | ResponseItem4 - | ResponseItem5 - | ResponseItem6 - | ResponseItem7 - | ResponseItem8 - | ResponseItem9 - | ResponseItem10 - | ResponseItem11 - | ResponseItem12 + MessageResponseItem + | ReasoningResponseItem + | LocalShellCallResponseItem + | FunctionCallResponseItem + | FunctionCallOutputResponseItem + | CustomToolCallResponseItem + | CustomToolCallOutputResponseItem + | WebSearchCallResponseItem + | ImageGenerationCallResponseItem + | GhostSnapshotResponseItem + | CompactionResponseItem + | OtherResponseItem ) @@ -7408,185 +7439,237 @@ class ReviewStartResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - review_thread_id: str = Field( - ..., - alias="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.", - ) + review_thread_id: Annotated[ + str, + Field( + alias="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.", + ), + ] turn: Turn -class ServerNotification9(BaseModel): +class ThreadTokenUsageUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method57 = Field(..., title="Thread/tokenUsage/updatedNotificationMethod") + method: Annotated[ + Literal["thread/tokenUsage/updated"], + Field(title="Thread/tokenUsage/updatedNotificationMethod"), + ] params: ThreadTokenUsageUpdatedNotification -class ServerNotification10(BaseModel): +class TurnStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method58 = Field(..., title="Turn/startedNotificationMethod") + method: Annotated[ + Literal["turn/started"], Field(title="Turn/startedNotificationMethod") + ] params: TurnStartedNotification -class ServerNotification12(BaseModel): +class TurnCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method60 = Field(..., title="Turn/completedNotificationMethod") + method: Annotated[ + Literal["turn/completed"], Field(title="Turn/completedNotificationMethod") + ] params: TurnCompletedNotification -class ServerNotification13(BaseModel): +class HookCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method61 = Field(..., title="Hook/completedNotificationMethod") + method: Annotated[ + Literal["hook/completed"], Field(title="Hook/completedNotificationMethod") + ] params: HookCompletedNotification -class ServerNotification15(BaseModel): +class TurnPlanUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method63 = Field(..., title="Turn/plan/updatedNotificationMethod") + method: Annotated[ + Literal["turn/plan/updated"], Field(title="Turn/plan/updatedNotificationMethod") + ] params: TurnPlanUpdatedNotification -class ServerNotification16(BaseModel): +class ItemStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method64 = Field(..., title="Item/startedNotificationMethod") + method: Annotated[ + Literal["item/started"], Field(title="Item/startedNotificationMethod") + ] params: ItemStartedNotification -class ServerNotification17(BaseModel): +class ItemCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method65 = Field(..., title="Item/completedNotificationMethod") + method: Annotated[ + Literal["item/completed"], Field(title="Item/completedNotificationMethod") + ] params: ItemCompletedNotification -class ServerNotification28(BaseModel): +class AccountRateLimitsUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method76 = Field(..., title="Account/rateLimits/updatedNotificationMethod") + method: Annotated[ + Literal["account/rateLimits/updated"], + Field(title="Account/rateLimits/updatedNotificationMethod"), + ] params: AccountRateLimitsUpdatedNotification -class ServerNotification29(BaseModel): +class AppListUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method77 = Field(..., title="App/list/updatedNotificationMethod") + method: Annotated[ + Literal["app/list/updated"], Field(title="App/list/updatedNotificationMethod") + ] params: AppListUpdatedNotification -class ServerNotification45(BaseModel): +class WindowsSandboxSetupCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method93 = Field( - ..., title="WindowsSandbox/setupCompletedNotificationMethod" - ) + method: Annotated[ + Literal["windowsSandbox/setupCompleted"], + Field(title="WindowsSandbox/setupCompletedNotificationMethod"), + ] params: WindowsSandboxSetupCompletedNotification -class SessionSource2(BaseModel): +class SubAgentSessionSource(BaseModel): model_config = ConfigDict( extra="forbid", populate_by_name=True, ) - sub_agent: SubAgentSource = Field(..., alias="subAgent") + sub_agent: Annotated[SubAgentSource, Field(alias="subAgent")] -class SessionSource(RootModel[SessionSource1 | SessionSource2]): +class SessionSource(RootModel[SessionSourceValue | SubAgentSessionSource]): model_config = ConfigDict( populate_by_name=True, ) - root: SessionSource1 | SessionSource2 + root: SessionSourceValue | SubAgentSessionSource class Thread(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - agent_nickname: str | None = Field( - None, - alias="agentNickname", - description="Optional random unique nickname assigned to an AgentControl-spawned sub-agent.", - ) - agent_role: str | None = Field( - None, - alias="agentRole", - description="Optional role (agent_role) assigned to an AgentControl-spawned sub-agent.", - ) - cli_version: str = Field( - ..., - alias="cliVersion", - description="Version of the CLI that created the thread.", - ) - created_at: int = Field( - ..., - alias="createdAt", - description="Unix timestamp (in seconds) when the thread was created.", - ) - cwd: str = Field(..., description="Working directory captured for the thread.") - ephemeral: bool = Field( - ..., - description="Whether the thread is ephemeral and should not be materialized on disk.", - ) - git_info: GitInfo | None = Field( - None, - alias="gitInfo", - description="Optional Git metadata captured when the thread was created.", - ) + agent_nickname: Annotated[ + str | None, + Field( + alias="agentNickname", + description="Optional random unique nickname assigned to an AgentControl-spawned sub-agent.", + ), + ] = None + agent_role: Annotated[ + str | None, + Field( + alias="agentRole", + description="Optional role (agent_role) assigned to an AgentControl-spawned sub-agent.", + ), + ] = None + cli_version: Annotated[ + str, + Field( + alias="cliVersion", + description="Version of the CLI that created the thread.", + ), + ] + created_at: Annotated[ + int, + Field( + alias="createdAt", + description="Unix timestamp (in seconds) when the thread was created.", + ), + ] + cwd: Annotated[str, Field(description="Working directory captured for the thread.")] + ephemeral: Annotated[ + bool, + Field( + description="Whether the thread is ephemeral and should not be materialized on disk." + ), + ] + git_info: Annotated[ + GitInfo | None, + Field( + alias="gitInfo", + description="Optional Git metadata captured when the thread was created.", + ), + ] = None id: str - model_provider: str = Field( - ..., - alias="modelProvider", - description="Model provider used for this thread (for example, 'openai').", - ) - name: str | None = Field(None, description="Optional user-facing thread title.") - path: str | None = Field(None, description="[UNSTABLE] Path to the thread on disk.") - preview: str = Field( - ..., description="Usually the first user message in the thread, if available." - ) - source: SessionSource = Field( - ..., - description="Origin of the thread (CLI, VSCode, codex exec, codex app-server, etc.).", - ) - status: ThreadStatus = Field( - ..., description="Current runtime status for the thread." - ) - turns: List[Turn] = Field( - ..., - description="Only populated on `thread/resume`, `thread/rollback`, `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.", - ) - updated_at: int = Field( - ..., - alias="updatedAt", - description="Unix timestamp (in seconds) when the thread was last updated.", - ) + model_provider: Annotated[ + str, + Field( + alias="modelProvider", + description="Model provider used for this thread (for example, 'openai').", + ), + ] + name: Annotated[ + str | None, Field(description="Optional user-facing thread title.") + ] = None + path: Annotated[ + str | None, Field(description="[UNSTABLE] Path to the thread on disk.") + ] = None + preview: Annotated[ + str, + Field( + description="Usually the first user message in the thread, if available." + ), + ] + source: Annotated[ + SessionSource, + Field( + description="Origin of the thread (CLI, VSCode, codex exec, codex app-server, etc.)." + ), + ] + status: Annotated[ + ThreadStatus, Field(description="Current runtime status for the thread.") + ] + turns: Annotated[ + list[Turn], + Field( + description="Only populated on `thread/resume`, `thread/rollback`, `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." + ), + ] + updated_at: Annotated[ + int, + Field( + alias="updatedAt", + description="Unix timestamp (in seconds) when the thread was last updated.", + ), + ] class ThreadForkResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: AskForApproval = Field(..., alias="approvalPolicy") + approval_policy: Annotated[AskForApproval, Field(alias="approvalPolicy")] cwd: str model: str - model_provider: str = Field(..., alias="modelProvider") - reasoning_effort: ReasoningEffort | None = Field(None, alias="reasoningEffort") + model_provider: Annotated[str, Field(alias="modelProvider")] + reasoning_effort: Annotated[ + ReasoningEffort | None, Field(alias="reasoningEffort") + ] = None sandbox: SandboxPolicy - service_tier: ServiceTier | None = Field(None, alias="serviceTier") + service_tier: Annotated[ServiceTier | None, Field(alias="serviceTier")] = None thread: Thread @@ -7594,12 +7677,14 @@ class ThreadListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - data: List[Thread] - next_cursor: str | None = Field( - None, - alias="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.", - ) + data: list[Thread] + next_cursor: Annotated[ + str | None, + Field( + alias="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.", + ), + ] = None class ThreadMetadataUpdateResponse(BaseModel): @@ -7609,158 +7694,204 @@ class ThreadMetadataUpdateResponse(BaseModel): thread: Thread -ThreadReadResponse = ThreadMetadataUpdateResponse +class ThreadReadResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread: Thread -ThreadResumeResponse = ThreadForkResponse +class ThreadResumeResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + approval_policy: Annotated[AskForApproval, Field(alias="approvalPolicy")] + cwd: str + model: str + model_provider: Annotated[str, Field(alias="modelProvider")] + reasoning_effort: Annotated[ + ReasoningEffort | None, Field(alias="reasoningEffort") + ] = None + sandbox: SandboxPolicy + service_tier: Annotated[ServiceTier | None, Field(alias="serviceTier")] = None + thread: Thread class ThreadRollbackResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - thread: Thread = Field( - ..., - description="The updated thread after applying the rollback, with `turns` populated.\n\nThe ThreadItems stored in each Turn are lossy since we explicitly do not persist all agent interactions, such as command executions. This is the same behavior as `thread/resume`.", + thread: Annotated[ + Thread, + Field( + description="The updated thread after applying the rollback, with `turns` populated.\n\nThe ThreadItems stored in each Turn are lossy since we explicitly do not persist all agent interactions, such as command executions. This is the same behavior as `thread/resume`." + ), + ] + + +class ThreadStartResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, ) + approval_policy: Annotated[AskForApproval, Field(alias="approvalPolicy")] + cwd: str + model: str + model_provider: Annotated[str, Field(alias="modelProvider")] + reasoning_effort: Annotated[ + ReasoningEffort | None, Field(alias="reasoningEffort") + ] = None + sandbox: SandboxPolicy + service_tier: Annotated[ServiceTier | None, Field(alias="serviceTier")] = None + thread: Thread -ThreadStartResponse = ThreadForkResponse +class ThreadStartedNotification(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread: Thread -ThreadStartedNotification = ThreadMetadataUpdateResponse +class ThreadUnarchiveResponse(BaseModel): + model_config = ConfigDict( + populate_by_name=True, + ) + thread: Thread -ThreadUnarchiveResponse = ThreadMetadataUpdateResponse - - -class ClientRequest44(BaseModel): +class ExternalAgentConfigImportRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method43 = Field(..., title="ExternalAgentConfig/importRequestMethod") + method: Annotated[ + Literal["externalAgentConfig/import"], + Field(title="ExternalAgentConfig/importRequestMethod"), + ] params: ExternalAgentConfigImportParams -class ClientRequest46(BaseModel): +class ConfigBatchWriteRequest(BaseModel): model_config = ConfigDict( populate_by_name=True, ) id: RequestId - method: Method45 = Field(..., title="Config/batchWriteRequestMethod") + method: Annotated[ + Literal["config/batchWrite"], Field(title="Config/batchWriteRequestMethod") + ] params: ConfigBatchWriteParams class ClientRequest( RootModel[ - ClientRequest1 - | ClientRequest2 - | ClientRequest3 - | ClientRequest4 - | ClientRequest5 - | ClientRequest6 - | ClientRequest7 - | ClientRequest8 - | ClientRequest9 - | ClientRequest10 - | ClientRequest11 - | ClientRequest12 - | ClientRequest13 - | ClientRequest14 - | ClientRequest15 - | ClientRequest16 - | ClientRequest17 - | ClientRequest18 - | ClientRequest19 - | ClientRequest20 - | ClientRequest21 - | ClientRequest22 - | ClientRequest23 - | ClientRequest24 - | ClientRequest25 - | ClientRequest26 - | ClientRequest27 - | ClientRequest28 - | ClientRequest29 - | ClientRequest30 - | ClientRequest31 - | ClientRequest32 - | ClientRequest33 - | ClientRequest34 - | ClientRequest35 - | ClientRequest36 - | ClientRequest37 - | ClientRequest38 - | ClientRequest39 - | ClientRequest40 - | ClientRequest41 - | ClientRequest42 - | ClientRequest43 - | ClientRequest44 - | ClientRequest45 - | ClientRequest46 - | ClientRequest47 - | ClientRequest48 - | ClientRequest49 + InitializeRequest + | ThreadStartRequest + | ThreadResumeRequest + | ThreadForkRequest + | ThreadArchiveRequest + | ThreadUnsubscribeRequest + | ThreadNameSetRequest + | ThreadMetadataUpdateRequest + | ThreadUnarchiveRequest + | ThreadCompactStartRequest + | ThreadRollbackRequest + | ThreadListRequest + | ThreadLoadedListRequest + | ThreadReadRequest + | SkillsListRequest + | PluginListRequest + | SkillsRemoteListRequest + | SkillsRemoteExportRequest + | AppListRequest + | SkillsConfigWriteRequest + | PluginInstallRequest + | PluginUninstallRequest + | TurnStartRequest + | TurnSteerRequest + | TurnInterruptRequest + | ReviewStartRequest + | ModelListRequest + | ExperimentalFeatureListRequest + | McpServerOauthLoginRequest + | ConfigMcpServerReloadRequest + | McpServerStatusListRequest + | WindowsSandboxSetupStartRequest + | AccountLoginStartRequest + | AccountLoginCancelRequest + | AccountLogoutRequest + | AccountRateLimitsReadRequest + | FeedbackUploadRequest + | CommandExecRequest + | CommandExecWriteRequest + | CommandExecTerminateRequest + | CommandExecResizeRequest + | ConfigReadRequest + | ExternalAgentConfigDetectRequest + | ExternalAgentConfigImportRequest + | ConfigValueWriteRequest + | ConfigBatchWriteRequest + | ConfigRequirementsReadRequest + | AccountReadRequest + | FuzzyFileSearchRequest ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - ClientRequest1 - | ClientRequest2 - | ClientRequest3 - | ClientRequest4 - | ClientRequest5 - | ClientRequest6 - | ClientRequest7 - | ClientRequest8 - | ClientRequest9 - | ClientRequest10 - | ClientRequest11 - | ClientRequest12 - | ClientRequest13 - | ClientRequest14 - | ClientRequest15 - | ClientRequest16 - | ClientRequest17 - | ClientRequest18 - | ClientRequest19 - | ClientRequest20 - | ClientRequest21 - | ClientRequest22 - | ClientRequest23 - | ClientRequest24 - | ClientRequest25 - | ClientRequest26 - | ClientRequest27 - | ClientRequest28 - | ClientRequest29 - | ClientRequest30 - | ClientRequest31 - | ClientRequest32 - | ClientRequest33 - | ClientRequest34 - | ClientRequest35 - | ClientRequest36 - | ClientRequest37 - | ClientRequest38 - | ClientRequest39 - | ClientRequest40 - | ClientRequest41 - | ClientRequest42 - | ClientRequest43 - | ClientRequest44 - | ClientRequest45 - | ClientRequest46 - | ClientRequest47 - | ClientRequest48 - | ClientRequest49 - ) = Field( - ..., description="Request from the client to the server.", title="ClientRequest" - ) + root: Annotated[ + InitializeRequest + | ThreadStartRequest + | ThreadResumeRequest + | ThreadForkRequest + | ThreadArchiveRequest + | ThreadUnsubscribeRequest + | ThreadNameSetRequest + | ThreadMetadataUpdateRequest + | ThreadUnarchiveRequest + | ThreadCompactStartRequest + | ThreadRollbackRequest + | ThreadListRequest + | ThreadLoadedListRequest + | ThreadReadRequest + | SkillsListRequest + | PluginListRequest + | SkillsRemoteListRequest + | SkillsRemoteExportRequest + | AppListRequest + | SkillsConfigWriteRequest + | PluginInstallRequest + | PluginUninstallRequest + | TurnStartRequest + | TurnSteerRequest + | TurnInterruptRequest + | ReviewStartRequest + | ModelListRequest + | ExperimentalFeatureListRequest + | McpServerOauthLoginRequest + | ConfigMcpServerReloadRequest + | McpServerStatusListRequest + | WindowsSandboxSetupStartRequest + | AccountLoginStartRequest + | AccountLoginCancelRequest + | AccountLogoutRequest + | AccountRateLimitsReadRequest + | FeedbackUploadRequest + | CommandExecRequest + | CommandExecWriteRequest + | CommandExecTerminateRequest + | CommandExecResizeRequest + | ConfigReadRequest + | ExternalAgentConfigDetectRequest + | ExternalAgentConfigImportRequest + | ConfigValueWriteRequest + | ConfigBatchWriteRequest + | ConfigRequirementsReadRequest + | AccountReadRequest + | FuzzyFileSearchRequest, + Field( + description="Request from the client to the server.", title="ClientRequest" + ), + ] class Config(BaseModel): @@ -7783,7 +7914,7 @@ class Config(BaseModel): model_reasoning_summary: ReasoningSummary | None = None model_verbosity: Verbosity | None = None profile: str | None = None - profiles: Dict[str, ProfileV2] | None = {} + profiles: dict[str, ProfileV2] | None = {} review_model: str | None = None sandbox_mode: SandboxMode | None = None sandbox_workspace_write: SandboxWorkspaceWrite | None = None @@ -7797,24 +7928,29 @@ class ConfigReadResponse(BaseModel): populate_by_name=True, ) config: Config - layers: List[ConfigLayer] | None = None - origins: Dict[str, ConfigLayerMetadata] + layers: list[ConfigLayer] | None = None + origins: dict[str, ConfigLayerMetadata] -class EventMsg4(BaseModel): +class RealtimeConversationRealtimeEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) payload: RealtimeEvent - type: Type22 = Field(..., title="RealtimeConversationRealtimeEventMsgType") + type: Annotated[ + Literal["realtime_conversation_realtime"], + Field(title="RealtimeConversationRealtimeEventMsgType"), + ] -class EventMsg62(BaseModel): +class RawResponseItemEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) item: ResponseItem - type: Type80 = Field(..., title="RawResponseItemEventMsgType") + type: Annotated[ + Literal["raw_response_item"], Field(title="RawResponseItemEventMsgType") + ] class RawResponseItemCompletedNotification(BaseModel): @@ -7822,346 +7958,367 @@ class RawResponseItemCompletedNotification(BaseModel): populate_by_name=True, ) item: ResponseItem - thread_id: str = Field(..., alias="threadId") - turn_id: str = Field(..., alias="turnId") + thread_id: Annotated[str, Field(alias="threadId")] + turn_id: Annotated[str, Field(alias="turnId")] -class ServerNotification2(BaseModel): +class ThreadStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Method50 = Field(..., title="Thread/startedNotificationMethod") + method: Annotated[ + Literal["thread/started"], Field(title="Thread/startedNotificationMethod") + ] params: ThreadStartedNotification class ServerNotification( RootModel[ - ServerNotification1 - | ServerNotification2 - | ServerNotification3 - | ServerNotification4 - | ServerNotification5 - | ServerNotification6 - | ServerNotification7 - | ServerNotification8 - | ServerNotification9 - | ServerNotification10 - | ServerNotification11 - | ServerNotification12 - | ServerNotification13 - | ServerNotification14 - | ServerNotification15 - | ServerNotification16 - | ServerNotification17 - | ServerNotification18 - | ServerNotification19 - | ServerNotification20 - | ServerNotification21 - | ServerNotification22 - | ServerNotification23 - | ServerNotification24 - | ServerNotification25 - | ServerNotification26 - | ServerNotification27 - | ServerNotification28 - | ServerNotification29 - | ServerNotification30 - | ServerNotification31 - | ServerNotification32 - | ServerNotification33 - | ServerNotification34 - | ServerNotification35 - | ServerNotification36 - | ServerNotification37 - | ServerNotification38 - | ServerNotification39 - | ServerNotification40 - | ServerNotification41 - | ServerNotification42 - | ServerNotification43 - | ServerNotification44 - | ServerNotification45 - | ServerNotification46 + ErrorServerNotification + | ThreadStartedServerNotification + | ThreadStatusChangedServerNotification + | ThreadArchivedServerNotification + | ThreadUnarchivedServerNotification + | ThreadClosedServerNotification + | SkillsChangedServerNotification + | ThreadNameUpdatedServerNotification + | ThreadTokenUsageUpdatedServerNotification + | TurnStartedServerNotification + | HookStartedServerNotification + | TurnCompletedServerNotification + | HookCompletedServerNotification + | TurnDiffUpdatedServerNotification + | TurnPlanUpdatedServerNotification + | ItemStartedServerNotification + | ItemCompletedServerNotification + | ItemAgentMessageDeltaServerNotification + | ItemPlanDeltaServerNotification + | CommandExecOutputDeltaServerNotification + | ItemCommandExecutionOutputDeltaServerNotification + | ItemCommandExecutionTerminalInteractionServerNotification + | ItemFileChangeOutputDeltaServerNotification + | ServerRequestResolvedServerNotification + | ItemMcpToolCallProgressServerNotification + | McpServerOauthLoginCompletedServerNotification + | AccountUpdatedServerNotification + | AccountRateLimitsUpdatedServerNotification + | AppListUpdatedServerNotification + | ItemReasoningSummaryTextDeltaServerNotification + | ItemReasoningSummaryPartAddedServerNotification + | ItemReasoningTextDeltaServerNotification + | ThreadCompactedServerNotification + | ModelReroutedServerNotification + | DeprecationNoticeServerNotification + | ConfigWarningServerNotification + | FuzzyFileSearchSessionUpdatedServerNotification + | FuzzyFileSearchSessionCompletedServerNotification + | ThreadRealtimeStartedServerNotification + | ThreadRealtimeItemAddedServerNotification + | ThreadRealtimeOutputAudioDeltaServerNotification + | ThreadRealtimeErrorServerNotification + | ThreadRealtimeClosedServerNotification + | WindowsWorldWritableWarningServerNotification + | WindowsSandboxSetupCompletedServerNotification + | AccountLoginCompletedServerNotification ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - ServerNotification1 - | ServerNotification2 - | ServerNotification3 - | ServerNotification4 - | ServerNotification5 - | ServerNotification6 - | ServerNotification7 - | ServerNotification8 - | ServerNotification9 - | ServerNotification10 - | ServerNotification11 - | ServerNotification12 - | ServerNotification13 - | ServerNotification14 - | ServerNotification15 - | ServerNotification16 - | ServerNotification17 - | ServerNotification18 - | ServerNotification19 - | ServerNotification20 - | ServerNotification21 - | ServerNotification22 - | ServerNotification23 - | ServerNotification24 - | ServerNotification25 - | ServerNotification26 - | ServerNotification27 - | ServerNotification28 - | ServerNotification29 - | ServerNotification30 - | ServerNotification31 - | ServerNotification32 - | ServerNotification33 - | ServerNotification34 - | ServerNotification35 - | ServerNotification36 - | ServerNotification37 - | ServerNotification38 - | ServerNotification39 - | ServerNotification40 - | ServerNotification41 - | ServerNotification42 - | ServerNotification43 - | ServerNotification44 - | ServerNotification45 - | ServerNotification46 - ) = Field( - ..., - description="Notification sent from the server to the client.", - title="ServerNotification", - ) + root: Annotated[ + ErrorServerNotification + | ThreadStartedServerNotification + | ThreadStatusChangedServerNotification + | ThreadArchivedServerNotification + | ThreadUnarchivedServerNotification + | ThreadClosedServerNotification + | SkillsChangedServerNotification + | ThreadNameUpdatedServerNotification + | ThreadTokenUsageUpdatedServerNotification + | TurnStartedServerNotification + | HookStartedServerNotification + | TurnCompletedServerNotification + | HookCompletedServerNotification + | TurnDiffUpdatedServerNotification + | TurnPlanUpdatedServerNotification + | ItemStartedServerNotification + | ItemCompletedServerNotification + | ItemAgentMessageDeltaServerNotification + | ItemPlanDeltaServerNotification + | CommandExecOutputDeltaServerNotification + | ItemCommandExecutionOutputDeltaServerNotification + | ItemCommandExecutionTerminalInteractionServerNotification + | ItemFileChangeOutputDeltaServerNotification + | ServerRequestResolvedServerNotification + | ItemMcpToolCallProgressServerNotification + | McpServerOauthLoginCompletedServerNotification + | AccountUpdatedServerNotification + | AccountRateLimitsUpdatedServerNotification + | AppListUpdatedServerNotification + | ItemReasoningSummaryTextDeltaServerNotification + | ItemReasoningSummaryPartAddedServerNotification + | ItemReasoningTextDeltaServerNotification + | ThreadCompactedServerNotification + | ModelReroutedServerNotification + | DeprecationNoticeServerNotification + | ConfigWarningServerNotification + | FuzzyFileSearchSessionUpdatedServerNotification + | FuzzyFileSearchSessionCompletedServerNotification + | ThreadRealtimeStartedServerNotification + | ThreadRealtimeItemAddedServerNotification + | ThreadRealtimeOutputAudioDeltaServerNotification + | ThreadRealtimeErrorServerNotification + | ThreadRealtimeClosedServerNotification + | WindowsWorldWritableWarningServerNotification + | WindowsSandboxSetupCompletedServerNotification + | AccountLoginCompletedServerNotification, + Field( + description="Notification sent from the server to the client.", + title="ServerNotification", + ), + ] -class EventMsg20(BaseModel): +class SessionConfiguredEventMsg(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: AskForApproval = Field( - ..., description="When to escalate for approval for execution" - ) - cwd: str = Field( - ..., - description="Working directory that should be treated as the *root* of the session.", - ) + approval_policy: Annotated[ + AskForApproval, Field(description="When to escalate for approval for execution") + ] + cwd: Annotated[ + str, + Field( + description="Working directory that should be treated as the *root* of the session." + ), + ] forked_from_id: ThreadId | None = None - history_entry_count: conint(ge=0) = Field( - ..., description="Current number of entries in the history log." - ) - history_log_id: conint(ge=0) = Field( - ..., - description="Identifier of the history log file (inode on Unix, 0 otherwise).", - ) - initial_messages: List[EventMsg] | None = Field( - None, - description="Optional initial messages (as events) for resumed sessions. When present, UIs can use these to seed the history.", - ) - model: str = Field(..., description="Tell the client what model is being queried.") + history_entry_count: Annotated[ + int, Field(description="Current number of entries in the history log.", ge=0) + ] + history_log_id: Annotated[ + int, + Field( + description="Identifier of the history log file (inode on Unix, 0 otherwise).", + ge=0, + ), + ] + initial_messages: Annotated[ + list[EventMsg] | None, + Field( + description="Optional initial messages (as events) for resumed sessions. When present, UIs can use these to seed the history." + ), + ] = None + model: Annotated[ + str, Field(description="Tell the client what model is being queried.") + ] model_provider_id: str - network_proxy: SessionNetworkProxyRuntime | None = Field( - None, - description="Runtime proxy bind addresses, when the managed proxy was started for this session.", - ) - reasoning_effort: ReasoningEffort | None = Field( - None, - description="The effort the model is putting into reasoning about the user's request.", - ) - rollout_path: str | None = Field( - None, - description="Path in which the rollout is stored. Can be `None` for ephemeral threads", - ) - sandbox_policy: SandboxPolicy = Field( - ..., description="How to sandbox commands executed in the system" - ) + network_proxy: Annotated[ + SessionNetworkProxyRuntime | None, + Field( + description="Runtime proxy bind addresses, when the managed proxy was started for this session." + ), + ] = None + reasoning_effort: Annotated[ + ReasoningEffort | None, + Field( + description="The effort the model is putting into reasoning about the user's request." + ), + ] = None + rollout_path: Annotated[ + str | None, + Field( + description="Path in which the rollout is stored. Can be `None` for ephemeral threads" + ), + ] = None + sandbox_policy: Annotated[ + SandboxPolicy, + Field(description="How to sandbox commands executed in the system"), + ] service_tier: ServiceTier | None = None session_id: ThreadId - thread_name: str | None = Field( - None, description="Optional user-facing thread name (may be unset)." - ) - type: Type38 = Field(..., title="SessionConfiguredEventMsgType") + thread_name: Annotated[ + str | None, + Field(description="Optional user-facing thread name (may be unset)."), + ] = None + type: Annotated[ + Literal["session_configured"], Field(title="SessionConfiguredEventMsgType") + ] class EventMsg( RootModel[ - EventMsg1 - | EventMsg2 - | EventMsg3 - | EventMsg4 - | EventMsg5 - | EventMsg6 - | EventMsg7 - | EventMsg8 - | EventMsg9 - | EventMsg10 - | EventMsg11 - | EventMsg12 - | EventMsg13 - | EventMsg14 - | EventMsg15 - | EventMsg16 - | EventMsg17 - | EventMsg18 - | EventMsg19 - | EventMsg20 - | EventMsg21 - | EventMsg22 - | EventMsg23 - | EventMsg24 - | EventMsg25 - | EventMsg26 - | EventMsg27 - | EventMsg28 - | EventMsg29 - | EventMsg30 - | EventMsg31 - | EventMsg32 - | EventMsg33 - | EventMsg34 - | EventMsg35 - | EventMsg36 - | EventMsg37 - | EventMsg38 - | EventMsg39 - | EventMsg40 - | EventMsg41 - | EventMsg42 - | EventMsg43 - | EventMsg44 - | EventMsg45 - | EventMsg46 - | EventMsg47 - | EventMsg48 - | EventMsg49 - | EventMsg50 - | EventMsg51 - | EventMsg52 - | EventMsg53 - | EventMsg54 - | EventMsg55 - | EventMsg56 - | EventMsg57 - | EventMsg58 - | EventMsg59 - | EventMsg60 - | EventMsg61 - | EventMsg62 - | EventMsg63 - | EventMsg64 - | EventMsg65 - | EventMsg66 - | EventMsg67 - | EventMsg68 - | EventMsg69 - | EventMsg70 - | EventMsg71 - | EventMsg72 - | EventMsg73 - | EventMsg74 - | EventMsg75 - | EventMsg76 - | EventMsg77 - | EventMsg78 - | EventMsg79 - | EventMsg80 + ErrorEventMsg + | WarningEventMsg + | RealtimeConversationStartedEventMsg + | RealtimeConversationRealtimeEventMsg + | RealtimeConversationClosedEventMsg + | ModelRerouteEventMsg + | ContextCompactedEventMsg + | ThreadRolledBackEventMsg + | TaskStartedEventMsg + | TaskCompleteEventMsg + | TokenCountEventMsg + | AgentMessageEventMsg + | UserMessageEventMsg + | AgentMessageDeltaEventMsg + | AgentReasoningEventMsg + | AgentReasoningDeltaEventMsg + | AgentReasoningRawContentEventMsg + | AgentReasoningRawContentDeltaEventMsg + | AgentReasoningSectionBreakEventMsg + | SessionConfiguredEventMsg + | ThreadNameUpdatedEventMsg + | McpStartupUpdateEventMsg + | McpStartupCompleteEventMsg + | McpToolCallBeginEventMsg + | McpToolCallEndEventMsg + | WebSearchBeginEventMsg + | WebSearchEndEventMsg + | ImageGenerationBeginEventMsg + | ImageGenerationEndEventMsg + | ExecCommandBeginEventMsg + | ExecCommandOutputDeltaEventMsg + | TerminalInteractionEventMsg + | ExecCommandEndEventMsg + | ViewImageToolCallEventMsg + | ExecApprovalRequestEventMsg + | RequestPermissionsEventMsg + | RequestUserInputEventMsg + | DynamicToolCallRequestEventMsg + | DynamicToolCallResponseEventMsg + | ElicitationRequestEventMsg + | ApplyPatchApprovalRequestEventMsg + | DeprecationNoticeEventMsg + | BackgroundEventEventMsg + | UndoStartedEventMsg + | UndoCompletedEventMsg + | StreamErrorEventMsg + | PatchApplyBeginEventMsg + | PatchApplyEndEventMsg + | TurnDiffEventMsg + | GetHistoryEntryResponseEventMsg + | McpListToolsResponseEventMsg + | ListCustomPromptsResponseEventMsg + | ListSkillsResponseEventMsg + | ListRemoteSkillsResponseEventMsg + | RemoteSkillDownloadedEventMsg + | SkillsUpdateAvailableEventMsg + | PlanUpdateEventMsg + | TurnAbortedEventMsg + | ShutdownCompleteEventMsg + | EnteredReviewModeEventMsg + | ExitedReviewModeEventMsg + | RawResponseItemEventMsg + | ItemStartedEventMsg + | ItemCompletedEventMsg + | HookStartedEventMsg + | HookCompletedEventMsg + | AgentMessageContentDeltaEventMsg + | PlanDeltaEventMsg + | ReasoningContentDeltaEventMsg + | ReasoningRawContentDeltaEventMsg + | CollabAgentSpawnBeginEventMsg + | CollabAgentSpawnEndEventMsg + | CollabAgentInteractionBeginEventMsg + | CollabAgentInteractionEndEventMsg + | CollabWaitingBeginEventMsg + | CollabWaitingEndEventMsg + | CollabCloseBeginEventMsg + | CollabCloseEndEventMsg + | CollabResumeBeginEventMsg + | CollabResumeEndEventMsg ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - EventMsg1 - | EventMsg2 - | EventMsg3 - | EventMsg4 - | EventMsg5 - | EventMsg6 - | EventMsg7 - | EventMsg8 - | EventMsg9 - | EventMsg10 - | EventMsg11 - | EventMsg12 - | EventMsg13 - | EventMsg14 - | EventMsg15 - | EventMsg16 - | EventMsg17 - | EventMsg18 - | EventMsg19 - | EventMsg20 - | EventMsg21 - | EventMsg22 - | EventMsg23 - | EventMsg24 - | EventMsg25 - | EventMsg26 - | EventMsg27 - | EventMsg28 - | EventMsg29 - | EventMsg30 - | EventMsg31 - | EventMsg32 - | EventMsg33 - | EventMsg34 - | EventMsg35 - | EventMsg36 - | EventMsg37 - | EventMsg38 - | EventMsg39 - | EventMsg40 - | EventMsg41 - | EventMsg42 - | EventMsg43 - | EventMsg44 - | EventMsg45 - | EventMsg46 - | EventMsg47 - | EventMsg48 - | EventMsg49 - | EventMsg50 - | EventMsg51 - | EventMsg52 - | EventMsg53 - | EventMsg54 - | EventMsg55 - | EventMsg56 - | EventMsg57 - | EventMsg58 - | EventMsg59 - | EventMsg60 - | EventMsg61 - | EventMsg62 - | EventMsg63 - | EventMsg64 - | EventMsg65 - | EventMsg66 - | EventMsg67 - | EventMsg68 - | EventMsg69 - | EventMsg70 - | EventMsg71 - | EventMsg72 - | EventMsg73 - | EventMsg74 - | EventMsg75 - | EventMsg76 - | EventMsg77 - | EventMsg78 - | EventMsg79 - | EventMsg80 - ) = Field( - ..., - description="Response event from the agent NOTE: Make sure none of these values have optional types, as it will mess up the extension code-gen.", - title="EventMsg", - ) + root: Annotated[ + ErrorEventMsg + | WarningEventMsg + | RealtimeConversationStartedEventMsg + | RealtimeConversationRealtimeEventMsg + | RealtimeConversationClosedEventMsg + | ModelRerouteEventMsg + | ContextCompactedEventMsg + | ThreadRolledBackEventMsg + | TaskStartedEventMsg + | TaskCompleteEventMsg + | TokenCountEventMsg + | AgentMessageEventMsg + | UserMessageEventMsg + | AgentMessageDeltaEventMsg + | AgentReasoningEventMsg + | AgentReasoningDeltaEventMsg + | AgentReasoningRawContentEventMsg + | AgentReasoningRawContentDeltaEventMsg + | AgentReasoningSectionBreakEventMsg + | SessionConfiguredEventMsg + | ThreadNameUpdatedEventMsg + | McpStartupUpdateEventMsg + | McpStartupCompleteEventMsg + | McpToolCallBeginEventMsg + | McpToolCallEndEventMsg + | WebSearchBeginEventMsg + | WebSearchEndEventMsg + | ImageGenerationBeginEventMsg + | ImageGenerationEndEventMsg + | ExecCommandBeginEventMsg + | ExecCommandOutputDeltaEventMsg + | TerminalInteractionEventMsg + | ExecCommandEndEventMsg + | ViewImageToolCallEventMsg + | ExecApprovalRequestEventMsg + | RequestPermissionsEventMsg + | RequestUserInputEventMsg + | DynamicToolCallRequestEventMsg + | DynamicToolCallResponseEventMsg + | ElicitationRequestEventMsg + | ApplyPatchApprovalRequestEventMsg + | DeprecationNoticeEventMsg + | BackgroundEventEventMsg + | UndoStartedEventMsg + | UndoCompletedEventMsg + | StreamErrorEventMsg + | PatchApplyBeginEventMsg + | PatchApplyEndEventMsg + | TurnDiffEventMsg + | GetHistoryEntryResponseEventMsg + | McpListToolsResponseEventMsg + | ListCustomPromptsResponseEventMsg + | ListSkillsResponseEventMsg + | ListRemoteSkillsResponseEventMsg + | RemoteSkillDownloadedEventMsg + | SkillsUpdateAvailableEventMsg + | PlanUpdateEventMsg + | TurnAbortedEventMsg + | ShutdownCompleteEventMsg + | EnteredReviewModeEventMsg + | ExitedReviewModeEventMsg + | RawResponseItemEventMsg + | ItemStartedEventMsg + | ItemCompletedEventMsg + | HookStartedEventMsg + | HookCompletedEventMsg + | AgentMessageContentDeltaEventMsg + | PlanDeltaEventMsg + | ReasoningContentDeltaEventMsg + | ReasoningRawContentDeltaEventMsg + | CollabAgentSpawnBeginEventMsg + | CollabAgentSpawnEndEventMsg + | CollabAgentInteractionBeginEventMsg + | CollabAgentInteractionEndEventMsg + | CollabWaitingBeginEventMsg + | CollabWaitingEndEventMsg + | CollabCloseBeginEventMsg + | CollabCloseEndEventMsg + | CollabResumeBeginEventMsg + | CollabResumeEndEventMsg, + Field( + description="Response event from the agent NOTE: Make sure none of these values have optional types, as it will mess up the extension code-gen.", + title="EventMsg", + ), + ] -EventMsg20.model_rebuild() +SessionConfiguredEventMsg.model_rebuild() diff --git a/sdk/python/tests/test_artifact_workflow_and_binaries.py b/sdk/python/tests/test_artifact_workflow_and_binaries.py index 2fd8a34f14..90446451d1 100644 --- a/sdk/python/tests/test_artifact_workflow_and_binaries.py +++ b/sdk/python/tests/test_artifact_workflow_and_binaries.py @@ -3,10 +3,11 @@ from __future__ import annotations import ast import importlib.util import json -import platform import sys +import tomllib from pathlib import Path +import pytest ROOT = Path(__file__).resolve().parents[1] @@ -32,7 +33,11 @@ def test_generate_types_wires_all_generation_steps() -> None: tree = ast.parse(source) generate_types_fn = next( - (node for node in tree.body if isinstance(node, ast.FunctionDef) and node.name == "generate_types"), + ( + node + for node in tree.body + if isinstance(node, ast.FunctionDef) and node.name == "generate_types" + ), None, ) assert generate_types_fn is not None @@ -81,66 +86,326 @@ def test_schema_normalization_only_flattens_string_literal_oneofs() -> None: ] -def test_bundled_binaries_exist_for_all_supported_platforms() -> None: +def test_python_codegen_schema_annotation_adds_stable_variant_titles() -> None: script = _load_update_script_module() - for platform_key in script.PLATFORMS: - bin_path = script.bundled_platform_bin_path(platform_key) - assert bin_path.is_file(), f"Missing bundled binary: {bin_path}" + schema = json.loads( + ( + ROOT.parent.parent + / "codex-rs" + / "app-server-protocol" + / "schema" + / "json" + / "codex_app_server_protocol.v2.schemas.json" + ).read_text() + ) + + script._annotate_schema(schema) + definitions = schema["definitions"] + + server_notification_titles = { + variant.get("title") + for variant in definitions["ServerNotification"]["oneOf"] + if isinstance(variant, dict) + } + assert "ErrorServerNotification" in server_notification_titles + assert "ThreadStartedServerNotification" in server_notification_titles + assert "ErrorNotification" not in server_notification_titles + assert "Thread/startedNotification" not in server_notification_titles + + ask_for_approval_titles = [ + variant.get("title") for variant in definitions["AskForApproval"]["oneOf"] + ] + assert ask_for_approval_titles == [ + "AskForApprovalValue", + "RejectAskForApproval", + ] + + reasoning_summary_titles = [ + variant.get("title") for variant in definitions["ReasoningSummary"]["oneOf"] + ] + assert reasoning_summary_titles == [ + "ReasoningSummaryValue", + "NoneReasoningSummary", + ] -def test_default_runtime_uses_current_platform_bundled_binary() -> None: - client_source = (ROOT / "src" / "codex_app_server" / "client.py").read_text() - client_tree = ast.parse(client_source) +def test_generate_v2_all_uses_titles_for_generated_names() -> None: + source = (ROOT / "scripts" / "update_sdk_artifacts.py").read_text() + assert "--use-title-as-name" in source + assert "--use-annotated" in source + assert "--formatters" in source + assert "ruff-format" in source - # Keep this assertion source-level so it works in both PR2 (types foundation) - # and PR3 (full SDK), regardless of runtime module wiring. - app_server_config = next( + +def test_runtime_package_template_has_no_checked_in_binaries() -> None: + runtime_root = ROOT.parent / "python-runtime" / "src" / "codex_cli_bin" + assert sorted( + path.name + for path in runtime_root.rglob("*") + if path.is_file() and "__pycache__" not in path.parts + ) == ["__init__.py"] + + +def test_runtime_package_is_wheel_only_and_builds_platform_specific_wheels() -> None: + pyproject = tomllib.loads( + (ROOT.parent / "python-runtime" / "pyproject.toml").read_text() + ) + hook_source = (ROOT.parent / "python-runtime" / "hatch_build.py").read_text() + hook_tree = ast.parse(hook_source) + initialize_fn = next( + node + for node in ast.walk(hook_tree) + if isinstance(node, ast.FunctionDef) and node.name == "initialize" + ) + + sdist_guard = next( ( node - for node in client_tree.body - if isinstance(node, ast.ClassDef) and node.name == "AppServerConfig" + for node in initialize_fn.body + if isinstance(node, ast.If) + and isinstance(node.test, ast.Compare) + and isinstance(node.test.left, ast.Attribute) + and isinstance(node.test.left.value, ast.Name) + and node.test.left.value.id == "self" + and node.test.left.attr == "target_name" + and len(node.test.ops) == 1 + and isinstance(node.test.ops[0], ast.Eq) + and len(node.test.comparators) == 1 + and isinstance(node.test.comparators[0], ast.Constant) + and node.test.comparators[0].value == "sdist" ), None, ) - assert app_server_config is not None + build_data_assignments = { + node.targets[0].slice.value: node.value.value + for node in initialize_fn.body + if isinstance(node, ast.Assign) + and len(node.targets) == 1 + and isinstance(node.targets[0], ast.Subscript) + and isinstance(node.targets[0].value, ast.Name) + and node.targets[0].value.id == "build_data" + and isinstance(node.targets[0].slice, ast.Constant) + and isinstance(node.targets[0].slice.value, str) + and isinstance(node.value, ast.Constant) + } - codex_bin_field = next( - ( - node - for node in app_server_config.body - if isinstance(node, ast.AnnAssign) - and isinstance(node.target, ast.Name) - and node.target.id == "codex_bin" - ), - None, + assert pyproject["tool"]["hatch"]["build"]["targets"]["wheel"] == { + "packages": ["src/codex_cli_bin"], + "include": ["src/codex_cli_bin/bin/**"], + "hooks": {"custom": {}}, + } + assert pyproject["tool"]["hatch"]["build"]["targets"]["sdist"] == { + "hooks": {"custom": {}}, + } + assert sdist_guard is not None + assert build_data_assignments == {"pure_python": False, "infer_tag": True} + + +def test_stage_runtime_release_copies_binary_and_sets_version(tmp_path: Path) -> None: + script = _load_update_script_module() + fake_binary = tmp_path / script.runtime_binary_name() + fake_binary.write_text("fake codex\n") + + staged = script.stage_python_runtime_package( + tmp_path / "runtime-stage", + "1.2.3", + fake_binary, ) - assert codex_bin_field is not None - assert isinstance(codex_bin_field.value, ast.Call) - assert isinstance(codex_bin_field.value.func, ast.Name) - assert codex_bin_field.value.func.id == "str" - assert len(codex_bin_field.value.args) == 1 - bundled_call = codex_bin_field.value.args[0] - assert isinstance(bundled_call, ast.Call) - assert isinstance(bundled_call.func, ast.Name) - assert bundled_call.func.id == "_bundled_codex_path" - bin_root = (ROOT / "src" / "codex_app_server" / "bin").resolve() + assert staged == tmp_path / "runtime-stage" + assert script.staged_runtime_bin_path(staged).read_text() == "fake codex\n" + assert 'version = "1.2.3"' in (staged / "pyproject.toml").read_text() - sys_name = platform.system().lower() - machine = platform.machine().lower() - is_arm = machine in {"arm64", "aarch64"} - if sys_name.startswith("darwin"): - platform_dir = "darwin-arm64" if is_arm else "darwin-x64" - exe = "codex" - elif sys_name.startswith("linux"): - platform_dir = "linux-arm64" if is_arm else "linux-x64" - exe = "codex" - elif sys_name.startswith("windows"): - platform_dir = "windows-arm64" if is_arm else "windows-x64" - exe = "codex.exe" - else: - raise AssertionError(f"Unsupported platform in test: {sys_name}/{machine}") +def test_stage_runtime_release_replaces_existing_staging_dir(tmp_path: Path) -> None: + script = _load_update_script_module() + staging_dir = tmp_path / "runtime-stage" + old_file = staging_dir / "stale.txt" + old_file.parent.mkdir(parents=True) + old_file.write_text("stale") - expected = (bin_root / platform_dir / exe).resolve() - assert expected.is_file() + fake_binary = tmp_path / script.runtime_binary_name() + fake_binary.write_text("fake codex\n") + + staged = script.stage_python_runtime_package( + staging_dir, + "1.2.3", + fake_binary, + ) + + assert staged == staging_dir + assert not old_file.exists() + assert script.staged_runtime_bin_path(staged).read_text() == "fake codex\n" + + +def test_stage_sdk_release_injects_exact_runtime_pin(tmp_path: Path) -> None: + script = _load_update_script_module() + staged = script.stage_python_sdk_package(tmp_path / "sdk-stage", "0.2.1", "1.2.3") + + pyproject = (staged / "pyproject.toml").read_text() + assert 'version = "0.2.1"' in pyproject + assert '"codex-cli-bin==1.2.3"' in pyproject + assert not any((staged / "src" / "codex_app_server").glob("bin/**")) + + +def test_stage_sdk_release_replaces_existing_staging_dir(tmp_path: Path) -> None: + script = _load_update_script_module() + staging_dir = tmp_path / "sdk-stage" + old_file = staging_dir / "stale.txt" + old_file.parent.mkdir(parents=True) + old_file.write_text("stale") + + staged = script.stage_python_sdk_package(staging_dir, "0.2.1", "1.2.3") + + assert staged == staging_dir + assert not old_file.exists() + + +def test_stage_sdk_runs_type_generation_before_staging(tmp_path: Path) -> None: + script = _load_update_script_module() + calls: list[str] = [] + args = script.parse_args( + [ + "stage-sdk", + str(tmp_path / "sdk-stage"), + "--runtime-version", + "1.2.3", + ] + ) + + def fake_generate_types() -> None: + calls.append("generate_types") + + def fake_stage_sdk_package( + _staging_dir: Path, _sdk_version: str, _runtime_version: str + ) -> Path: + calls.append("stage_sdk") + return tmp_path / "sdk-stage" + + def fake_stage_runtime_package( + _staging_dir: Path, _runtime_version: str, _runtime_binary: Path + ) -> Path: + raise AssertionError("runtime staging should not run for stage-sdk") + + def fake_current_sdk_version() -> str: + return "0.2.0" + + ops = script.CliOps( + generate_types=fake_generate_types, + stage_python_sdk_package=fake_stage_sdk_package, + stage_python_runtime_package=fake_stage_runtime_package, + current_sdk_version=fake_current_sdk_version, + ) + + script.run_command(args, ops) + + assert calls == ["generate_types", "stage_sdk"] + + +def test_stage_runtime_stages_binary_without_type_generation(tmp_path: Path) -> None: + script = _load_update_script_module() + fake_binary = tmp_path / script.runtime_binary_name() + fake_binary.write_text("fake codex\n") + calls: list[str] = [] + args = script.parse_args( + [ + "stage-runtime", + str(tmp_path / "runtime-stage"), + str(fake_binary), + "--runtime-version", + "1.2.3", + ] + ) + + def fake_generate_types() -> None: + calls.append("generate_types") + + def fake_stage_sdk_package( + _staging_dir: Path, _sdk_version: str, _runtime_version: str + ) -> Path: + raise AssertionError("sdk staging should not run for stage-runtime") + + def fake_stage_runtime_package( + _staging_dir: Path, _runtime_version: str, _runtime_binary: Path + ) -> Path: + calls.append("stage_runtime") + return tmp_path / "runtime-stage" + + def fake_current_sdk_version() -> str: + return "0.2.0" + + ops = script.CliOps( + generate_types=fake_generate_types, + stage_python_sdk_package=fake_stage_sdk_package, + stage_python_runtime_package=fake_stage_runtime_package, + current_sdk_version=fake_current_sdk_version, + ) + + script.run_command(args, ops) + + assert calls == ["stage_runtime"] + + +def test_default_runtime_is_resolved_from_installed_runtime_package( + tmp_path: Path, +) -> None: + from codex_app_server import client as client_module + + fake_binary = tmp_path / ("codex.exe" if client_module.os.name == "nt" else "codex") + fake_binary.write_text("") + ops = client_module.CodexBinResolverOps( + installed_codex_path=lambda: fake_binary, + path_exists=lambda path: path == fake_binary, + ) + + config = client_module.AppServerConfig() + assert config.codex_bin is None + assert client_module.resolve_codex_bin(config, ops) == fake_binary + + +def test_explicit_codex_bin_override_takes_priority(tmp_path: Path) -> None: + from codex_app_server import client as client_module + + explicit_binary = tmp_path / ( + "custom-codex.exe" if client_module.os.name == "nt" else "custom-codex" + ) + explicit_binary.write_text("") + ops = client_module.CodexBinResolverOps( + installed_codex_path=lambda: (_ for _ in ()).throw( + AssertionError("packaged runtime should not be used") + ), + path_exists=lambda path: path == explicit_binary, + ) + + config = client_module.AppServerConfig(codex_bin=str(explicit_binary)) + assert client_module.resolve_codex_bin(config, ops) == explicit_binary + + +def test_missing_runtime_package_requires_explicit_codex_bin() -> None: + from codex_app_server import client as client_module + + ops = client_module.CodexBinResolverOps( + installed_codex_path=lambda: (_ for _ in ()).throw( + FileNotFoundError("missing packaged runtime") + ), + path_exists=lambda _path: False, + ) + + with pytest.raises(FileNotFoundError, match="missing packaged runtime"): + client_module.resolve_codex_bin(client_module.AppServerConfig(), ops) + + +def test_broken_runtime_package_does_not_fall_back() -> None: + from codex_app_server import client as client_module + + ops = client_module.CodexBinResolverOps( + installed_codex_path=lambda: (_ for _ in ()).throw( + FileNotFoundError("missing packaged binary") + ), + path_exists=lambda _path: False, + ) + + with pytest.raises(FileNotFoundError) as exc_info: + client_module.resolve_codex_bin(client_module.AppServerConfig(), ops) + + assert str(exc_info.value) == ("missing packaged binary") diff --git a/sdk/python/tests/test_contract_generation.py b/sdk/python/tests/test_contract_generation.py index 4865494e23..ae926e4817 100644 --- a/sdk/python/tests/test_contract_generation.py +++ b/sdk/python/tests/test_contract_generation.py @@ -42,7 +42,7 @@ def test_generated_files_are_up_to_date(): env["PATH"] = f"{python_bin}{os.pathsep}{env.get('PATH', '')}" subprocess.run( - [sys.executable, "scripts/update_sdk_artifacts.py", "--types-only"], + [sys.executable, "scripts/update_sdk_artifacts.py", "generate-types"], cwd=ROOT, check=True, env=env,