diff --git a/.github/workflows/sdk.yml b/.github/workflows/sdk.yml index f6f65a7dc6..54ed8dc558 100644 --- a/.github/workflows/sdk.yml +++ b/.github/workflows/sdk.yml @@ -36,6 +36,8 @@ jobs: python -m venv /tmp/uv /tmp/uv/bin/python -m pip install uv==0.11.3 /tmp/uv/bin/uv sync --extra dev --frozen + /tmp/uv/bin/uv run --extra dev ruff check --output-format=github . + /tmp/uv/bin/uv run --extra dev ruff format --check . /tmp/uv/bin/uv run --extra dev pytest ' diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 8d6532aa7c..e92864a68a 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,7 @@ { "recommendations": [ "rust-lang.rust-analyzer", + "charliermarsh.ruff", "tamasfe.even-better-toml", "vadimcn.vscode-lldb", diff --git a/.vscode/settings.json b/.vscode/settings.json index 1e857367cb..d19746aec4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,14 @@ "editor.defaultFormatter": "tamasfe.even-better-toml", "editor.formatOnSave": true, }, + "[python]": { + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.ruff": "explicit", + "source.organizeImports.ruff": "explicit", + }, + }, // Array order for options in ~/.codex/config.toml such as `notify` and the // `args` for an MCP server is significant, so we disable reordering. "evenBetterToml.formatter.reorderArrays": false, diff --git a/justfile b/justfile index 71eed89a35..9297c372a3 100644 --- a/justfile +++ b/justfile @@ -30,9 +30,11 @@ app-server-test-client *args: cargo build -p codex-cli cargo run -p codex-app-server-test-client -- --codex-bin ./target/debug/codex "$@" -# format code +# Format Rust and Python SDK code. fmt: cargo fmt -- --config imports_granularity=Item 2>/dev/null + uv run --project ../sdk/python --extra dev ruff check --fix --fix-only ../sdk/python + uv run --project ../sdk/python --extra dev ruff format ../sdk/python fix *args: cargo clippy --fix --tests --allow-dirty "$@" diff --git a/sdk/python/_runtime_setup.py b/sdk/python/_runtime_setup.py index 6237d047df..db7007fa64 100644 --- a/sdk/python/_runtime_setup.py +++ b/sdk/python/_runtime_setup.py @@ -197,15 +197,9 @@ def _download_release_archive(version: str, temp_root: Path) -> Path: metadata = _release_metadata(version) assets = metadata.get("assets") if not isinstance(assets, list): - raise RuntimeSetupError( - f"Release {release_tag} returned malformed assets metadata." - ) + raise RuntimeSetupError(f"Release {release_tag} returned malformed assets metadata.") asset = next( - ( - item - for item in assets - if isinstance(item, dict) and item.get("name") == asset_name - ), + (item for item in assets if isinstance(item, dict) and item.get("name") == asset_name), None, ) if asset is None: @@ -279,9 +273,7 @@ def _extract_runtime_binary(archive_path: Path, temp_root: Path) -> Path: with zipfile.ZipFile(archive_path) as zip_file: zip_file.extractall(extract_dir) else: - raise RuntimeSetupError( - f"Unsupported release archive format: {archive_path.name}" - ) + raise RuntimeSetupError(f"Unsupported release archive format: {archive_path.name}") binary_name = runtime_binary_name() archive_stem = archive_path.name.removesuffix(".tar.gz").removesuffix(".zip") @@ -290,9 +282,7 @@ def _extract_runtime_binary(archive_path: Path, temp_root: Path) -> Path: for path in extract_dir.rglob("*") if path.is_file() and ( - path.name == binary_name - or path.name == archive_stem - or path.name.startswith("codex-") + path.name == binary_name or path.name == archive_stem or path.name.startswith("codex-") ) ] if not candidates: diff --git a/sdk/python/examples/01_quickstart_constructor/async.py b/sdk/python/examples/01_quickstart_constructor/async.py index 6b98adf025..9a5a48e8e5 100644 --- a/sdk/python/examples/01_quickstart_constructor/async.py +++ b/sdk/python/examples/01_quickstart_constructor/async.py @@ -22,7 +22,9 @@ async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: print("Server:", server_label(codex.metadata)) - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) result = await thread.run("Say hello in one sentence.") print("Items:", len(result.items)) print("Text:", result.final_response) diff --git a/sdk/python/examples/02_turn_run/async.py b/sdk/python/examples/02_turn_run/async.py index 73274c82d2..0f6ef94f91 100644 --- a/sdk/python/examples/02_turn_run/async.py +++ b/sdk/python/examples/02_turn_run/async.py @@ -21,7 +21,9 @@ from openai_codex import AsyncCodex, TextInput async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) turn = await thread.turn(TextInput("Give 3 bullets about SIMD.")) result = await turn.run() persisted = await thread.read(include_turns=True) diff --git a/sdk/python/examples/03_turn_stream_events/async.py b/sdk/python/examples/03_turn_stream_events/async.py index 0712a493d1..dcf57af4f2 100644 --- a/sdk/python/examples/03_turn_stream_events/async.py +++ b/sdk/python/examples/03_turn_stream_events/async.py @@ -21,7 +21,9 @@ from openai_codex import AsyncCodex, TextInput async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) turn = await thread.turn(TextInput("Explain SIMD in 3 short bullets.")) event_count = 0 @@ -44,7 +46,9 @@ async def main() -> None: saw_delta = True continue if event.method == "turn/completed": - completed_status = getattr(event.payload.turn.status, "value", str(event.payload.turn.status)) + completed_status = getattr( + event.payload.turn.status, "value", str(event.payload.turn.status) + ) if saw_delta: print() diff --git a/sdk/python/examples/03_turn_stream_events/sync.py b/sdk/python/examples/03_turn_stream_events/sync.py index a9fc25cdca..f96f5c6acd 100644 --- a/sdk/python/examples/03_turn_stream_events/sync.py +++ b/sdk/python/examples/03_turn_stream_events/sync.py @@ -40,7 +40,9 @@ with Codex(config=runtime_config()) as codex: saw_delta = True continue if event.method == "turn/completed": - completed_status = getattr(event.payload.turn.status, "value", str(event.payload.turn.status)) + completed_status = getattr( + event.payload.turn.status, "value", str(event.payload.turn.status) + ) if saw_delta: print() diff --git a/sdk/python/examples/05_existing_thread/async.py b/sdk/python/examples/05_existing_thread/async.py index fa33839790..4dc36531d8 100644 --- a/sdk/python/examples/05_existing_thread/async.py +++ b/sdk/python/examples/05_existing_thread/async.py @@ -5,7 +5,12 @@ _EXAMPLES_ROOT = Path(__file__).resolve().parents[1] if str(_EXAMPLES_ROOT) not in sys.path: sys.path.insert(0, str(_EXAMPLES_ROOT)) -from _bootstrap import assistant_text_from_turn, ensure_local_sdk_src, find_turn_by_id, runtime_config +from _bootstrap import ( + assistant_text_from_turn, + ensure_local_sdk_src, + find_turn_by_id, + runtime_config, +) ensure_local_sdk_src() @@ -16,7 +21,9 @@ from openai_codex import AsyncCodex, TextInput async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: - original = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + original = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) first_turn = await original.turn(TextInput("Tell me one fact about Saturn.")) _ = await first_turn.run() diff --git a/sdk/python/examples/05_existing_thread/sync.py b/sdk/python/examples/05_existing_thread/sync.py index 0e70ca084f..ca441c4223 100644 --- a/sdk/python/examples/05_existing_thread/sync.py +++ b/sdk/python/examples/05_existing_thread/sync.py @@ -5,7 +5,12 @@ _EXAMPLES_ROOT = Path(__file__).resolve().parents[1] if str(_EXAMPLES_ROOT) not in sys.path: sys.path.insert(0, str(_EXAMPLES_ROOT)) -from _bootstrap import assistant_text_from_turn, ensure_local_sdk_src, find_turn_by_id, runtime_config +from _bootstrap import ( + assistant_text_from_turn, + ensure_local_sdk_src, + find_turn_by_id, + runtime_config, +) ensure_local_sdk_src() diff --git a/sdk/python/examples/06_thread_lifecycle_and_controls/async.py b/sdk/python/examples/06_thread_lifecycle_and_controls/async.py index 7f13441c15..ad73a896ee 100644 --- a/sdk/python/examples/06_thread_lifecycle_and_controls/async.py +++ b/sdk/python/examples/06_thread_lifecycle_and_controls/async.py @@ -16,8 +16,12 @@ from openai_codex import AsyncCodex, TextInput async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) - first = await (await thread.turn(TextInput("One sentence about structured planning."))).run() + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) + first = await ( + await thread.turn(TextInput("One sentence about structured planning.")) + ).run() second = await (await thread.turn(TextInput("Now restate it for a junior engineer."))).run() reopened = await codex.thread_resume(thread.id) @@ -36,7 +40,9 @@ async def main() -> None: model="gpt-5.4", config={"model_reasoning_effort": "high"}, ) - resumed_result = await (await resumed.turn(TextInput("Continue in one short sentence."))).run() + resumed_result = await ( + await resumed.turn(TextInput("Continue in one short sentence.")) + ).run() resumed_info = f"{resumed_result.id} {resumed_result.status}" except Exception as exc: resumed_info = f"skipped({type(exc).__name__})" @@ -44,7 +50,9 @@ async def main() -> None: forked_info = "n/a" try: forked = await codex.thread_fork(unarchived.id, model="gpt-5.4") - forked_result = await (await forked.turn(TextInput("Take a different angle in one short sentence."))).run() + forked_result = await ( + await forked.turn(TextInput("Take a different angle in one short sentence.")) + ).run() forked_info = f"{forked_result.id} {forked_result.status}" except Exception as exc: forked_info = f"skipped({type(exc).__name__})" diff --git a/sdk/python/examples/06_thread_lifecycle_and_controls/sync.py b/sdk/python/examples/06_thread_lifecycle_and_controls/sync.py index 6abe11bdaf..d01f165235 100644 --- a/sdk/python/examples/06_thread_lifecycle_and_controls/sync.py +++ b/sdk/python/examples/06_thread_lifecycle_and_controls/sync.py @@ -11,7 +11,6 @@ ensure_local_sdk_src() from openai_codex import Codex, TextInput - with Codex(config=runtime_config()) as codex: thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) first = thread.turn(TextInput("One sentence about structured planning.")).run() @@ -41,7 +40,9 @@ with Codex(config=runtime_config()) as codex: forked_info = "n/a" try: forked = codex.thread_fork(unarchived.id, model="gpt-5.4") - forked_result = forked.turn(TextInput("Take a different angle in one short sentence.")).run() + forked_result = forked.turn( + TextInput("Take a different angle in one short sentence.") + ).run() forked_info = f"{forked_result.id} {forked_result.status}" except Exception as exc: forked_info = f"skipped({type(exc).__name__})" diff --git a/sdk/python/examples/07_image_and_text/async.py b/sdk/python/examples/07_image_and_text/async.py index 862915daf1..41fe96a830 100644 --- a/sdk/python/examples/07_image_and_text/async.py +++ b/sdk/python/examples/07_image_and_text/async.py @@ -23,7 +23,9 @@ REMOTE_IMAGE_URL = "https://raw.githubusercontent.com/github/explore/main/topics async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) turn = await thread.turn( [ TextInput("What is in this image? Give 3 bullets."), diff --git a/sdk/python/examples/08_local_image_and_text/async.py b/sdk/python/examples/08_local_image_and_text/async.py index a571bfa80d..c3abf4d2ee 100644 --- a/sdk/python/examples/08_local_image_and_text/async.py +++ b/sdk/python/examples/08_local_image_and_text/async.py @@ -23,11 +23,15 @@ from openai_codex import AsyncCodex, LocalImageInput, TextInput async def main() -> None: with temporary_sample_image_path() as image_path: async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) turn = await thread.turn( [ - TextInput("Read this generated local image and summarize the colors/layout in 2 bullets."), + TextInput( + "Read this generated local image and summarize the colors/layout in 2 bullets." + ), LocalImageInput(str(image_path.resolve())), ] ) diff --git a/sdk/python/examples/08_local_image_and_text/sync.py b/sdk/python/examples/08_local_image_and_text/sync.py index 784778645e..45c5161cb8 100644 --- a/sdk/python/examples/08_local_image_and_text/sync.py +++ b/sdk/python/examples/08_local_image_and_text/sync.py @@ -23,7 +23,9 @@ with temporary_sample_image_path() as image_path: result = thread.turn( [ - TextInput("Read this generated local image and summarize the colors/layout in 2 bullets."), + TextInput( + "Read this generated local image and summarize the colors/layout in 2 bullets." + ), LocalImageInput(str(image_path.resolve())), ] ).run() diff --git a/sdk/python/examples/10_error_handling_and_retry/async.py b/sdk/python/examples/10_error_handling_and_retry/async.py index daf9e82549..65c95b2b63 100644 --- a/sdk/python/examples/10_error_handling_and_retry/async.py +++ b/sdk/python/examples/10_error_handling_and_retry/async.py @@ -60,7 +60,9 @@ async def retry_on_overload_async( async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) try: result = await retry_on_overload_async( diff --git a/sdk/python/examples/11_cli_mini_app/async.py b/sdk/python/examples/11_cli_mini_app/async.py index a4a13907ce..1b0a2cfd3a 100644 --- a/sdk/python/examples/11_cli_mini_app/async.py +++ b/sdk/python/examples/11_cli_mini_app/async.py @@ -45,7 +45,9 @@ async def main() -> None: print("Codex async mini CLI. Type /exit to quit.") async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) print("Thread:", thread.id) while True: diff --git a/sdk/python/examples/12_turn_params_kitchen_sink/async.py b/sdk/python/examples/12_turn_params_kitchen_sink/async.py index 95037f712d..30b72f3173 100644 --- a/sdk/python/examples/12_turn_params_kitchen_sink/async.py +++ b/sdk/python/examples/12_turn_params_kitchen_sink/async.py @@ -49,7 +49,9 @@ PROMPT = ( async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) turn = await thread.turn( TextInput(PROMPT), @@ -64,12 +66,16 @@ async def main() -> None: try: structured = json.loads(structured_text) except json.JSONDecodeError as exc: - raise RuntimeError(f"Expected JSON matching OUTPUT_SCHEMA, got: {structured_text!r}") from exc + raise RuntimeError( + f"Expected JSON matching OUTPUT_SCHEMA, got: {structured_text!r}" + ) from exc summary = structured.get("summary") actions = structured.get("actions") - if not isinstance(summary, str) or not isinstance(actions, list) or not all( - isinstance(action, str) for action in actions + if ( + not isinstance(summary, str) + or not isinstance(actions, list) + or not all(isinstance(action, str) for action in actions) ): raise RuntimeError( f"Expected structured output with string summary/actions, got: {structured!r}" diff --git a/sdk/python/examples/12_turn_params_kitchen_sink/sync.py b/sdk/python/examples/12_turn_params_kitchen_sink/sync.py index 20b5a7b757..dffe74a915 100644 --- a/sdk/python/examples/12_turn_params_kitchen_sink/sync.py +++ b/sdk/python/examples/12_turn_params_kitchen_sink/sync.py @@ -60,14 +60,20 @@ with Codex(config=runtime_config()) as codex: try: structured = json.loads(structured_text) except json.JSONDecodeError as exc: - raise RuntimeError(f"Expected JSON matching OUTPUT_SCHEMA, got: {structured_text!r}") from exc + raise RuntimeError( + f"Expected JSON matching OUTPUT_SCHEMA, got: {structured_text!r}" + ) from exc summary = structured.get("summary") actions = structured.get("actions") - if not isinstance(summary, str) or not isinstance(actions, list) or not all( - isinstance(action, str) for action in actions + if ( + not isinstance(summary, str) + or not isinstance(actions, list) + or not all(isinstance(action, str) for action in actions) ): - raise RuntimeError(f"Expected structured output with string summary/actions, got: {structured!r}") + raise RuntimeError( + f"Expected structured output with string summary/actions, got: {structured!r}" + ) print("Status:", result.status) print("summary:", summary) diff --git a/sdk/python/examples/13_model_select_and_turn_params/async.py b/sdk/python/examples/13_model_select_and_turn_params/async.py index f221dc0589..f2810d8fd9 100644 --- a/sdk/python/examples/13_model_select_and_turn_params/async.py +++ b/sdk/python/examples/13_model_select_and_turn_params/async.py @@ -5,7 +5,12 @@ _EXAMPLES_ROOT = Path(__file__).resolve().parents[1] if str(_EXAMPLES_ROOT) not in sys.path: sys.path.insert(0, str(_EXAMPLES_ROOT)) -from _bootstrap import assistant_text_from_turn, ensure_local_sdk_src, find_turn_by_id, runtime_config +from _bootstrap import ( + assistant_text_from_turn, + ensure_local_sdk_src, + find_turn_by_id, + runtime_config, +) ensure_local_sdk_src() @@ -35,7 +40,9 @@ PREFERRED_MODEL = "gpt-5.4" def _pick_highest_model(models): visible = [m for m in models if not m.hidden] or models - preferred = next((m for m in visible if m.model == PREFERRED_MODEL or m.id == PREFERRED_MODEL), None) + preferred = next( + (m for m in visible if m.model == PREFERRED_MODEL or m.id == PREFERRED_MODEL), None + ) if preferred is not None: return preferred known_names = {m.id for m in visible} | {m.model for m in visible} @@ -100,7 +107,9 @@ async def main() -> None: first_persisted_turn = find_turn_by_id(persisted.thread.turns, first.id) print("agent.message:", assistant_text_from_turn(first_persisted_turn)) - print("items:", 0 if first_persisted_turn is None else len(first_persisted_turn.items or [])) + print( + "items:", 0 if first_persisted_turn is None else len(first_persisted_turn.items or []) + ) second_turn = await thread.turn( TextInput("Return JSON for a safe feature-flag rollout plan."), @@ -117,7 +126,10 @@ async def main() -> None: second_persisted_turn = find_turn_by_id(persisted.thread.turns, second.id) print("agent.message.params:", assistant_text_from_turn(second_persisted_turn)) - print("items.params:", 0 if second_persisted_turn is None else len(second_persisted_turn.items or [])) + print( + "items.params:", + 0 if second_persisted_turn is None else len(second_persisted_turn.items or []), + ) if __name__ == "__main__": diff --git a/sdk/python/examples/13_model_select_and_turn_params/sync.py b/sdk/python/examples/13_model_select_and_turn_params/sync.py index 51a8b8f0ef..b1154ce171 100644 --- a/sdk/python/examples/13_model_select_and_turn_params/sync.py +++ b/sdk/python/examples/13_model_select_and_turn_params/sync.py @@ -5,7 +5,12 @@ _EXAMPLES_ROOT = Path(__file__).resolve().parents[1] if str(_EXAMPLES_ROOT) not in sys.path: sys.path.insert(0, str(_EXAMPLES_ROOT)) -from _bootstrap import assistant_text_from_turn, ensure_local_sdk_src, find_turn_by_id, runtime_config +from _bootstrap import ( + assistant_text_from_turn, + ensure_local_sdk_src, + find_turn_by_id, + runtime_config, +) ensure_local_sdk_src() @@ -33,7 +38,9 @@ PREFERRED_MODEL = "gpt-5.4" def _pick_highest_model(models): visible = [m for m in models if not m.hidden] or models - preferred = next((m for m in visible if m.model == PREFERRED_MODEL or m.id == PREFERRED_MODEL), None) + preferred = next( + (m for m in visible if m.model == PREFERRED_MODEL or m.id == PREFERRED_MODEL), None + ) if preferred is not None: return preferred known_names = {m.id for m in visible} | {m.model for m in visible} diff --git a/sdk/python/examples/14_turn_controls/async.py b/sdk/python/examples/14_turn_controls/async.py index 02cdfcd9d9..4f2777c2e4 100644 --- a/sdk/python/examples/14_turn_controls/async.py +++ b/sdk/python/examples/14_turn_controls/async.py @@ -20,8 +20,12 @@ from openai_codex import AsyncCodex, TextInput async def main() -> None: async with AsyncCodex(config=runtime_config()) as codex: - thread = await codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) - steer_turn = await thread.turn(TextInput("Count from 1 to 40 with commas, then one summary sentence.")) + thread = await codex.thread_start( + model="gpt-5.4", config={"model_reasoning_effort": "high"} + ) + steer_turn = await thread.turn( + TextInput("Count from 1 to 40 with commas, then one summary sentence.") + ) steer_result = "sent" try: _ = await steer_turn.steer(TextInput("Keep it brief and stop after 10 numbers.")) @@ -35,11 +39,17 @@ async def main() -> None: steer_event_count += 1 if event.method == "turn/completed": steer_completed_turn = event.payload.turn - steer_completed_status = getattr(event.payload.turn.status, "value", str(event.payload.turn.status)) + steer_completed_status = getattr( + event.payload.turn.status, "value", str(event.payload.turn.status) + ) - steer_preview = assistant_text_from_turn(steer_completed_turn).strip() or "[no assistant text]" + steer_preview = ( + assistant_text_from_turn(steer_completed_turn).strip() or "[no assistant text]" + ) - interrupt_turn = await thread.turn(TextInput("Count from 1 to 200 with commas, then one summary sentence.")) + interrupt_turn = await thread.turn( + TextInput("Count from 1 to 200 with commas, then one summary sentence.") + ) interrupt_result = "sent" try: _ = await interrupt_turn.interrupt() @@ -53,9 +63,13 @@ async def main() -> None: interrupt_event_count += 1 if event.method == "turn/completed": interrupt_completed_turn = event.payload.turn - interrupt_completed_status = getattr(event.payload.turn.status, "value", str(event.payload.turn.status)) + interrupt_completed_status = getattr( + event.payload.turn.status, "value", str(event.payload.turn.status) + ) - interrupt_preview = assistant_text_from_turn(interrupt_completed_turn).strip() or "[no assistant text]" + interrupt_preview = ( + assistant_text_from_turn(interrupt_completed_turn).strip() or "[no assistant text]" + ) print("steer.result:", steer_result) print("steer.final.status:", steer_completed_status) diff --git a/sdk/python/examples/14_turn_controls/sync.py b/sdk/python/examples/14_turn_controls/sync.py index 59d7b45d4c..03180ba8eb 100644 --- a/sdk/python/examples/14_turn_controls/sync.py +++ b/sdk/python/examples/14_turn_controls/sync.py @@ -17,7 +17,9 @@ from openai_codex import Codex, TextInput with Codex(config=runtime_config()) as codex: thread = codex.thread_start(model="gpt-5.4", config={"model_reasoning_effort": "high"}) - steer_turn = thread.turn(TextInput("Count from 1 to 40 with commas, then one summary sentence.")) + steer_turn = thread.turn( + TextInput("Count from 1 to 40 with commas, then one summary sentence.") + ) steer_result = "sent" try: _ = steer_turn.steer(TextInput("Keep it brief and stop after 10 numbers.")) @@ -31,11 +33,15 @@ with Codex(config=runtime_config()) as codex: steer_event_count += 1 if event.method == "turn/completed": steer_completed_turn = event.payload.turn - steer_completed_status = getattr(event.payload.turn.status, "value", str(event.payload.turn.status)) + steer_completed_status = getattr( + event.payload.turn.status, "value", str(event.payload.turn.status) + ) steer_preview = assistant_text_from_turn(steer_completed_turn).strip() or "[no assistant text]" - interrupt_turn = thread.turn(TextInput("Count from 1 to 200 with commas, then one summary sentence.")) + interrupt_turn = thread.turn( + TextInput("Count from 1 to 200 with commas, then one summary sentence.") + ) interrupt_result = "sent" try: _ = interrupt_turn.interrupt() @@ -49,9 +55,13 @@ with Codex(config=runtime_config()) as codex: interrupt_event_count += 1 if event.method == "turn/completed": interrupt_completed_turn = event.payload.turn - interrupt_completed_status = getattr(event.payload.turn.status, "value", str(event.payload.turn.status)) + interrupt_completed_status = getattr( + event.payload.turn.status, "value", str(event.payload.turn.status) + ) - interrupt_preview = assistant_text_from_turn(interrupt_completed_turn).strip() or "[no assistant text]" + interrupt_preview = ( + assistant_text_from_turn(interrupt_completed_turn).strip() or "[no assistant text]" + ) print("steer.result:", steer_result) print("steer.final.status:", steer_completed_status) diff --git a/sdk/python/examples/_bootstrap.py b/sdk/python/examples/_bootstrap.py index df2f1b87eb..af115119ac 100644 --- a/sdk/python/examples/_bootstrap.py +++ b/sdk/python/examples/_bootstrap.py @@ -2,7 +2,6 @@ from __future__ import annotations import contextlib import importlib.util -import os import sys import tempfile import zlib @@ -107,11 +106,15 @@ def temporary_sample_image_path() -> Iterator[Path]: def server_label(metadata: object) -> str: server = getattr(metadata, "serverInfo", None) server_name = ((getattr(server, "name", None) or "") if server is not None else "").strip() - server_version = ((getattr(server, "version", None) or "") if server is not None else "").strip() + server_version = ( + (getattr(server, "version", None) or "") if server is not None else "" + ).strip() if server_name and server_version: return f"{server_name} {server_version}" - user_agent = ((getattr(metadata, "userAgent", None) or "") if metadata is not None else "").strip() + user_agent = ( + (getattr(metadata, "userAgent", None) or "") if metadata is not None else "" + ).strip() return user_agent or "unknown" diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index aeb8a2cf39..b7c890d06e 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", "ruff>=0.11"] +dev = ["pytest>=8.0", "datamodel-code-generator==0.31.2", "ruff>=0.15.8"] [tool.hatch.build] exclude = [ @@ -61,6 +61,29 @@ include = [ addopts = "-q" testpaths = ["tests"] +[tool.ruff] +target-version = "py310" +required-version = ">=0.15.8" +line-length = 100 +extend-exclude = [ + "notebooks/**", + "src/openai_codex/generated/**", +] + +[tool.ruff.lint] +select = ["E", "F", "I", "B", "C4"] +ignore = ["E501"] +preview = true +extend-safe-fixes = ["ALL"] +unfixable = ["F841"] + +[tool.ruff.lint.per-file-ignores] +"examples/**/*.py" = ["E402"] +"tests/test_real_app_server_integration.py" = ["E402"] + +[tool.ruff.lint.isort] +combine-as-imports = true + [tool.uv] exclude-newer = "7 days" exclude-newer-package = { openai-codex-cli-bin = "2026-05-10T00:00:00Z" } diff --git a/sdk/python/scripts/update_sdk_artifacts.py b/sdk/python/scripts/update_sdk_artifacts.py index 1889026a01..a40a4aa9c3 100755 --- a/sdk/python/scripts/update_sdk_artifacts.py +++ b/sdk/python/scripts/update_sdk_artifacts.py @@ -88,9 +88,7 @@ def pinned_runtime_version() -> str: pyproject_text = sdk_pyproject_path().read_text() match = re.search(r"(?ms)^dependencies = \[(.*?)\]$", pyproject_text) if match is None: - raise RuntimeError( - "Could not find dependencies array in sdk/python/pyproject.toml" - ) + raise RuntimeError("Could not find dependencies array in sdk/python/pyproject.toml") pins = re.findall( rf'"{re.escape(RUNTIME_DISTRIBUTION_NAME)}==([^"]+)"', @@ -126,8 +124,7 @@ def pinned_runtime_codex_path() -> Path: from codex_cli_bin import bundled_codex_path except ImportError as exc: raise RuntimeError( - f"Installed {RUNTIME_DISTRIBUTION_NAME} package does not expose " - "bundled_codex_path." + f"Installed {RUNTIME_DISTRIBUTION_NAME} package does not expose bundled_codex_path." ) from exc codex_path = bundled_codex_path() @@ -148,9 +145,7 @@ def normalize_codex_version(version: str) -> str: normalized = re.sub(r"-rc\.?([0-9]+)$", r"rc\1", normalized) if not re.fullmatch(r"[0-9]+(?:\.[0-9]+)*(?:(?:a|b|rc)[0-9]+)?", normalized): - raise RuntimeError( - f"Could not normalize Codex version {version!r} to a PEP 440 version" - ) + raise RuntimeError(f"Could not normalize Codex version {version!r} to a PEP 440 version") return normalized @@ -231,9 +226,7 @@ def _rewrite_project_name(pyproject_text: str, name: str) -> str: 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" - ) + raise RuntimeError("Could not find dependencies array in sdk/python/pyproject.toml") raw_items = [item.strip() for item in match.group(1).split(",") if item.strip()] raw_items = [ @@ -285,9 +278,7 @@ def stage_python_runtime_package( 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 - ) + out_bin.chmod(out_bin.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) for resource_binary in resource_binaries: # Some release targets need helper executables beside the main binary # (for example Linux bwrap or Windows sandbox helpers). Keep this @@ -361,11 +352,7 @@ 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) - ): + if not isinstance(enum, list) or not enum or not all(isinstance(item, str) for item in enum): return None return list(enum) @@ -403,11 +390,7 @@ def _variant_definition_name(base: str, variant: dict[str, Any]) -> str | None: 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) - ): + 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) @@ -419,9 +402,7 @@ def _variant_definition_name(base: str, variant: dict[str, Any]) -> str | None: return None -def _variant_collision_key( - base: str, variant: dict[str, Any], generated_name: str -) -> str: +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): @@ -433,11 +414,7 @@ def _variant_collision_key( 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) - ): + 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) @@ -619,13 +596,9 @@ def generate_v2_all(schema_dir: Path) -> None: def _notification_specs(schema_dir: Path) -> list[tuple[str, str]]: """Map each server notification method to its generated payload model class.""" - server_notifications = json.loads( - (schema_dir / "ServerNotification.json").read_text() - ) + server_notifications = json.loads((schema_dir / "ServerNotification.json").read_text()) one_of = server_notifications.get("oneOf", []) - generated_source = ( - sdk_root() / "src" / "openai_codex" / "generated" / "v2_all.py" - ).read_text() + generated_source = (sdk_root() / "src" / "openai_codex" / "generated" / "v2_all.py").read_text() specs: list[tuple[str, str]] = [] @@ -662,9 +635,7 @@ def _notification_turn_id_specs( specs: list[tuple[str, str]], ) -> tuple[list[str], list[str]]: """Classify notification payloads by where their turn id is carried.""" - server_notifications = json.loads( - (schema_dir / "ServerNotification.json").read_text() - ) + server_notifications = json.loads((schema_dir / "ServerNotification.json").read_text()) definitions = server_notifications.get("definitions", {}) if not isinstance(definitions, dict): return ([], []) @@ -699,13 +670,7 @@ def _type_tuple_source(class_names: list[str]) -> str: def generate_notification_registry(schema_dir: Path) -> None: """Regenerate notification dispatch metadata from the runtime notification schema.""" - out = ( - sdk_root() - / "src" - / "openai_codex" - / "generated" - / "notification_registry.py" - ) + out = sdk_root() / "src" / "openai_codex" / "generated" / "notification_registry.py" specs = _notification_specs(schema_dir) class_names = sorted({class_name for _, class_name in specs}) direct_turn_id_types, nested_turn_types = _notification_turn_id_specs( @@ -787,9 +752,7 @@ class PublicFieldSpec: class CliOps: generate_types: Callable[[], None] stage_python_sdk_package: Callable[[Path, str], Path] - stage_python_runtime_package: Callable[ - [Path, str, Path, str | None, Sequence[Path]], Path - ] + stage_python_runtime_package: Callable[[Path, str, Path, str | None, Sequence[Path]], Path] current_sdk_version: Callable[[], str] @@ -891,14 +854,9 @@ def _approval_mode_override_signature_lines() -> list[str]: return [" approval_mode: ApprovalMode | None = None,"] -def _approval_mode_assignment_line( - helper_name: str, *, indent: str = " " -) -> str: +def _approval_mode_assignment_line(helper_name: str, *, indent: str = " ") -> str: """Return the local mapping from public mode to app-server params.""" - return ( - f"{indent}approval_policy, approvals_reviewer = " - f"{helper_name}(approval_mode)" - ) + return f"{indent}approval_policy, approvals_reviewer = {helper_name}(approval_mode)" def _approval_mode_model_arg_lines(*, indent: str = " ") -> list[str]: @@ -909,9 +867,7 @@ def _approval_mode_model_arg_lines(*, indent: str = " ") -> list[str] ] -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] @@ -1224,9 +1180,7 @@ def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="Single SDK maintenance entrypoint") subparsers = parser.add_subparsers(dest="command", required=True) - subparsers.add_parser( - "generate-types", help="Regenerate Python protocol-derived types" - ) + subparsers.add_parser("generate-types", help="Regenerate Python protocol-derived types") stage_sdk_parser = subparsers.add_parser( "stage-sdk", @@ -1324,9 +1278,7 @@ def _resolve_codex_version(args: argparse.Namespace) -> str: normalized_versions = [normalize_codex_version(version) for version in versions] if len(set(normalized_versions)) != 1: - raise RuntimeError( - "SDK and runtime package versions must match; pass one --codex-version" - ) + raise RuntimeError("SDK and runtime package versions must match; pass one --codex-version") return normalized_versions[0] diff --git a/sdk/python/src/openai_codex/__init__.py b/sdk/python/src/openai_codex/__init__.py index c55afbc15f..4a68fabbef 100644 --- a/sdk/python/src/openai_codex/__init__.py +++ b/sdk/python/src/openai_codex/__init__.py @@ -1,18 +1,4 @@ -from .client import AppServerConfig -from .errors import ( - AppServerError, - AppServerRpcError, - InternalRpcError, - InvalidParamsError, - InvalidRequestError, - JsonRpcError, - MethodNotFoundError, - ParseError, - RetryLimitExceededError, - ServerBusyError, - TransportClosedError, - is_retryable_error, -) +from ._version import __version__ from .api import ( ApprovalMode, AsyncCodex, @@ -30,8 +16,22 @@ from .api import ( Thread, TurnHandle, ) +from .client import AppServerConfig +from .errors import ( + AppServerError, + AppServerRpcError, + InternalRpcError, + InvalidParamsError, + InvalidRequestError, + JsonRpcError, + MethodNotFoundError, + ParseError, + RetryLimitExceededError, + ServerBusyError, + TransportClosedError, + is_retryable_error, +) from .retry import retry_on_overload -from ._version import __version__ __all__ = [ "__version__", diff --git a/sdk/python/src/openai_codex/_message_router.py b/sdk/python/src/openai_codex/_message_router.py index fb466f958c..7d4554bb8a 100644 --- a/sdk/python/src/openai_codex/_message_router.py +++ b/sdk/python/src/openai_codex/_message_router.py @@ -122,9 +122,7 @@ class MessageRouter: if notification.method == "turn/completed": self._pending_turn_notifications.pop(turn_id, None) return - self._pending_turn_notifications.setdefault(turn_id, deque()).append( - notification - ) + self._pending_turn_notifications.setdefault(turn_id, deque()).append(notification) return turn_queue.put(notification) diff --git a/sdk/python/src/openai_codex/_version.py b/sdk/python/src/openai_codex/_version.py index 54d150426d..f6e94c2ed0 100644 --- a/sdk/python/src/openai_codex/_version.py +++ b/sdk/python/src/openai_codex/_version.py @@ -1,8 +1,7 @@ from __future__ import annotations import re -from importlib.metadata import PackageNotFoundError -from importlib.metadata import version as distribution_version +from importlib.metadata import PackageNotFoundError, version as distribution_version from pathlib import Path DISTRIBUTION_NAME = "openai-codex" diff --git a/sdk/python/src/openai_codex/api.py b/sdk/python/src/openai_codex/api.py index 683575c7e2..3d47de2a0e 100644 --- a/sdk/python/src/openai_codex/api.py +++ b/sdk/python/src/openai_codex/api.py @@ -5,6 +5,23 @@ from dataclasses import dataclass from enum import Enum from typing import AsyncIterator, Iterator, NoReturn +from ._inputs import ( + ImageInput as ImageInput, + Input, + InputItem as InputItem, + LocalImageInput as LocalImageInput, + MentionInput as MentionInput, + RunInput, + SkillInput as SkillInput, + TextInput as TextInput, + _normalize_run_input, + _to_wire_input, +) +from ._run import ( + RunResult, + _collect_async_run_result, + _collect_run_result, +) from .async_client import AsyncAppServerClient from .client import AppServerClient, AppServerConfig from .generated.v2_all import ( @@ -30,8 +47,8 @@ from .generated.v2_all import ( ThreadSortKey, ThreadSource, ThreadSourceKind, - ThreadStartSource, ThreadStartParams, + ThreadStartSource, Turn as AppServerTurn, TurnCompletedNotification, TurnInterruptResponse, @@ -39,23 +56,6 @@ from .generated.v2_all import ( TurnSteerResponse, ) from .models import InitializeResponse, JsonObject, Notification, ServerInfo -from ._inputs import ( - ImageInput as ImageInput, - Input, - InputItem as InputItem, - LocalImageInput as LocalImageInput, - MentionInput as MentionInput, - RunInput, - SkillInput as SkillInput, - TextInput as TextInput, - _normalize_run_input, - _to_wire_input, -) -from ._run import ( - RunResult, - _collect_async_run_result, - _collect_run_result, -) def _split_user_agent(user_agent: str) -> tuple[str | None, str | None]: @@ -151,11 +151,7 @@ class Codex: normalized_server_name = (server_name or "").strip() normalized_server_version = (server_version or "").strip() - if ( - not user_agent - or not normalized_server_name - or not normalized_server_version - ): + if not user_agent or not normalized_server_name or not normalized_server_version: raise RuntimeError( "initialize response missing required metadata " f"(user_agent={user_agent!r}, server_name={normalized_server_name!r}, server_version={normalized_server_version!r})" @@ -262,9 +258,7 @@ class Codex: sandbox: SandboxMode | None = None, service_tier: str | None = None, ) -> Thread: - approval_policy, approvals_reviewer = _approval_mode_override_settings( - approval_mode - ) + approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode) params = ThreadResumeParams( thread_id=thread_id, approval_policy=approval_policy, @@ -298,9 +292,7 @@ class Codex: service_tier: str | None = None, thread_source: ThreadSource | None = None, ) -> Thread: - approval_policy, approvals_reviewer = _approval_mode_override_settings( - approval_mode - ) + approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode) params = ThreadForkParams( thread_id=thread_id, approval_policy=approval_policy, @@ -470,9 +462,7 @@ class AsyncCodex: service_tier: str | None = None, ) -> AsyncThread: await self._ensure_initialized() - approval_policy, approvals_reviewer = _approval_mode_override_settings( - approval_mode - ) + approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode) params = ThreadResumeParams( thread_id=thread_id, approval_policy=approval_policy, @@ -507,9 +497,7 @@ class AsyncCodex: thread_source: ThreadSource | None = None, ) -> AsyncThread: await self._ensure_initialized() - approval_policy, approvals_reviewer = _approval_mode_override_settings( - approval_mode - ) + approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode) params = ThreadForkParams( thread_id=thread_id, approval_policy=approval_policy, @@ -597,9 +585,7 @@ class Thread: summary: ReasoningSummary | None = None, ) -> TurnHandle: wire_input = _to_wire_input(input) - approval_policy, approvals_reviewer = _approval_mode_override_settings( - approval_mode - ) + approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode) params = TurnStartParams( thread_id=self.id, input=wire_input, @@ -683,9 +669,7 @@ class AsyncThread: ) -> AsyncTurnHandle: await self._codex._ensure_initialized() wire_input = _to_wire_input(input) - approval_policy, approvals_reviewer = _approval_mode_override_settings( - approval_mode - ) + approval_policy, approvals_reviewer = _approval_mode_override_settings(approval_mode) params = TurnStartParams( thread_id=self.id, input=wire_input, @@ -711,9 +695,7 @@ class AsyncThread: async def read(self, *, include_turns: bool = False) -> ThreadReadResponse: await self._codex._ensure_initialized() - return await self._codex._client.thread_read( - self.id, include_turns=include_turns - ) + return await self._codex._client.thread_read(self.id, include_turns=include_turns) async def set_name(self, name: str) -> ThreadSetNameResponse: await self._codex._ensure_initialized() @@ -758,10 +740,7 @@ class TurnHandle: try: for event in stream: payload = event.payload - if ( - isinstance(payload, TurnCompletedNotification) - and payload.turn.id == self.id - ): + if isinstance(payload, TurnCompletedNotification) and payload.turn.id == self.id: completed = payload finally: stream.close() @@ -812,10 +791,7 @@ class AsyncTurnHandle: try: async for event in stream: payload = event.payload - if ( - isinstance(payload, TurnCompletedNotification) - and payload.turn.id == self.id - ): + if isinstance(payload, TurnCompletedNotification) and payload.turn.id == self.id: completed = payload finally: await stream.aclose() diff --git a/sdk/python/src/openai_codex/async_client.py b/sdk/python/src/openai_codex/async_client.py index 581d14abe9..2c38a43087 100644 --- a/sdk/python/src/openai_codex/async_client.py +++ b/sdk/python/src/openai_codex/async_client.py @@ -127,9 +127,7 @@ class AsyncAppServerClient: """List threads using the wrapped sync client.""" return await self._call_sync(self._sync.thread_list, params) - async def thread_read( - self, thread_id: str, include_turns: bool = False - ) -> ThreadReadResponse: + async def thread_read(self, thread_id: str, include_turns: bool = False) -> ThreadReadResponse: """Read a thread using the wrapped sync client.""" return await self._call_sync(self._sync.thread_read, thread_id, include_turns) @@ -164,13 +162,9 @@ class AsyncAppServerClient: params: V2TurnStartParams | JsonObject | None = None, ) -> TurnStartResponse: """Start a turn using the wrapped sync client.""" - return await self._call_sync( - self._sync.turn_start, thread_id, input_items, params - ) + return await self._call_sync(self._sync.turn_start, thread_id, input_items, params) - async def turn_interrupt( - self, thread_id: str, turn_id: str - ) -> TurnInterruptResponse: + async def turn_interrupt(self, thread_id: str, turn_id: str) -> TurnInterruptResponse: """Interrupt a turn using the wrapped sync client.""" return await self._call_sync(self._sync.turn_interrupt, thread_id, turn_id) diff --git a/sdk/python/src/openai_codex/client.py b/sdk/python/src/openai_codex/client.py index 26d23e3fa7..a4b1e4acaf 100644 --- a/sdk/python/src/openai_codex/client.py +++ b/sdk/python/src/openai_codex/client.py @@ -12,6 +12,8 @@ from typing import Callable, Iterator, TypeVar from pydantic import BaseModel +from ._message_router import MessageRouter +from ._version import __version__ as SDK_VERSION from .errors import AppServerError, TransportClosedError from .generated.notification_registry import NOTIFICATION_MODELS from .generated.v2_all import ( @@ -43,9 +45,7 @@ from .models import ( Notification, UnknownNotification, ) -from ._message_router import MessageRouter from .retry import retry_on_overload -from ._version import __version__ as SDK_VERSION ModelT = TypeVar("ModelT", bound=BaseModel) ApprovalHandler = Callable[[str, JsonObject | None], JsonObject] @@ -76,9 +76,7 @@ def _params_dict( return dumped if isinstance(params, dict): return params - raise TypeError( - f"Expected generated params model or dict, got {type(params).__name__}" - ) + raise TypeError(f"Expected generated params model or dict, got {type(params).__name__}") def _installed_codex_path() -> Path: @@ -248,9 +246,7 @@ class AppServerClient: waiter = self._router.create_response_waiter(request_id) try: - self._write_message( - {"id": request_id, "method": method, "params": params or {}} - ) + self._write_message({"id": request_id, "method": method, "params": params or {}}) except BaseException: self._router.discard_response_waiter(request_id) raise @@ -293,20 +289,14 @@ class AppServerClient: params: V2ThreadResumeParams | JsonObject | None = None, ) -> ThreadResumeResponse: payload = {"threadId": thread_id, **_params_dict(params)} - return self.request( - "thread/resume", payload, response_model=ThreadResumeResponse - ) + return self.request("thread/resume", payload, response_model=ThreadResumeResponse) def thread_list( self, params: V2ThreadListParams | JsonObject | None = None ) -> ThreadListResponse: - return self.request( - "thread/list", _params_dict(params), response_model=ThreadListResponse - ) + return self.request("thread/list", _params_dict(params), response_model=ThreadListResponse) - def thread_read( - self, thread_id: str, include_turns: bool = False - ) -> ThreadReadResponse: + def thread_read(self, thread_id: str, include_turns: bool = False) -> ThreadReadResponse: return self.request( "thread/read", {"threadId": thread_id, "includeTurns": include_turns}, @@ -461,16 +451,12 @@ class AppServerClient: model = NOTIFICATION_MODELS.get(method) if model is None: - return Notification( - method=method, payload=UnknownNotification(params=params_dict) - ) + return Notification(method=method, payload=UnknownNotification(params=params_dict)) try: payload = model.model_validate(params_dict) except Exception: # noqa: BLE001 - return Notification( - method=method, payload=UnknownNotification(params=params_dict) - ) + return Notification(method=method, payload=UnknownNotification(params=params_dict)) return Notification(method=method, payload=payload) def _normalize_input_items( @@ -483,9 +469,7 @@ class AppServerClient: return [input_items] return input_items - def _default_approval_handler( - self, method: str, params: JsonObject | None - ) -> JsonObject: + def _default_approval_handler(self, method: str, params: JsonObject | None) -> JsonObject: """Accept approval requests when the caller did not provide a handler.""" if method == "item/commandExecution/requestApproval": return {"decision": "accept"} diff --git a/sdk/python/src/openai_codex/errors.py b/sdk/python/src/openai_codex/errors.py index 24972e4fd7..104e35f2e9 100644 --- a/sdk/python/src/openai_codex/errors.py +++ b/sdk/python/src/openai_codex/errors.py @@ -66,11 +66,7 @@ def _is_server_overloaded(data: Any) -> bool: return data.lower() == "server_overloaded" if isinstance(data, dict): - direct = ( - data.get("codex_error_info") - or data.get("codexErrorInfo") - or data.get("errorInfo") - ) + direct = data.get("codex_error_info") or data.get("codexErrorInfo") or data.get("errorInfo") if isinstance(direct, str) and direct.lower() == "server_overloaded": return True if isinstance(direct, dict): diff --git a/sdk/python/src/openai_codex/generated/v2_all.py b/sdk/python/src/openai_codex/generated/v2_all.py index f573f667a7..363d87495c 100644 --- a/sdk/python/src/openai_codex/generated/v2_all.py +++ b/sdk/python/src/openai_codex/generated/v2_all.py @@ -191,8 +191,7 @@ class AppsListParams(BaseModel): populate_by_name=True, ) cursor: Annotated[ - str | None, - Field(description="Opaque pagination cursor returned by a previous call."), + str | None, Field(description="Opaque pagination cursor returned by a previous call.") ] = None force_refetch: Annotated[ bool | None, @@ -203,10 +202,7 @@ class AppsListParams(BaseModel): ] = None limit: Annotated[ int | None, - Field( - description="Optional page size; defaults to a reasonable server-side value.", - ge=0, - ), + Field(description="Optional page size; defaults to a reasonable server-side value.", ge=0), ] = None thread_id: Annotated[ str | None, @@ -323,9 +319,7 @@ class HttpConnectionFailedCodexErrorInfo(BaseModel): extra="forbid", populate_by_name=True, ) - http_connection_failed: Annotated[ - HttpConnectionFailed, Field(alias="httpConnectionFailed") - ] + http_connection_failed: Annotated[HttpConnectionFailed, Field(alias="httpConnectionFailed")] class ResponseStreamConnectionFailed(BaseModel): @@ -442,21 +436,13 @@ class UnknownCommandAction(BaseModel): class CommandAction( RootModel[ - ReadCommandAction - | ListFilesCommandAction - | SearchCommandAction - | UnknownCommandAction + ReadCommandAction | ListFilesCommandAction | SearchCommandAction | UnknownCommandAction ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - ReadCommandAction - | ListFilesCommandAction - | SearchCommandAction - | UnknownCommandAction - ) + root: ReadCommandAction | ListFilesCommandAction | SearchCommandAction | UnknownCommandAction class CommandExecOutputStream(Enum): @@ -525,16 +511,12 @@ class CommandExecWriteParams(BaseModel): close_stdin: Annotated[ bool | None, Field( - alias="closeStdin", - description="Close stdin after writing `deltaBase64`, if present.", + 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.", - ), + Field(alias="deltaBase64", description="Optional base64-encoded stdin bytes to write."), ] = None process_id: Annotated[ str, @@ -630,9 +612,7 @@ class SessionFlagsConfigLayerSource(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Annotated[ - Literal["sessionFlags"], Field(title="SessionFlagsConfigLayerSourceType") - ] + type: Annotated[Literal["sessionFlags"], Field(title="SessionFlagsConfigLayerSourceType")] class LegacyManagedConfigTomlFromFileConfigLayerSource(BaseModel): @@ -721,19 +701,13 @@ class AgentConfiguredHookHandler(BaseModel): class ConfiguredHookHandler( RootModel[ - CommandConfiguredHookHandler - | PromptConfiguredHookHandler - | AgentConfiguredHookHandler + CommandConfiguredHookHandler | PromptConfiguredHookHandler | AgentConfiguredHookHandler ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - CommandConfiguredHookHandler - | PromptConfiguredHookHandler - | AgentConfiguredHookHandler - ) + root: CommandConfiguredHookHandler | PromptConfiguredHookHandler | AgentConfiguredHookHandler class ConfiguredHookMatcherGroup(BaseModel): @@ -783,9 +757,7 @@ class DeprecationNoticeNotification(BaseModel): ) details: Annotated[ str | None, - Field( - description="Optional extra guidance, such as migration steps or rationale." - ), + Field(description="Optional extra guidance, such as migration steps or rationale."), ] = None summary: Annotated[str, Field(description="Concise summary of what is deprecated.")] @@ -796,8 +768,7 @@ class InputTextDynamicToolCallOutputContentItem(BaseModel): ) text: str type: Annotated[ - Literal["inputText"], - Field(title="InputTextDynamicToolCallOutputContentItemType"), + Literal["inputText"], Field(title="InputTextDynamicToolCallOutputContentItemType") ] @@ -807,24 +778,19 @@ class InputImageDynamicToolCallOutputContentItem(BaseModel): ) image_url: Annotated[str, Field(alias="imageUrl")] type: Annotated[ - Literal["inputImage"], - Field(title="InputImageDynamicToolCallOutputContentItemType"), + Literal["inputImage"], Field(title="InputImageDynamicToolCallOutputContentItemType") ] class DynamicToolCallOutputContentItem( RootModel[ - InputTextDynamicToolCallOutputContentItem - | InputImageDynamicToolCallOutputContentItem + InputTextDynamicToolCallOutputContentItem | InputImageDynamicToolCallOutputContentItem ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - InputTextDynamicToolCallOutputContentItem - | InputImageDynamicToolCallOutputContentItem - ) + root: InputTextDynamicToolCallOutputContentItem | InputImageDynamicToolCallOutputContentItem class DynamicToolCallStatus(Enum): @@ -861,8 +827,7 @@ class ExperimentalFeatureEnablementSetResponse(BaseModel): populate_by_name=True, ) enablement: Annotated[ - dict[str, bool], - Field(description="Feature enablement entries updated by this request."), + dict[str, bool], Field(description="Feature enablement entries updated by this request.") ] @@ -871,15 +836,11 @@ class ExperimentalFeatureListParams(BaseModel): populate_by_name=True, ) cursor: Annotated[ - str | None, - Field(description="Opaque pagination cursor returned by a previous call."), + 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, - ), + Field(description="Optional page size; defaults to a reasonable server-side value.", ge=0), ] = None @@ -897,9 +858,7 @@ class ExternalAgentConfigDetectParams(BaseModel): ) cwds: Annotated[ list[str] | None, - Field( - description="Zero or more working directories to include for repo-scoped detection." - ), + Field(description="Zero or more working directories to include for repo-scoped detection."), ] = None include_home: Annotated[ bool | None, @@ -984,9 +943,7 @@ class GlobPatternFileSystemPath(BaseModel): populate_by_name=True, ) pattern: str - type: Annotated[ - Literal["glob_pattern"], Field(title="GlobPatternFileSystemPathType") - ] + type: Annotated[Literal["glob_pattern"], Field(title="GlobPatternFileSystemPathType")] class RootFileSystemSpecialPath(BaseModel): @@ -1069,16 +1026,12 @@ class FsChangedNotification(BaseModel): changed_paths: Annotated[ list[AbsolutePathBuf], Field( - alias="changedPaths", - description="File or directory paths associated with this event.", + alias="changedPaths", description="File or directory paths associated with this event." ), ] watch_id: Annotated[ str, - Field( - alias="watchId", - description="Watch identifier previously provided to `fs/watch`.", - ), + Field(alias="watchId", description="Watch identifier previously provided to `fs/watch`."), ] @@ -1087,12 +1040,10 @@ class FsCopyParams(BaseModel): populate_by_name=True, ) destination_path: Annotated[ - AbsolutePathBuf, - Field(alias="destinationPath", description="Absolute destination path."), + AbsolutePathBuf, Field(alias="destinationPath", description="Absolute destination path.") ] recursive: Annotated[ - bool | None, - Field(description="Required for directory copies; ignored for file copies."), + bool | None, Field(description="Required for directory copies; ignored for file copies.") ] = None source_path: Annotated[ AbsolutePathBuf, Field(alias="sourcePath", description="Absolute source path.") @@ -1110,14 +1061,10 @@ class FsCreateDirectoryParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - path: Annotated[ - AbsolutePathBuf, Field(description="Absolute directory path to create.") - ] + path: Annotated[AbsolutePathBuf, Field(description="Absolute directory path to create.")] recursive: Annotated[ bool | None, - Field( - description="Whether parent directories should also be created. Defaults to `true`." - ), + Field(description="Whether parent directories should also be created. Defaults to `true`."), ] = None @@ -1147,22 +1094,13 @@ class FsGetMetadataResponse(BaseModel): ), ] is_directory: Annotated[ - bool, - Field( - alias="isDirectory", description="Whether the path resolves to a directory." - ), + bool, Field(alias="isDirectory", description="Whether the path resolves to a directory.") ] is_file: Annotated[ - bool, - Field( - alias="isFile", description="Whether the path resolves to a regular file." - ), + bool, Field(alias="isFile", description="Whether the path resolves to a regular file.") ] is_symlink: Annotated[ - bool, - Field( - alias="isSymlink", description="Whether the path itself is a symbolic link." - ), + bool, Field(alias="isSymlink", description="Whether the path itself is a symbolic link.") ] modified_at_ms: Annotated[ int, @@ -1185,17 +1123,10 @@ class FsReadDirectoryEntry(BaseModel): ), ] is_directory: Annotated[ - bool, - Field( - alias="isDirectory", - description="Whether this entry resolves to a directory.", - ), + bool, Field(alias="isDirectory", description="Whether this entry resolves to a directory.") ] is_file: Annotated[ - bool, - Field( - alias="isFile", description="Whether this entry resolves to a regular file." - ), + bool, Field(alias="isFile", description="Whether this entry resolves to a regular file.") ] @@ -1203,9 +1134,7 @@ class FsReadDirectoryParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - path: Annotated[ - AbsolutePathBuf, Field(description="Absolute directory path to read.") - ] + path: Annotated[AbsolutePathBuf, Field(description="Absolute directory path to read.")] class FsReadDirectoryResponse(BaseModel): @@ -1240,16 +1169,12 @@ class FsRemoveParams(BaseModel): ) force: Annotated[ bool | None, - Field( - description="Whether missing paths should be ignored. Defaults to `true`." - ), + Field(description="Whether missing paths should be ignored. Defaults to `true`."), ] = None path: Annotated[AbsolutePathBuf, Field(description="Absolute path to remove.")] recursive: Annotated[ bool | None, - Field( - description="Whether directory removal should recurse. Defaults to `true`." - ), + Field(description="Whether directory removal should recurse. Defaults to `true`."), ] = None @@ -1266,10 +1191,7 @@ class FsUnwatchParams(BaseModel): ) watch_id: Annotated[ str, - Field( - alias="watchId", - description="Watch identifier previously provided to `fs/watch`.", - ), + Field(alias="watchId", description="Watch identifier previously provided to `fs/watch`."), ] @@ -1284,9 +1206,7 @@ class FsWatchParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - path: Annotated[ - AbsolutePathBuf, Field(description="Absolute file or directory path to watch.") - ] + path: Annotated[AbsolutePathBuf, Field(description="Absolute file or directory path to watch.")] watch_id: Annotated[ str, Field( @@ -1301,8 +1221,7 @@ class FsWatchResponse(BaseModel): populate_by_name=True, ) path: Annotated[ - AbsolutePathBuf, - Field(description="Canonicalized path associated with the watch."), + AbsolutePathBuf, Field(description="Canonicalized path associated with the watch.") ] @@ -1425,8 +1344,7 @@ class McpToolCallGuardianApprovalReviewAction(BaseModel): tool_name: Annotated[str, Field(alias="toolName")] tool_title: Annotated[str | None, Field(alias="toolTitle")] = None type: Annotated[ - Literal["mcpToolCall"], - Field(title="McpToolCallGuardianApprovalReviewActionType"), + Literal["mcpToolCall"], Field(title="McpToolCallGuardianApprovalReviewActionType") ] @@ -1461,12 +1379,9 @@ class GuardianWarningNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - message: Annotated[ - str, Field(description="Concise guardian warning message for the user.") - ] + message: Annotated[str, Field(description="Concise guardian warning message for the user.")] thread_id: Annotated[ - str, - Field(alias="threadId", description="Thread target for the guardian warning."), + str, Field(alias="threadId", description="Thread target for the guardian warning.") ] @@ -1562,9 +1477,7 @@ class HooksListParams(BaseModel): ) cwds: Annotated[ list[str] | None, - Field( - description="When empty, defaults to the current session working directory." - ), + Field(description="When empty, defaults to the current session working directory."), ] = None @@ -1652,12 +1565,8 @@ class ChatgptLoginAccountParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - codex_streamlined_login: Annotated[ - bool | None, Field(alias="codexStreamlinedLogin") - ] = None - type: Annotated[ - Literal["chatgpt"], Field(title="Chatgptv2::LoginAccountParamsType") - ] + codex_streamlined_login: Annotated[bool | None, Field(alias="codexStreamlinedLogin")] = None + type: Annotated[Literal["chatgpt"], Field(title="Chatgptv2::LoginAccountParamsType")] class ChatgptDeviceCodeLoginAccountParams(BaseModel): @@ -1665,8 +1574,7 @@ class ChatgptDeviceCodeLoginAccountParams(BaseModel): populate_by_name=True, ) type: Annotated[ - Literal["chatgptDeviceCode"], - Field(title="ChatgptDeviceCodev2::LoginAccountParamsType"), + Literal["chatgptDeviceCode"], Field(title="ChatgptDeviceCodev2::LoginAccountParamsType") ] @@ -1696,8 +1604,7 @@ class ChatgptAuthTokensLoginAccountParams(BaseModel): ), ] = None type: Annotated[ - Literal["chatgptAuthTokens"], - Field(title="ChatgptAuthTokensv2::LoginAccountParamsType"), + Literal["chatgptAuthTokens"], Field(title="ChatgptAuthTokensv2::LoginAccountParamsType") ] @@ -1725,9 +1632,7 @@ class ApiKeyLoginAccountResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Annotated[ - Literal["apiKey"], Field(title="ApiKeyv2::LoginAccountResponseType") - ] + type: Annotated[Literal["apiKey"], Field(title="ApiKeyv2::LoginAccountResponseType")] class ChatgptLoginAccountResponse(BaseModel): @@ -1742,9 +1647,7 @@ class ChatgptLoginAccountResponse(BaseModel): ), ] login_id: Annotated[str, Field(alias="loginId")] - type: Annotated[ - Literal["chatgpt"], Field(title="Chatgptv2::LoginAccountResponseType") - ] + type: Annotated[Literal["chatgpt"], Field(title="Chatgptv2::LoginAccountResponseType")] class ChatgptDeviceCodeLoginAccountResponse(BaseModel): @@ -1753,15 +1656,11 @@ class ChatgptDeviceCodeLoginAccountResponse(BaseModel): ) login_id: Annotated[str, Field(alias="loginId")] type: Annotated[ - Literal["chatgptDeviceCode"], - Field(title="ChatgptDeviceCodev2::LoginAccountResponseType"), + Literal["chatgptDeviceCode"], Field(title="ChatgptDeviceCodev2::LoginAccountResponseType") ] user_code: Annotated[ str, - Field( - alias="userCode", - description="One-time code the user must enter after signing in.", - ), + Field(alias="userCode", description="One-time code the user must enter after signing in."), ] verification_url: Annotated[ str, @@ -1777,8 +1676,7 @@ class ChatgptAuthTokensLoginAccountResponse(BaseModel): populate_by_name=True, ) type: Annotated[ - Literal["chatgptAuthTokens"], - Field(title="ChatgptAuthTokensv2::LoginAccountResponseType"), + Literal["chatgptAuthTokens"], Field(title="ChatgptAuthTokensv2::LoginAccountResponseType") ] @@ -1816,21 +1714,13 @@ class ManagedHooksRequirements(BaseModel): permission_request: Annotated[ list[ConfiguredHookMatcherGroup], Field(alias="PermissionRequest") ] - post_compact: Annotated[ - list[ConfiguredHookMatcherGroup], Field(alias="PostCompact") - ] - post_tool_use: Annotated[ - list[ConfiguredHookMatcherGroup], Field(alias="PostToolUse") - ] + post_compact: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="PostCompact")] + post_tool_use: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="PostToolUse")] pre_compact: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="PreCompact")] pre_tool_use: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="PreToolUse")] - session_start: Annotated[ - list[ConfiguredHookMatcherGroup], Field(alias="SessionStart") - ] + session_start: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="SessionStart")] stop: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="Stop")] - user_prompt_submit: Annotated[ - list[ConfiguredHookMatcherGroup], Field(alias="UserPromptSubmit") - ] + user_prompt_submit: Annotated[list[ConfiguredHookMatcherGroup], Field(alias="UserPromptSubmit")] managed_dir: Annotated[str | None, Field(alias="managedDir")] = None windows_managed_dir: Annotated[str | None, Field(alias="windowsManagedDir")] = None @@ -1879,9 +1769,7 @@ class MarketplaceRemoveResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - installed_root: Annotated[AbsolutePathBuf | None, Field(alias="installedRoot")] = ( - None - ) + installed_root: Annotated[AbsolutePathBuf | None, Field(alias="installedRoot")] = None marketplace_name: Annotated[str, Field(alias="marketplaceName")] @@ -2075,8 +1963,7 @@ class ModelListParams(BaseModel): populate_by_name=True, ) cursor: Annotated[ - str | None, - Field(description="Opaque pagination cursor returned by a previous call."), + str | None, Field(description="Opaque pagination cursor returned by a previous call.") ] = None include_hidden: Annotated[ bool | None, @@ -2087,10 +1974,7 @@ class ModelListParams(BaseModel): ] = None limit: Annotated[ int | None, - Field( - description="Optional page size; defaults to a reasonable server-side value.", - ge=0, - ), + Field(description="Optional page size; defaults to a reasonable server-side value.", ge=0), ] = None @@ -2192,14 +2076,11 @@ class NetworkRequirements(BaseModel): description="Legacy compatibility view derived from `unix_sockets`.", ), ] = None - allow_upstream_proxy: Annotated[bool | None, Field(alias="allowUpstreamProxy")] = ( - None - ) + allow_upstream_proxy: Annotated[bool | None, Field(alias="allowUpstreamProxy")] = None allowed_domains: Annotated[ list[str] | None, Field( - alias="allowedDomains", - description="Legacy compatibility view derived from `domains`.", + alias="allowedDomains", description="Legacy compatibility view derived from `domains`." ), ] = None dangerously_allow_all_unix_sockets: Annotated[ @@ -2211,15 +2092,12 @@ class NetworkRequirements(BaseModel): denied_domains: Annotated[ list[str] | None, Field( - alias="deniedDomains", - description="Legacy compatibility view derived from `domains`.", + alias="deniedDomains", description="Legacy compatibility view derived from `domains`." ), ] = None domains: Annotated[ dict[str, Any] | None, - Field( - description="Canonical network permission map for `experimental_network`." - ), + Field(description="Canonical network permission map for `experimental_network`."), ] = None enabled: bool | None = None http_port: Annotated[int | None, Field(alias="httpPort", ge=0)] = None @@ -2338,14 +2216,10 @@ class ProfilePermissionProfileSelectionParams(BaseModel): ) id: str modifications: list[PermissionProfileModificationParams] | None = None - type: Annotated[ - Literal["profile"], Field(title="ProfilePermissionProfileSelectionParamsType") - ] + type: Annotated[Literal["profile"], Field(title="ProfilePermissionProfileSelectionParamsType")] -class PermissionProfileSelectionParams( - RootModel[ProfilePermissionProfileSelectionParams] -): +class PermissionProfileSelectionParams(RootModel[ProfilePermissionProfileSelectionParams]): model_config = ConfigDict( populate_by_name=True, ) @@ -2405,13 +2279,9 @@ class PluginInstallParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - marketplace_path: Annotated[ - AbsolutePathBuf | None, Field(alias="marketplacePath") - ] = None + marketplace_path: Annotated[AbsolutePathBuf | None, Field(alias="marketplacePath")] = None plugin_name: Annotated[str, Field(alias="pluginName")] - remote_marketplace_name: Annotated[ - str | None, Field(alias="remoteMarketplaceName") - ] = None + remote_marketplace_name: Annotated[str | None, Field(alias="remoteMarketplaceName")] = None class PluginInstallPolicy(Enum): @@ -2445,8 +2315,7 @@ class PluginInterface(BaseModel): composer_icon_url: Annotated[ str | None, Field( - alias="composerIconUrl", - description="Remote composer icon URL from the plugin catalog.", + alias="composerIconUrl", description="Remote composer icon URL from the plugin catalog." ), ] = None default_prompt: Annotated[ @@ -2460,28 +2329,22 @@ class PluginInterface(BaseModel): display_name: Annotated[str | None, Field(alias="displayName")] = None logo: Annotated[ AbsolutePathBuf | None, - Field( - description="Local logo path, resolved from the installed plugin package." - ), + Field(description="Local logo path, resolved from the installed plugin package."), ] = None logo_url: Annotated[ - str | None, - Field(alias="logoUrl", description="Remote logo URL from the plugin catalog."), + str | None, Field(alias="logoUrl", description="Remote logo URL from the plugin catalog.") ] = None long_description: Annotated[str | None, Field(alias="longDescription")] = None privacy_policy_url: Annotated[str | None, Field(alias="privacyPolicyUrl")] = None screenshot_urls: Annotated[ list[str], Field( - alias="screenshotUrls", - description="Remote screenshot URLs from the plugin catalog.", + alias="screenshotUrls", description="Remote screenshot URLs from the plugin catalog." ), ] screenshots: Annotated[ list[AbsolutePathBuf], - Field( - description="Local screenshot paths, resolved from the installed plugin package." - ), + Field(description="Local screenshot paths, resolved from the installed plugin package."), ] short_description: Annotated[str | None, Field(alias="shortDescription")] = None terms_of_service_url: Annotated[str | None, Field(alias="termsOfServiceUrl")] = None @@ -2517,13 +2380,9 @@ class PluginReadParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - marketplace_path: Annotated[ - AbsolutePathBuf | None, Field(alias="marketplacePath") - ] = None + marketplace_path: Annotated[AbsolutePathBuf | None, Field(alias="marketplacePath")] = None plugin_name: Annotated[str, Field(alias="pluginName")] - remote_marketplace_name: Annotated[ - str | None, Field(alias="remoteMarketplaceName") - ] = None + remote_marketplace_name: Annotated[str | None, Field(alias="remoteMarketplaceName")] = None class PluginShareDeleteParams(BaseModel): @@ -2721,9 +2580,7 @@ class RateLimitWindow(BaseModel): ) 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 - ) + window_duration_mins: Annotated[int | None, Field(alias="windowDurationMins")] = None class RealtimeConversationVersion(Enum): @@ -2790,9 +2647,7 @@ class ReasoningTextReasoningItemContent(BaseModel): populate_by_name=True, ) text: str - type: Annotated[ - Literal["reasoning_text"], Field(title="ReasoningTextReasoningItemContentType") - ] + type: Annotated[Literal["reasoning_text"], Field(title="ReasoningTextReasoningItemContentType")] class TextReasoningItemContent(BaseModel): @@ -2803,9 +2658,7 @@ class TextReasoningItemContent(BaseModel): type: Annotated[Literal["text"], Field(title="TextReasoningItemContentType")] -class ReasoningItemContent( - RootModel[ReasoningTextReasoningItemContent | TextReasoningItemContent] -): +class ReasoningItemContent(RootModel[ReasoningTextReasoningItemContent | TextReasoningItemContent]): model_config = ConfigDict( populate_by_name=True, ) @@ -2818,14 +2671,11 @@ class SummaryTextReasoningItemReasoningSummary(BaseModel): ) text: str type: Annotated[ - Literal["summary_text"], - Field(title="SummaryTextReasoningItemReasoningSummaryType"), + Literal["summary_text"], Field(title="SummaryTextReasoningItemReasoningSummaryType") ] -class ReasoningItemReasoningSummary( - RootModel[SummaryTextReasoningItemReasoningSummary] -): +class ReasoningItemReasoningSummary(RootModel[SummaryTextReasoningItemReasoningSummary]): model_config = ConfigDict( populate_by_name=True, ) @@ -2953,9 +2803,7 @@ class ResourceContent(RootModel[ResourceContent1 | ResourceContent2]): ) root: Annotated[ ResourceContent1 | ResourceContent2, - Field( - description="Contents returned when reading a resource from an MCP server." - ), + Field(description="Contents returned when reading a resource from an MCP server."), ] @@ -2986,19 +2834,13 @@ class LocalShellCallResponseItem(BaseModel): populate_by_name=True, ) action: LocalShellAction - call_id: Annotated[ - str | None, Field(description="Set when using the Responses API.") - ] = None + 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." - ), + Field(description="Legacy id field retained for compatibility with older payloads."), ] = None status: LocalShellStatus - type: Annotated[ - Literal["local_shell_call"], Field(title="LocalShellCallResponseItemType") - ] + type: Annotated[Literal["local_shell_call"], Field(title="LocalShellCallResponseItemType")] class FunctionCallResponseItem(BaseModel): @@ -3010,9 +2852,7 @@ class FunctionCallResponseItem(BaseModel): id: str | None = None name: str namespace: str | None = None - type: Annotated[ - Literal["function_call"], Field(title="FunctionCallResponseItemType") - ] + type: Annotated[Literal["function_call"], Field(title="FunctionCallResponseItemType")] class ToolSearchCallResponseItem(BaseModel): @@ -3024,9 +2864,7 @@ class ToolSearchCallResponseItem(BaseModel): execution: str id: str | None = None status: str | None = None - type: Annotated[ - Literal["tool_search_call"], Field(title="ToolSearchCallResponseItemType") - ] + type: Annotated[Literal["tool_search_call"], Field(title="ToolSearchCallResponseItemType")] class CustomToolCallResponseItem(BaseModel): @@ -3038,9 +2876,7 @@ class CustomToolCallResponseItem(BaseModel): input: str name: str status: str | None = None - type: Annotated[ - Literal["custom_tool_call"], Field(title="CustomToolCallResponseItemType") - ] + type: Annotated[Literal["custom_tool_call"], Field(title="CustomToolCallResponseItemType")] class ToolSearchOutputResponseItem(BaseModel): @@ -3051,9 +2887,7 @@ class ToolSearchOutputResponseItem(BaseModel): execution: str status: str tools: list - type: Annotated[ - Literal["tool_search_output"], Field(title="ToolSearchOutputResponseItemType") - ] + type: Annotated[Literal["tool_search_output"], Field(title="ToolSearchOutputResponseItemType")] class ImageGenerationCallResponseItem(BaseModel): @@ -3065,8 +2899,7 @@ class ImageGenerationCallResponseItem(BaseModel): revised_prompt: str | None = None status: str type: Annotated[ - Literal["image_generation_call"], - Field(title="ImageGenerationCallResponseItemType"), + Literal["image_generation_call"], Field(title="ImageGenerationCallResponseItemType") ] @@ -3083,9 +2916,7 @@ class ContextCompactionResponseItem(BaseModel): populate_by_name=True, ) encrypted_content: str | None = None - type: Annotated[ - Literal["context_compaction"], Field(title="ContextCompactionResponseItemType") - ] + type: Annotated[Literal["context_compaction"], Field(title="ContextCompactionResponseItemType")] class OtherResponseItem(BaseModel): @@ -3101,18 +2932,14 @@ class SearchResponsesApiWebSearchAction(BaseModel): ) queries: list[str] | None = None query: str | None = None - type: Annotated[ - Literal["search"], Field(title="SearchResponsesApiWebSearchActionType") - ] + type: Annotated[Literal["search"], Field(title="SearchResponsesApiWebSearchActionType")] class OpenPageResponsesApiWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Annotated[ - Literal["open_page"], Field(title="OpenPageResponsesApiWebSearchActionType") - ] + type: Annotated[Literal["open_page"], Field(title="OpenPageResponsesApiWebSearchActionType")] url: str | None = None @@ -3122,8 +2949,7 @@ class FindInPageResponsesApiWebSearchAction(BaseModel): ) pattern: str | None = None type: Annotated[ - Literal["find_in_page"], - Field(title="FindInPageResponsesApiWebSearchActionType"), + Literal["find_in_page"], Field(title="FindInPageResponsesApiWebSearchActionType") ] url: str | None = None @@ -3132,9 +2958,7 @@ class OtherResponsesApiWebSearchAction(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Annotated[ - Literal["other"], Field(title="OtherResponsesApiWebSearchActionType") - ] + type: Annotated[Literal["other"], Field(title="OtherResponsesApiWebSearchActionType")] class ResponsesApiWebSearchAction( @@ -3185,9 +3009,7 @@ class CommitReviewTarget(BaseModel): sha: str title: Annotated[ str | None, - Field( - description="Optional human-readable label (e.g., commit subject) for UIs." - ), + Field(description="Optional human-readable label (e.g., commit subject) for UIs."), ] = None type: Annotated[Literal["commit"], Field(title="CommitReviewTargetType")] @@ -3229,9 +3051,7 @@ class DangerFullAccessSandboxPolicy(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Annotated[ - Literal["dangerFullAccess"], Field(title="DangerFullAccessSandboxPolicyType") - ] + type: Annotated[Literal["dangerFullAccess"], Field(title="DangerFullAccessSandboxPolicyType")] class ReadOnlySandboxPolicy(BaseModel): @@ -3246,12 +3066,8 @@ class ExternalSandboxSandboxPolicy(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - network_access: Annotated[NetworkAccess | None, Field(alias="networkAccess")] = ( - "restricted" - ) - type: Annotated[ - Literal["externalSandbox"], Field(title="ExternalSandboxSandboxPolicyType") - ] + network_access: Annotated[NetworkAccess | None, Field(alias="networkAccess")] = "restricted" + type: Annotated[Literal["externalSandbox"], Field(title="ExternalSandboxSandboxPolicyType")] class WorkspaceWriteSandboxPolicy(BaseModel): @@ -3259,16 +3075,10 @@ class WorkspaceWriteSandboxPolicy(BaseModel): populate_by_name=True, ) exclude_slash_tmp: Annotated[bool | None, Field(alias="excludeSlashTmp")] = False - exclude_tmpdir_env_var: Annotated[ - bool | None, Field(alias="excludeTmpdirEnvVar") - ] = False + exclude_tmpdir_env_var: Annotated[bool | None, Field(alias="excludeTmpdirEnvVar")] = False network_access: Annotated[bool | None, Field(alias="networkAccess")] = False - type: Annotated[ - Literal["workspaceWrite"], Field(title="WorkspaceWriteSandboxPolicyType") - ] - writable_roots: Annotated[ - list[AbsolutePathBuf] | None, Field(alias="writableRoots") - ] = [] + type: Annotated[Literal["workspaceWrite"], Field(title="WorkspaceWriteSandboxPolicyType")] + writable_roots: Annotated[list[AbsolutePathBuf] | None, Field(alias="writableRoots")] = [] class SandboxPolicy( @@ -3319,8 +3129,7 @@ class ItemAgentMessageDeltaServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["item/agentMessage/delta"], - Field(title="Item/agentMessage/deltaNotificationMethod"), + Literal["item/agentMessage/delta"], Field(title="Item/agentMessage/deltaNotificationMethod") ] params: AgentMessageDeltaNotification @@ -3329,9 +3138,7 @@ class ItemPlanDeltaServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["item/plan/delta"], Field(title="Item/plan/deltaNotificationMethod") - ] + method: Annotated[Literal["item/plan/delta"], Field(title="Item/plan/deltaNotificationMethod")] params: PlanDeltaNotification @@ -3339,9 +3146,7 @@ class ProcessExitedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["process/exited"], Field(title="Process/exitedNotificationMethod") - ] + method: Annotated[Literal["process/exited"], Field(title="Process/exitedNotificationMethod")] params: ProcessExitedNotification @@ -3426,9 +3231,7 @@ class FsChangedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["fs/changed"], Field(title="Fs/changedNotificationMethod") - ] + method: Annotated[Literal["fs/changed"], Field(title="Fs/changedNotificationMethod")] params: FsChangedNotification @@ -3479,9 +3282,7 @@ class ModelReroutedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["model/rerouted"], Field(title="Model/reroutedNotificationMethod") - ] + method: Annotated[Literal["model/rerouted"], Field(title="Model/reroutedNotificationMethod")] params: ModelReroutedNotification @@ -3490,8 +3291,7 @@ class ModelVerificationServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["model/verification"], - Field(title="Model/verificationNotificationMethod"), + Literal["model/verification"], Field(title="Model/verificationNotificationMethod") ] params: ModelVerificationNotification @@ -3500,9 +3300,7 @@ class GuardianWarningServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["guardianWarning"], Field(title="GuardianWarningNotificationMethod") - ] + method: Annotated[Literal["guardianWarning"], Field(title="GuardianWarningNotificationMethod")] params: GuardianWarningNotification @@ -3543,8 +3341,7 @@ class AccountLoginCompletedServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["account/login/completed"], - Field(title="Account/login/completedNotificationMethod"), + Literal["account/login/completed"], Field(title="Account/login/completedNotificationMethod") ] params: AccountLoginCompletedNotification @@ -3655,9 +3452,7 @@ class SkillsConfigWriteParams(BaseModel): ) enabled: bool name: Annotated[str | None, Field(description="Name-based selector.")] = None - path: Annotated[ - AbsolutePathBuf | None, Field(description="Path-based selector.") - ] = None + path: Annotated[AbsolutePathBuf | None, Field(description="Path-based selector.")] = None class SkillsConfigWriteResponse(BaseModel): @@ -3673,9 +3468,7 @@ class SkillsListParams(BaseModel): ) cwds: Annotated[ list[str] | None, - Field( - description="When empty, defaults to the current session working directory." - ), + Field(description="When empty, defaults to the current session working directory."), ] = None force_reload: Annotated[ bool | None, @@ -3747,8 +3540,7 @@ class TextPosition(BaseModel): populate_by_name=True, ) column: Annotated[ - int, - Field(description="1-based column number (in Unicode scalar values).", ge=0), + int, Field(description="1-based column number (in Unicode scalar values).", ge=0) ] line: Annotated[int, Field(description="1-based line number.", ge=0)] @@ -3771,10 +3563,7 @@ class ThreadApproveGuardianDeniedActionParams(BaseModel): populate_by_name=True, ) event: Annotated[ - Any, - Field( - description="Serialized `codex_protocol::protocol::GuardianAssessmentEvent`." - ), + Any, Field(description="Serialized `codex_protocol::protocol::GuardianAssessmentEvent`.") ] thread_id: Annotated[str, Field(alias="threadId")] @@ -3916,14 +3705,11 @@ class CommandExecutionThreadItem(BaseModel): 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[ - AbsolutePathBuf, Field(description="The command's working directory.") - ] + cwd: Annotated[AbsolutePathBuf, Field(description="The command's working directory.")] duration_ms: Annotated[ int | None, Field( - alias="durationMs", - description="The duration of the command execution in milliseconds.", + alias="durationMs", description="The duration of the command execution in milliseconds." ), ] = None exit_code: Annotated[ @@ -3939,9 +3725,7 @@ class CommandExecutionThreadItem(BaseModel): ] = None source: CommandExecutionSource | None = "agent" status: CommandExecutionStatus - type: Annotated[ - Literal["commandExecution"], Field(title="CommandExecutionThreadItemType") - ] + type: Annotated[Literal["commandExecution"], Field(title="CommandExecutionThreadItemType")] class McpToolCallThreadItem(BaseModel): @@ -3951,10 +3735,7 @@ class McpToolCallThreadItem(BaseModel): arguments: Any duration_ms: Annotated[ int | None, - Field( - alias="durationMs", - description="The duration of the MCP tool call in milliseconds.", - ), + Field(alias="durationMs", description="The duration of the MCP tool call in milliseconds."), ] = None error: McpToolCallError | None = None id: str @@ -3977,8 +3758,7 @@ class DynamicToolCallThreadItem(BaseModel): duration_ms: Annotated[ int | None, Field( - alias="durationMs", - description="The duration of the dynamic tool call in milliseconds.", + alias="durationMs", description="The duration of the dynamic tool call in milliseconds." ), ] = None id: str @@ -3986,9 +3766,7 @@ class DynamicToolCallThreadItem(BaseModel): status: DynamicToolCallStatus success: bool | None = None tool: str - type: Annotated[ - Literal["dynamicToolCall"], Field(title="DynamicToolCallThreadItemType") - ] + type: Annotated[Literal["dynamicToolCall"], Field(title="DynamicToolCallThreadItemType")] class ImageViewThreadItem(BaseModel): @@ -4009,9 +3787,7 @@ class ImageGenerationThreadItem(BaseModel): revised_prompt: Annotated[str | None, Field(alias="revisedPrompt")] = None saved_path: Annotated[AbsolutePathBuf | None, Field(alias="savedPath")] = None status: str - type: Annotated[ - Literal["imageGeneration"], Field(title="ImageGenerationThreadItemType") - ] + type: Annotated[Literal["imageGeneration"], Field(title="ImageGenerationThreadItemType")] class EnteredReviewModeThreadItem(BaseModel): @@ -4020,9 +3796,7 @@ class EnteredReviewModeThreadItem(BaseModel): ) id: str review: str - type: Annotated[ - Literal["enteredReviewMode"], Field(title="EnteredReviewModeThreadItemType") - ] + type: Annotated[Literal["enteredReviewMode"], Field(title="EnteredReviewModeThreadItemType")] class ExitedReviewModeThreadItem(BaseModel): @@ -4031,9 +3805,7 @@ class ExitedReviewModeThreadItem(BaseModel): ) id: str review: str - type: Annotated[ - Literal["exitedReviewMode"], Field(title="ExitedReviewModeThreadItemType") - ] + type: Annotated[Literal["exitedReviewMode"], Field(title="ExitedReviewModeThreadItemType")] class ContextCompactionThreadItem(BaseModel): @@ -4041,9 +3813,7 @@ class ContextCompactionThreadItem(BaseModel): populate_by_name=True, ) id: str - type: Annotated[ - Literal["contextCompaction"], Field(title="ContextCompactionThreadItemType") - ] + type: Annotated[Literal["contextCompaction"], Field(title="ContextCompactionThreadItemType")] class ThreadListCwdFilter(RootModel[str | list[str]]): @@ -4058,8 +3828,7 @@ class ThreadLoadedListParams(BaseModel): populate_by_name=True, ) cursor: Annotated[ - str | None, - Field(description="Opaque pagination cursor returned by a previous call."), + 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) @@ -4071,8 +3840,7 @@ class ThreadLoadedListResponse(BaseModel): populate_by_name=True, ) data: Annotated[ - list[str], - Field(description="Thread ids for sessions currently loaded in memory."), + list[str], Field(description="Thread ids for sessions currently loaded in memory.") ] next_cursor: Annotated[ str | None, @@ -4157,9 +3925,7 @@ class ThreadRealtimeAudioChunk(BaseModel): item_id: Annotated[str | None, Field(alias="itemId")] = None 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 + samples_per_channel: Annotated[int | None, Field(alias="samplesPerChannel", ge=0)] = None class ThreadRealtimeClosedNotification(BaseModel): @@ -4206,9 +3972,7 @@ class WebsocketThreadRealtimeStartTransport(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - type: Annotated[ - Literal["websocket"], Field(title="WebsocketThreadRealtimeStartTransportType") - ] + type: Annotated[Literal["websocket"], Field(title="WebsocketThreadRealtimeStartTransportType")] class WebrtcThreadRealtimeStartTransport(BaseModel): @@ -4221,15 +3985,11 @@ class WebrtcThreadRealtimeStartTransport(BaseModel): description="SDP offer generated by a WebRTC RTCPeerConnection after configuring audio and the realtime events data channel." ), ] - type: Annotated[ - Literal["webrtc"], Field(title="WebrtcThreadRealtimeStartTransportType") - ] + type: Annotated[Literal["webrtc"], Field(title="WebrtcThreadRealtimeStartTransportType")] class ThreadRealtimeStartTransport( - RootModel[ - WebsocketThreadRealtimeStartTransport | WebrtcThreadRealtimeStartTransport - ] + RootModel[WebsocketThreadRealtimeStartTransport | WebrtcThreadRealtimeStartTransport] ): model_config = ConfigDict( populate_by_name=True, @@ -4253,9 +4013,7 @@ class ThreadRealtimeTranscriptDeltaNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - delta: Annotated[ - str, Field(description="Live transcript delta from the realtime event.") - ] + delta: Annotated[str, Field(description="Live transcript delta from the realtime event.")] role: str thread_id: Annotated[str, Field(alias="threadId")] @@ -4265,9 +4023,7 @@ class ThreadRealtimeTranscriptDoneNotification(BaseModel): populate_by_name=True, ) role: str - text: Annotated[ - str, Field(description="Final complete text for the transcript part.") - ] + text: Annotated[str, Field(description="Final complete text for the transcript part.")] thread_id: Annotated[str, Field(alias="threadId")] @@ -4275,9 +4031,7 @@ class ThreadResumeParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = ( - None - ) + approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = None approvals_reviewer: Annotated[ ApprovalsReviewer | None, Field( @@ -4288,12 +4042,9 @@ class ThreadResumeParams(BaseModel): 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 + developer_instructions: Annotated[str | None, Field(alias="developerInstructions")] = None model: Annotated[ - str | None, - Field(description="Configuration overrides for the resumed thread, if any."), + 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 @@ -4412,21 +4163,13 @@ class ActiveThreadStatus(BaseModel): class ThreadStatus( RootModel[ - NotLoadedThreadStatus - | IdleThreadStatus - | SystemErrorThreadStatus - | ActiveThreadStatus + NotLoadedThreadStatus | IdleThreadStatus | SystemErrorThreadStatus | ActiveThreadStatus ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - NotLoadedThreadStatus - | IdleThreadStatus - | SystemErrorThreadStatus - | ActiveThreadStatus - ) + root: NotLoadedThreadStatus | IdleThreadStatus | SystemErrorThreadStatus | ActiveThreadStatus class ThreadStatusChangedNotification(BaseModel): @@ -4597,23 +4340,13 @@ class MentionUserInput(BaseModel): class UserInput( RootModel[ - TextUserInput - | ImageUserInput - | LocalImageUserInput - | SkillUserInput - | MentionUserInput + TextUserInput | ImageUserInput | LocalImageUserInput | SkillUserInput | MentionUserInput ] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - TextUserInput - | ImageUserInput - | LocalImageUserInput - | SkillUserInput - | MentionUserInput - ) + root: TextUserInput | ImageUserInput | LocalImageUserInput | SkillUserInput | MentionUserInput class Verbosity(Enum): @@ -4878,9 +4611,7 @@ class ThreadResumeRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["thread/resume"], Field(title="Thread/resumeRequestMethod") - ] + method: Annotated[Literal["thread/resume"], Field(title="Thread/resumeRequestMethod")] params: ThreadResumeParams @@ -4889,9 +4620,7 @@ class ThreadArchiveRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["thread/archive"], Field(title="Thread/archiveRequestMethod") - ] + method: Annotated[Literal["thread/archive"], Field(title="Thread/archiveRequestMethod")] params: ThreadArchiveParams @@ -4900,9 +4629,7 @@ class ThreadUnsubscribeRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["thread/unsubscribe"], Field(title="Thread/unsubscribeRequestMethod") - ] + method: Annotated[Literal["thread/unsubscribe"], Field(title="Thread/unsubscribeRequestMethod")] params: ThreadUnsubscribeParams @@ -4911,9 +4638,7 @@ class ThreadNameSetRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["thread/name/set"], Field(title="Thread/name/setRequestMethod") - ] + method: Annotated[Literal["thread/name/set"], Field(title="Thread/name/setRequestMethod")] params: ThreadSetNameParams @@ -4923,8 +4648,7 @@ class ThreadMetadataUpdateRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["thread/metadata/update"], - Field(title="Thread/metadata/updateRequestMethod"), + Literal["thread/metadata/update"], Field(title="Thread/metadata/updateRequestMethod") ] params: ThreadMetadataUpdateParams @@ -4934,9 +4658,7 @@ class ThreadUnarchiveRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["thread/unarchive"], Field(title="Thread/unarchiveRequestMethod") - ] + method: Annotated[Literal["thread/unarchive"], Field(title="Thread/unarchiveRequestMethod")] params: ThreadUnarchiveParams @@ -4946,8 +4668,7 @@ class ThreadCompactStartRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["thread/compact/start"], - Field(title="Thread/compact/startRequestMethod"), + Literal["thread/compact/start"], Field(title="Thread/compact/startRequestMethod") ] params: ThreadCompactStartParams @@ -4980,9 +4701,7 @@ class ThreadRollbackRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["thread/rollback"], Field(title="Thread/rollbackRequestMethod") - ] + method: Annotated[Literal["thread/rollback"], Field(title="Thread/rollbackRequestMethod")] params: ThreadRollbackParams @@ -4991,9 +4710,7 @@ class ThreadLoadedListRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["thread/loaded/list"], Field(title="Thread/loaded/listRequestMethod") - ] + method: Annotated[Literal["thread/loaded/list"], Field(title="Thread/loaded/listRequestMethod")] params: ThreadLoadedListParams @@ -5040,9 +4757,7 @@ class MarketplaceAddRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["marketplace/add"], Field(title="Marketplace/addRequestMethod") - ] + method: Annotated[Literal["marketplace/add"], Field(title="Marketplace/addRequestMethod")] params: MarketplaceAddParams @@ -5051,9 +4766,7 @@ class MarketplaceRemoveRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["marketplace/remove"], Field(title="Marketplace/removeRequestMethod") - ] + method: Annotated[Literal["marketplace/remove"], Field(title="Marketplace/removeRequestMethod")] params: MarketplaceRemoveParams @@ -5091,9 +4804,7 @@ class PluginSkillReadRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["plugin/skill/read"], Field(title="Plugin/skill/readRequestMethod") - ] + method: Annotated[Literal["plugin/skill/read"], Field(title="Plugin/skill/readRequestMethod")] params: PluginSkillReadParams @@ -5102,9 +4813,7 @@ class PluginShareListRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["plugin/share/list"], Field(title="Plugin/share/listRequestMethod") - ] + method: Annotated[Literal["plugin/share/list"], Field(title="Plugin/share/listRequestMethod")] params: PluginShareListParams @@ -5151,9 +4860,7 @@ class FsCreateDirectoryRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["fs/createDirectory"], Field(title="Fs/createDirectoryRequestMethod") - ] + method: Annotated[Literal["fs/createDirectory"], Field(title="Fs/createDirectoryRequestMethod")] params: FsCreateDirectoryParams @@ -5162,9 +4869,7 @@ class FsGetMetadataRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["fs/getMetadata"], Field(title="Fs/getMetadataRequestMethod") - ] + method: Annotated[Literal["fs/getMetadata"], Field(title="Fs/getMetadataRequestMethod")] params: FsGetMetadataParams @@ -5173,9 +4878,7 @@ class FsReadDirectoryRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["fs/readDirectory"], Field(title="Fs/readDirectoryRequestMethod") - ] + method: Annotated[Literal["fs/readDirectory"], Field(title="Fs/readDirectoryRequestMethod")] params: FsReadDirectoryParams @@ -5231,9 +4934,7 @@ class PluginInstallRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["plugin/install"], Field(title="Plugin/installRequestMethod") - ] + method: Annotated[Literal["plugin/install"], Field(title="Plugin/installRequestMethod")] params: PluginInstallParams @@ -5242,9 +4943,7 @@ class PluginUninstallRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["plugin/uninstall"], Field(title="Plugin/uninstallRequestMethod") - ] + method: Annotated[Literal["plugin/uninstall"], Field(title="Plugin/uninstallRequestMethod")] params: PluginUninstallParams @@ -5253,9 +4952,7 @@ class TurnInterruptRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["turn/interrupt"], Field(title="Turn/interruptRequestMethod") - ] + method: Annotated[Literal["turn/interrupt"], Field(title="Turn/interruptRequestMethod")] params: TurnInterruptParams @@ -5286,8 +4983,7 @@ class ExperimentalFeatureListRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["experimentalFeature/list"], - Field(title="ExperimentalFeature/listRequestMethod"), + Literal["experimentalFeature/list"], Field(title="ExperimentalFeature/listRequestMethod") ] params: ExperimentalFeatureListParams @@ -5310,8 +5006,7 @@ class McpServerOauthLoginRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["mcpServer/oauth/login"], - Field(title="McpServer/oauth/loginRequestMethod"), + Literal["mcpServer/oauth/login"], Field(title="McpServer/oauth/loginRequestMethod") ] params: McpServerOauthLoginParams @@ -5322,8 +5017,7 @@ class ConfigMcpServerReloadRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["config/mcpServer/reload"], - Field(title="Config/mcpServer/reloadRequestMethod"), + Literal["config/mcpServer/reload"], Field(title="Config/mcpServer/reloadRequestMethod") ] params: None = None @@ -5334,8 +5028,7 @@ class McpServerResourceReadRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["mcpServer/resource/read"], - Field(title="McpServer/resource/readRequestMethod"), + Literal["mcpServer/resource/read"], Field(title="McpServer/resource/readRequestMethod") ] params: McpResourceReadParams @@ -5357,8 +5050,7 @@ class WindowsSandboxSetupStartRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["windowsSandbox/setupStart"], - Field(title="WindowsSandbox/setupStartRequestMethod"), + Literal["windowsSandbox/setupStart"], Field(title="WindowsSandbox/setupStartRequestMethod") ] params: WindowsSandboxSetupStartParams @@ -5369,8 +5061,7 @@ class WindowsSandboxReadinessRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["windowsSandbox/readiness"], - Field(title="WindowsSandbox/readinessRequestMethod"), + Literal["windowsSandbox/readiness"], Field(title="WindowsSandbox/readinessRequestMethod") ] params: None = None @@ -5392,8 +5083,7 @@ class AccountLoginCancelRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["account/login/cancel"], - Field(title="Account/login/cancelRequestMethod"), + Literal["account/login/cancel"], Field(title="Account/login/cancelRequestMethod") ] params: CancelLoginAccountParams @@ -5403,9 +5093,7 @@ class AccountLogoutRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["account/logout"], Field(title="Account/logoutRequestMethod") - ] + method: Annotated[Literal["account/logout"], Field(title="Account/logoutRequestMethod")] params: None = None @@ -5415,8 +5103,7 @@ class AccountRateLimitsReadRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["account/rateLimits/read"], - Field(title="Account/rateLimits/readRequestMethod"), + Literal["account/rateLimits/read"], Field(title="Account/rateLimits/readRequestMethod") ] params: None = None @@ -5438,9 +5125,7 @@ class FeedbackUploadRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["feedback/upload"], Field(title="Feedback/uploadRequestMethod") - ] + method: Annotated[Literal["feedback/upload"], Field(title="Feedback/uploadRequestMethod")] params: FeedbackUploadParams @@ -5449,9 +5134,7 @@ class CommandExecWriteRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["command/exec/write"], Field(title="Command/exec/writeRequestMethod") - ] + method: Annotated[Literal["command/exec/write"], Field(title="Command/exec/writeRequestMethod")] params: CommandExecWriteParams @@ -5461,8 +5144,7 @@ class CommandExecTerminateRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["command/exec/terminate"], - Field(title="Command/exec/terminateRequestMethod"), + Literal["command/exec/terminate"], Field(title="Command/exec/terminateRequestMethod") ] params: CommandExecTerminateParams @@ -5494,8 +5176,7 @@ class ConfigRequirementsReadRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["configRequirements/read"], - Field(title="ConfigRequirements/readRequestMethod"), + Literal["configRequirements/read"], Field(title="ConfigRequirements/readRequestMethod") ] params: None = None @@ -5514,9 +5195,7 @@ class FuzzyFileSearchRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["fuzzyFileSearch"], Field(title="FuzzyFileSearchRequestMethod") - ] + method: Annotated[Literal["fuzzyFileSearch"], Field(title="FuzzyFileSearchRequestMethod")] params: FuzzyFileSearchParams @@ -5610,9 +5289,7 @@ class CommandExecOutputDeltaNotification(BaseModel): description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", ), ] - stream: Annotated[ - CommandExecOutputStream, Field(description="Output stream for this chunk.") - ] + stream: Annotated[CommandExecOutputStream, Field(description="Output stream for this chunk.")] class CommandExecParams(BaseModel): @@ -5623,8 +5300,7 @@ class CommandExecParams(BaseModel): 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."), + str | None, Field(description="Optional working directory. Defaults to the server cwd.") ] = None disable_output_cap: Annotated[ bool | None, @@ -5714,9 +5390,7 @@ class CommandExecResizeParams(BaseModel): description="Client-supplied, connection-scoped `processId` from the original `command/exec` request.", ), ] - size: Annotated[ - CommandExecTerminalSize, Field(description="New PTY size in character cells.") - ] + size: Annotated[CommandExecTerminalSize, Field(description="New PTY size in character cells.")] class ConfigEdit(BaseModel): @@ -5759,12 +5433,12 @@ class ConfigRequirements(BaseModel): 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 + enforce_residency: Annotated[ResidencyRequirement | None, Field(alias="enforceResidency")] = ( + None + ) + feature_requirements: Annotated[dict[str, Any] | None, Field(alias="featureRequirements")] = ( + None + ) class ConfigRequirementsReadResponse(BaseModel): @@ -5805,15 +5479,11 @@ class ConfigWarningNotification(BaseModel): ] = None path: Annotated[ str | None, - Field( - description="Optional path to the config file that triggered the warning." - ), + 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." - ), + Field(description="Optional range for the error location inside the config file."), ] = None summary: Annotated[str, Field(description="Concise summary of the warning.")] @@ -5827,9 +5497,7 @@ class InputImageContentItem(BaseModel): type: Annotated[Literal["input_image"], Field(title="InputImageContentItemType")] -class ContentItem( - RootModel[InputTextContentItem | InputImageContentItem | OutputTextContentItem] -): +class ContentItem(RootModel[InputTextContentItem | InputImageContentItem | OutputTextContentItem]): model_config = ConfigDict( populate_by_name=True, ) @@ -5848,10 +5516,7 @@ class ExperimentalFeature(BaseModel): ] = None default_enabled: Annotated[ bool, - Field( - alias="defaultEnabled", - description="Whether this feature is enabled by default.", - ), + Field(alias="defaultEnabled", description="Whether this feature is enabled by default."), ] description: Annotated[ str | None, @@ -5867,17 +5532,11 @@ class ExperimentalFeature(BaseModel): ), ] = 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.") + 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."), + ExperimentalFeatureStage, Field(description="Lifecycle stage of this feature flag.") ] @@ -5936,22 +5595,18 @@ class InputImageFunctionCallOutputContentItem(BaseModel): detail: ImageDetail | None = None image_url: str type: Annotated[ - Literal["input_image"], - Field(title="InputImageFunctionCallOutputContentItemType"), + Literal["input_image"], Field(title="InputImageFunctionCallOutputContentItemType") ] class FunctionCallOutputContentItem( - RootModel[ - InputTextFunctionCallOutputContentItem | InputImageFunctionCallOutputContentItem - ] + RootModel[InputTextFunctionCallOutputContentItem | InputImageFunctionCallOutputContentItem] ): model_config = ConfigDict( populate_by_name=True, ) root: Annotated[ - InputTextFunctionCallOutputContentItem - | InputImageFunctionCallOutputContentItem, + 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." ), @@ -5985,9 +5640,7 @@ class CommandGuardianApprovalReviewAction(BaseModel): command: str cwd: AbsolutePathBuf source: GuardianCommandSource - type: Annotated[ - Literal["command"], Field(title="CommandGuardianApprovalReviewActionType") - ] + type: Annotated[Literal["command"], Field(title="CommandGuardianApprovalReviewActionType")] class ExecveGuardianApprovalReviewAction(BaseModel): @@ -5998,9 +5651,7 @@ class ExecveGuardianApprovalReviewAction(BaseModel): cwd: AbsolutePathBuf program: str source: GuardianCommandSource - type: Annotated[ - Literal["execve"], Field(title="ExecveGuardianApprovalReviewActionType") - ] + type: Annotated[Literal["execve"], Field(title="ExecveGuardianApprovalReviewActionType")] class NetworkAccessGuardianApprovalReviewAction(BaseModel): @@ -6012,8 +5663,7 @@ class NetworkAccessGuardianApprovalReviewAction(BaseModel): protocol: NetworkApprovalProtocol target: str type: Annotated[ - Literal["networkAccess"], - Field(title="NetworkAccessGuardianApprovalReviewActionType"), + Literal["networkAccess"], Field(title="NetworkAccessGuardianApprovalReviewActionType") ] @@ -6097,8 +5747,7 @@ class ListMcpServerStatusParams(BaseModel): populate_by_name=True, ) cursor: Annotated[ - str | None, - Field(description="Opaque pagination cursor returned by a previous call."), + str | None, Field(description="Opaque pagination cursor returned by a previous call.") ] = None detail: Annotated[ McpServerStatusDetail | None, @@ -6108,9 +5757,7 @@ class ListMcpServerStatusParams(BaseModel): ] = None limit: Annotated[ int | None, - Field( - description="Optional page size; defaults to a server-defined value.", ge=0 - ), + Field(description="Optional page size; defaults to a server-defined value.", ge=0), ] = None @@ -6127,9 +5774,7 @@ class McpServerStatus(BaseModel): ) auth_status: Annotated[McpAuthStatus, Field(alias="authStatus")] name: str - resource_templates: Annotated[ - list[ResourceTemplate], Field(alias="resourceTemplates") - ] + resource_templates: Annotated[list[ResourceTemplate], Field(alias="resourceTemplates")] resources: list[Resource] tools: dict[str, Tool] @@ -6148,9 +5793,7 @@ class MigrationDetails(BaseModel): ) commands: list[CommandMigration] | None = [] hooks: list[HookMigration] | None = [] - mcp_servers: Annotated[ - list[McpServerMigration] | None, Field(alias="mcpServers") - ] = [] + mcp_servers: Annotated[list[McpServerMigration] | None, Field(alias="mcpServers")] = [] plugins: list[PluginsMigration] | None = [] sessions: list[SessionMigration] | None = [] subagents: list[SubagentMigration] | None = [] @@ -6162,35 +5805,25 @@ class Model(BaseModel): ) additional_speed_tiers: Annotated[ list[str] | None, - Field( - alias="additionalSpeedTiers", - description="Deprecated: use `serviceTiers` instead.", - ), + Field(alias="additionalSpeedTiers", description="Deprecated: use `serviceTiers` instead."), ] = [] - availability_nux: Annotated[ - ModelAvailabilityNux | None, Field(alias="availabilityNux") - ] = None - default_reasoning_effort: Annotated[ - 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: Annotated[str, Field(alias="displayName")] hidden: bool id: str - input_modalities: Annotated[ - list[InputModality] | None, Field(alias="inputModalities") - ] = ["text", "image"] + input_modalities: Annotated[list[InputModality] | None, Field(alias="inputModalities")] = [ + "text", + "image", + ] is_default: Annotated[bool, Field(alias="isDefault")] model: str - service_tiers: Annotated[ - list[ModelServiceTier] | None, Field(alias="serviceTiers") - ] = [] + service_tiers: Annotated[list[ModelServiceTier] | None, Field(alias="serviceTiers")] = [] supported_reasoning_efforts: Annotated[ list[ReasoningEffortOption], Field(alias="supportedReasoningEfforts") ] - supports_personality: Annotated[bool | None, Field(alias="supportsPersonality")] = ( - False - ) + supports_personality: Annotated[bool | None, Field(alias="supportsPersonality")] = False upgrade: str | None = None upgrade_info: Annotated[ModelUpgradeInfo | None, Field(alias="upgradeInfo")] = None @@ -6231,12 +5864,9 @@ class RestrictedPermissionProfileFileSystemPermissions(BaseModel): populate_by_name=True, ) entries: list[FileSystemSandboxEntry] - glob_scan_max_depth: Annotated[ - int | None, Field(alias="globScanMaxDepth", ge=1) - ] = None + glob_scan_max_depth: Annotated[int | None, Field(alias="globScanMaxDepth", ge=1)] = None type: Annotated[ - Literal["restricted"], - Field(title="RestrictedPermissionProfileFileSystemPermissionsType"), + Literal["restricted"], Field(title="RestrictedPermissionProfileFileSystemPermissionsType") ] @@ -6350,9 +5980,7 @@ class WebSearchCallResponseItem(BaseModel): action: ResponsesApiWebSearchAction | None = None id: str | None = None status: str | None = None - type: Annotated[ - Literal["web_search_call"], Field(title="WebSearchCallResponseItemType") - ] + type: Annotated[Literal["web_search_call"], Field(title="WebSearchCallResponseItemType")] class ReviewStartParams(BaseModel): @@ -6374,8 +6002,7 @@ class ThreadStatusChangedServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["thread/status/changed"], - Field(title="Thread/status/changedNotificationMethod"), + Literal["thread/status/changed"], Field(title="Thread/status/changedNotificationMethod") ] params: ThreadStatusChangedNotification @@ -6384,9 +6011,7 @@ class ThreadArchivedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["thread/archived"], Field(title="Thread/archivedNotificationMethod") - ] + method: Annotated[Literal["thread/archived"], Field(title="Thread/archivedNotificationMethod")] params: ThreadArchivedNotification @@ -6404,9 +6029,7 @@ class ThreadClosedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["thread/closed"], Field(title="Thread/closedNotificationMethod") - ] + method: Annotated[Literal["thread/closed"], Field(title="Thread/closedNotificationMethod")] params: ThreadClosedNotification @@ -6414,9 +6037,7 @@ class SkillsChangedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["skills/changed"], Field(title="Skills/changedNotificationMethod") - ] + method: Annotated[Literal["skills/changed"], Field(title="Skills/changedNotificationMethod")] params: SkillsChangedNotification @@ -6425,8 +6046,7 @@ class ThreadNameUpdatedServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["thread/name/updated"], - Field(title="Thread/name/updatedNotificationMethod"), + Literal["thread/name/updated"], Field(title="Thread/name/updatedNotificationMethod") ] params: ThreadNameUpdatedNotification @@ -6436,8 +6056,7 @@ class ThreadGoalClearedServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["thread/goal/cleared"], - Field(title="Thread/goal/clearedNotificationMethod"), + Literal["thread/goal/cleared"], Field(title="Thread/goal/clearedNotificationMethod") ] params: ThreadGoalClearedNotification @@ -6446,9 +6065,7 @@ class HookStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["hook/started"], Field(title="Hook/startedNotificationMethod") - ] + method: Annotated[Literal["hook/started"], Field(title="Hook/startedNotificationMethod")] params: HookStartedNotification @@ -6478,8 +6095,7 @@ class ProcessOutputDeltaServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["process/outputDelta"], - Field(title="Process/outputDeltaNotificationMethod"), + Literal["process/outputDelta"], Field(title="Process/outputDeltaNotificationMethod") ] params: ProcessOutputDeltaNotification @@ -6500,8 +6116,7 @@ class ServerRequestResolvedServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["serverRequest/resolved"], - Field(title="ServerRequest/resolvedNotificationMethod"), + Literal["serverRequest/resolved"], Field(title="ServerRequest/resolvedNotificationMethod") ] params: ServerRequestResolvedNotification @@ -6510,9 +6125,7 @@ class AccountUpdatedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["account/updated"], Field(title="Account/updatedNotificationMethod") - ] + method: Annotated[Literal["account/updated"], Field(title="Account/updatedNotificationMethod")] params: AccountUpdatedNotification @@ -6528,9 +6141,7 @@ class ConfigWarningServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["configWarning"], Field(title="ConfigWarningNotificationMethod") - ] + method: Annotated[Literal["configWarning"], Field(title="ConfigWarningNotificationMethod")] params: ConfigWarningNotification @@ -6539,8 +6150,7 @@ class ThreadRealtimeStartedServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["thread/realtime/started"], - Field(title="Thread/realtime/startedNotificationMethod"), + Literal["thread/realtime/started"], Field(title="Thread/realtime/startedNotificationMethod") ] params: ThreadRealtimeStartedNotification @@ -6594,8 +6204,7 @@ class ThreadRealtimeSdpServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["thread/realtime/sdp"], - Field(title="Thread/realtime/sdpNotificationMethod"), + Literal["thread/realtime/sdp"], Field(title="Thread/realtime/sdpNotificationMethod") ] params: ThreadRealtimeSdpNotification @@ -6605,8 +6214,7 @@ class ThreadRealtimeErrorServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["thread/realtime/error"], - Field(title="Thread/realtime/errorNotificationMethod"), + Literal["thread/realtime/error"], Field(title="Thread/realtime/errorNotificationMethod") ] params: ThreadRealtimeErrorNotification @@ -6616,8 +6224,7 @@ class ThreadRealtimeClosedServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["thread/realtime/closed"], - Field(title="Thread/realtime/closedNotificationMethod"), + Literal["thread/realtime/closed"], Field(title="Thread/realtime/closedNotificationMethod") ] params: ThreadRealtimeClosedNotification @@ -6708,9 +6315,7 @@ class ThreadForkParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = ( - None - ) + approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = None approvals_reviewer: Annotated[ ApprovalsReviewer | None, Field( @@ -6721,13 +6326,10 @@ class ThreadForkParams(BaseModel): 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 + developer_instructions: Annotated[str | None, Field(alias="developerInstructions")] = None ephemeral: bool | None = None model: Annotated[ - str | None, - Field(description="Configuration overrides for the forked thread, if any."), + 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 @@ -6779,9 +6381,7 @@ class AgentMessageThreadItem(BaseModel): populate_by_name=True, ) id: str - memory_citation: Annotated[MemoryCitation | None, Field(alias="memoryCitation")] = ( - None - ) + memory_citation: Annotated[MemoryCitation | None, Field(alias="memoryCitation")] = None phase: MessagePhase | None = None text: str type: Annotated[Literal["agentMessage"], Field(title="AgentMessageThreadItemType")] @@ -6808,18 +6408,13 @@ class CollabAgentToolCallThreadItem(BaseModel): description="Last known status of the target agents, when available.", ), ] - id: Annotated[ - str, Field(description="Unique identifier for this collab tool call.") - ] + id: Annotated[str, Field(description="Unique identifier for this collab tool call.")] model: Annotated[ - str | None, - Field(description="Model requested for the spawned agent, when applicable."), + str | None, Field(description="Model requested for the spawned agent, when applicable.") ] = None prompt: Annotated[ str | None, - Field( - description="Prompt text sent as part of the collab tool call, when available." - ), + Field(description="Prompt text sent as part of the collab tool call, when available."), ] = None reasoning_effort: Annotated[ ReasoningEffort | None, @@ -6838,17 +6433,13 @@ class CollabAgentToolCallThreadItem(BaseModel): sender_thread_id: Annotated[ str, Field( - alias="senderThreadId", - description="Thread ID of the agent issuing the collab request.", + 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.") + 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") ] @@ -6918,8 +6509,7 @@ class ThreadListParams(BaseModel): ), ] = None cursor: Annotated[ - str | None, - Field(description="Opaque pagination cursor returned by a previous call."), + str | None, Field(description="Opaque pagination cursor returned by a previous call.") ] = None cwd: Annotated[ ThreadListCwdFilter | None, @@ -6929,10 +6519,7 @@ class ThreadListParams(BaseModel): ] = None limit: Annotated[ int | None, - Field( - description="Optional page size; defaults to a reasonable server-side value.", - ge=0, - ), + Field(description="Optional page size; defaults to a reasonable server-side value.", ge=0), ] = None model_providers: Annotated[ list[str] | None, @@ -6957,9 +6544,7 @@ class ThreadListParams(BaseModel): ] = None sort_key: Annotated[ ThreadSortKey | None, - Field( - alias="sortKey", description="Optional sort key; defaults to created_at." - ), + Field(alias="sortKey", description="Optional sort key; defaults to created_at."), ] = None source_kinds: Annotated[ list[ThreadSourceKind] | None, @@ -6981,9 +6566,7 @@ class ThreadStartParams(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = ( - None - ) + approval_policy: Annotated[AskForApproval | None, Field(alias="approvalPolicy")] = None approvals_reviewer: Annotated[ ApprovalsReviewer | None, Field( @@ -6994,9 +6577,7 @@ class ThreadStartParams(BaseModel): 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 + developer_instructions: Annotated[str | None, Field(alias="developerInstructions")] = None ephemeral: bool | None = None model: str | None = None model_provider: Annotated[str | None, Field(alias="modelProvider")] = None @@ -7004,9 +6585,9 @@ class ThreadStartParams(BaseModel): sandbox: SandboxMode | None = None service_name: Annotated[str | None, Field(alias="serviceName")] = None service_tier: Annotated[str | None, Field(alias="serviceTier")] = None - session_start_source: Annotated[ - ThreadStartSource | None, Field(alias="sessionStartSource") - ] = None + session_start_source: Annotated[ThreadStartSource | None, Field(alias="sessionStartSource")] = ( + None + ) thread_source: Annotated[ ThreadSource | None, Field( @@ -7021,9 +6602,7 @@ class ThreadTokenUsage(BaseModel): populate_by_name=True, ) last: TokenUsageBreakdown - model_context_window: Annotated[int | None, Field(alias="modelContextWindow")] = ( - None - ) + model_context_window: Annotated[int | None, Field(alias="modelContextWindow")] = None total: TokenUsageBreakdown @@ -7056,9 +6635,7 @@ class TurnError(BaseModel): populate_by_name=True, ) additional_details: Annotated[str | None, Field(alias="additionalDetails")] = None - codex_error_info: Annotated[ - CodexErrorInfo | None, Field(alias="codexErrorInfo") - ] = None + codex_error_info: Annotated[CodexErrorInfo | None, Field(alias="codexErrorInfo")] = None message: str @@ -7100,20 +6677,15 @@ class TurnStartParams(BaseModel): ] = None cwd: Annotated[ str | None, - Field( - description="Override the working directory for this turn and subsequent turns." - ), + 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." - ), + 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."), + str | None, Field(description="Override the model for this turn and subsequent turns.") ] = None output_schema: Annotated[ Any | None, @@ -7124,9 +6696,7 @@ class TurnStartParams(BaseModel): ] = None personality: Annotated[ Personality | None, - Field( - description="Override the personality for this turn and subsequent turns." - ), + Field(description="Override the personality for this turn and subsequent turns."), ] = None sandbox_policy: Annotated[ SandboxPolicy | None, @@ -7144,9 +6714,7 @@ class TurnStartParams(BaseModel): ] = None summary: Annotated[ ReasoningSummary | None, - Field( - description="Override the reasoning summary for this turn and subsequent turns." - ), + Field(description="Override the reasoning summary for this turn and subsequent turns."), ] = None thread_id: Annotated[str, Field(alias="threadId")] @@ -7187,9 +6755,7 @@ class AdditionalFileSystemPermissions(BaseModel): populate_by_name=True, ) entries: list[FileSystemSandboxEntry] | None = None - glob_scan_max_depth: Annotated[ - int | None, Field(alias="globScanMaxDepth", ge=1) - ] = None + glob_scan_max_depth: Annotated[int | None, Field(alias="globScanMaxDepth", ge=1)] = None read: Annotated[ list[AbsolutePathBuf] | None, Field(description="This will be removed in favor of `entries`."), @@ -7207,9 +6773,7 @@ class AppInfo(BaseModel): app_metadata: Annotated[AppMetadata | None, Field(alias="appMetadata")] = None branding: AppBranding | None = None description: str | None = None - distribution_channel: Annotated[str | None, Field(alias="distributionChannel")] = ( - None - ) + distribution_channel: Annotated[str | None, Field(alias="distributionChannel")] = None id: str install_url: Annotated[str | None, Field(alias="installUrl")] = None is_accessible: Annotated[bool | None, Field(alias="isAccessible")] = False @@ -7224,9 +6788,7 @@ class AppInfo(BaseModel): logo_url: Annotated[str | None, Field(alias="logoUrl")] = None logo_url_dark: Annotated[str | None, Field(alias="logoUrlDark")] = None name: str - plugin_display_names: Annotated[ - list[str] | None, Field(alias="pluginDisplayNames") - ] = [] + plugin_display_names: Annotated[list[str] | None, Field(alias="pluginDisplayNames")] = [] class AppListUpdatedNotification(BaseModel): @@ -7322,8 +6884,7 @@ class McpServerStatusListRequest(BaseModel): ) id: RequestId method: Annotated[ - Literal["mcpServerStatus/list"], - Field(title="McpServerStatus/listRequestMethod"), + Literal["mcpServerStatus/list"], Field(title="McpServerStatus/listRequestMethod") ] params: ListMcpServerStatusParams @@ -7353,9 +6914,7 @@ class ConfigValueWriteRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["config/value/write"], Field(title="Config/value/writeRequestMethod") - ] + method: Annotated[Literal["config/value/write"], Field(title="Config/value/writeRequestMethod")] params: ConfigValueWriteParams @@ -7387,14 +6946,11 @@ class ConfigWriteResponse(BaseModel): ) file_path: Annotated[ AbsolutePathBuf, - Field( - alias="filePath", - description="Canonical path to the config file that was written.", - ), + Field(alias="filePath", description="Canonical path to the config file that was written."), ] - overridden_metadata: Annotated[ - OverriddenMetadata | None, Field(alias="overriddenMetadata") - ] = None + overridden_metadata: Annotated[OverriddenMetadata | None, Field(alias="overriddenMetadata")] = ( + None + ) status: WriteStatus version: str @@ -7520,33 +7076,25 @@ class ManagedPermissionProfile(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - file_system: Annotated[ - PermissionProfileFileSystemPermissions, Field(alias="fileSystem") - ] + file_system: Annotated[PermissionProfileFileSystemPermissions, Field(alias="fileSystem")] network: PermissionProfileNetworkPermissions type: Annotated[Literal["managed"], Field(title="ManagedPermissionProfileType")] class PermissionProfile( - RootModel[ - ManagedPermissionProfile | DisabledPermissionProfile | ExternalPermissionProfile - ] + RootModel[ManagedPermissionProfile | DisabledPermissionProfile | ExternalPermissionProfile] ): model_config = ConfigDict( populate_by_name=True, ) - root: ( - ManagedPermissionProfile | DisabledPermissionProfile | ExternalPermissionProfile - ) + root: ManagedPermissionProfile | DisabledPermissionProfile | ExternalPermissionProfile class PluginShareContext(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - creator_account_user_id: Annotated[ - str | None, Field(alias="creatorAccountUserId") - ] = None + creator_account_user_id: Annotated[str | None, Field(alias="creatorAccountUserId")] = None creator_name: Annotated[str | None, Field(alias="creatorName")] = None discoverability: PluginShareDiscoverability | None = None remote_plugin_id: Annotated[str, Field(alias="remotePluginId")] @@ -7563,9 +7111,7 @@ class PluginShareSaveParams(BaseModel): discoverability: PluginShareDiscoverability | None = None plugin_path: Annotated[AbsolutePathBuf, Field(alias="pluginPath")] remote_plugin_id: Annotated[str | None, Field(alias="remotePluginId")] = None - share_targets: Annotated[ - list[PluginShareTarget] | None, Field(alias="shareTargets") - ] = None + share_targets: Annotated[list[PluginShareTarget] | None, Field(alias="shareTargets")] = None class PluginSummary(BaseModel): @@ -7622,9 +7168,7 @@ class RequestPermissionProfile(BaseModel): extra="forbid", populate_by_name=True, ) - file_system: Annotated[ - AdditionalFileSystemPermissions | None, Field(alias="fileSystem") - ] = None + file_system: Annotated[AdditionalFileSystemPermissions | None, Field(alias="fileSystem")] = None network: AdditionalNetworkPermissions | None = None @@ -7635,8 +7179,7 @@ class FunctionCallOutputResponseItem(BaseModel): call_id: str output: FunctionCallOutputBody type: Annotated[ - Literal["function_call_output"], - Field(title="FunctionCallOutputResponseItemType"), + Literal["function_call_output"], Field(title="FunctionCallOutputResponseItemType") ] @@ -7648,8 +7191,7 @@ class CustomToolCallOutputResponseItem(BaseModel): name: str | None = None output: FunctionCallOutputBody type: Annotated[ - Literal["custom_tool_call_output"], - Field(title="CustomToolCallOutputResponseItemType"), + Literal["custom_tool_call_output"], Field(title="CustomToolCallOutputResponseItemType") ] @@ -7705,8 +7247,7 @@ class ThreadGoalUpdatedServerNotification(BaseModel): populate_by_name=True, ) method: Annotated[ - Literal["thread/goal/updated"], - Field(title="Thread/goal/updatedNotificationMethod"), + Literal["thread/goal/updated"], Field(title="Thread/goal/updatedNotificationMethod") ] params: ThreadGoalUpdatedNotification @@ -7726,9 +7267,7 @@ class HookCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["hook/completed"], Field(title="Hook/completedNotificationMethod") - ] + method: Annotated[Literal["hook/completed"], Field(title="Hook/completedNotificationMethod")] params: HookCompletedNotification @@ -7746,9 +7285,7 @@ class ItemStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["item/started"], Field(title="Item/startedNotificationMethod") - ] + method: Annotated[Literal["item/started"], Field(title="Item/startedNotificationMethod")] params: ItemStartedNotification @@ -7756,9 +7293,7 @@ class ItemCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["item/completed"], Field(title="Item/completedNotificationMethod") - ] + method: Annotated[Literal["item/completed"], Field(title="Item/completedNotificationMethod")] params: ItemCompletedNotification @@ -7813,9 +7348,7 @@ class SubAgentSessionSource(BaseModel): sub_agent: Annotated[SubAgentSource, Field(alias="subAgent")] -class SessionSource( - RootModel[SessionSourceValue | CustomSessionSource | SubAgentSessionSource] -): +class SessionSource(RootModel[SessionSourceValue | CustomSessionSource | SubAgentSessionSource]): model_config = ConfigDict( populate_by_name=True, ) @@ -7829,8 +7362,7 @@ class Turn(BaseModel): completed_at: Annotated[ int | None, Field( - alias="completedAt", - description="Unix timestamp (in seconds) when the turn completed.", + alias="completedAt", description="Unix timestamp (in seconds) when the turn completed." ), ] = None duration_ms: Annotated[ @@ -7841,13 +7373,11 @@ class Turn(BaseModel): ), ] = None error: Annotated[ - TurnError | None, - Field(description="Only populated when the Turn's status is failed."), + TurnError | None, Field(description="Only populated when the Turn's status is failed.") ] = None id: str items: Annotated[ - list[ThreadItem], - Field(description="Thread items currently included in this turn payload."), + list[ThreadItem], Field(description="Thread items currently included in this turn payload.") ] items_view: Annotated[ TurnItemsView | None, @@ -7858,10 +7388,7 @@ class Turn(BaseModel): ] = "full" started_at: Annotated[ int | None, - Field( - alias="startedAt", - description="Unix timestamp (in seconds) when the turn started.", - ), + Field(alias="startedAt", description="Unix timestamp (in seconds) when the turn started."), ] = None status: TurnStatus @@ -7894,9 +7421,7 @@ class PluginShareSaveRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["plugin/share/save"], Field(title="Plugin/share/saveRequestMethod") - ] + method: Annotated[Literal["plugin/share/save"], Field(title="Plugin/share/saveRequestMethod")] params: PluginShareSaveParams @@ -7905,9 +7430,7 @@ class ConfigBatchWriteRequest(BaseModel): populate_by_name=True, ) id: RequestId - method: Annotated[ - Literal["config/batchWrite"], Field(title="Config/batchWriteRequestMethod") - ] + method: Annotated[Literal["config/batchWrite"], Field(title="Config/batchWriteRequestMethod")] params: ConfigBatchWriteParams @@ -8076,9 +7599,7 @@ class PluginDetail(BaseModel): description: str | None = None hooks: list[PluginHookSummary] marketplace_name: Annotated[str, Field(alias="marketplaceName")] - marketplace_path: Annotated[ - AbsolutePathBuf | None, Field(alias="marketplacePath") - ] = None + marketplace_path: Annotated[AbsolutePathBuf | None, Field(alias="marketplacePath")] = None mcp_servers: Annotated[list[str], Field(alias="mcpServers")] skills: list[SkillSummary] summary: PluginSummary @@ -8110,9 +7631,7 @@ class PluginShareListItem(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - local_plugin_path: Annotated[ - AbsolutePathBuf | None, Field(alias="localPluginPath") - ] = None + local_plugin_path: Annotated[AbsolutePathBuf | None, Field(alias="localPluginPath")] = None plugin: PluginSummary @@ -8150,9 +7669,7 @@ class TurnStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["turn/started"], Field(title="Turn/startedNotificationMethod") - ] + method: Annotated[Literal["turn/started"], Field(title="Turn/startedNotificationMethod")] params: TurnStartedNotification @@ -8160,9 +7677,7 @@ class TurnCompletedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["turn/completed"], Field(title="Turn/completedNotificationMethod") - ] + method: Annotated[Literal["turn/completed"], Field(title="Turn/completedNotificationMethod")] params: TurnCompletedNotification @@ -8207,11 +7722,7 @@ class Thread(BaseModel): ), ] = None cli_version: Annotated[ - str, - Field( - alias="cliVersion", - description="Version of the CLI that created the thread.", - ), + str, Field(alias="cliVersion", description="Version of the CLI that created the thread.") ] created_at: Annotated[ int, @@ -8220,9 +7731,7 @@ class Thread(BaseModel): description="Unix timestamp (in seconds) when the thread was created.", ), ] - cwd: Annotated[ - AbsolutePathBuf, Field(description="Working directory captured for the thread.") - ] + cwd: Annotated[AbsolutePathBuf, Field(description="Working directory captured for the thread.")] ephemeral: Annotated[ bool, Field( @@ -8251,17 +7760,10 @@ class Thread(BaseModel): 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 + 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." - ), + str, Field(description="Usually the first user message in the thread, if available.") ] session_id: Annotated[ str, @@ -8276,9 +7778,7 @@ class Thread(BaseModel): description="Origin of the thread (CLI, VSCode, codex exec, codex app-server, etc.)." ), ] - status: Annotated[ - ThreadStatus, Field(description="Current runtime status for the thread.") - ] + status: Annotated[ThreadStatus, Field(description="Current runtime status for the thread.")] thread_source: Annotated[ ThreadSource | None, Field( @@ -8323,9 +7823,7 @@ class ThreadForkResponse(BaseModel): ] = [] model: str model_provider: Annotated[str, Field(alias="modelProvider")] - reasoning_effort: Annotated[ - ReasoningEffort | None, Field(alias="reasoningEffort") - ] = None + reasoning_effort: Annotated[ReasoningEffort | None, Field(alias="reasoningEffort")] = None sandbox: Annotated[ SandboxPolicy, Field( @@ -8393,9 +7891,7 @@ class ThreadResumeResponse(BaseModel): ] = [] model: str model_provider: Annotated[str, Field(alias="modelProvider")] - reasoning_effort: Annotated[ - ReasoningEffort | None, Field(alias="reasoningEffort") - ] = None + reasoning_effort: Annotated[ReasoningEffort | None, Field(alias="reasoningEffort")] = None sandbox: Annotated[ SandboxPolicy, Field( @@ -8440,9 +7936,7 @@ class ThreadStartResponse(BaseModel): ] = [] model: str model_provider: Annotated[str, Field(alias="modelProvider")] - reasoning_effort: Annotated[ - ReasoningEffort | None, Field(alias="reasoningEffort") - ] = None + reasoning_effort: Annotated[ReasoningEffort | None, Field(alias="reasoningEffort")] = None sandbox: Annotated[ SandboxPolicy, Field( @@ -8637,9 +8131,7 @@ class ClientRequest( | ConfigRequirementsReadRequest | AccountReadRequest | FuzzyFileSearchRequest, - Field( - description="Request from the client to the server.", title="ClientRequest" - ), + Field(description="Request from the client to the server.", title="ClientRequest"), ] @@ -8647,9 +8139,7 @@ class PluginListResponse(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - featured_plugin_ids: Annotated[ - list[str] | None, Field(alias="featuredPluginIds") - ] = [] + featured_plugin_ids: Annotated[list[str] | None, Field(alias="featuredPluginIds")] = [] marketplace_load_errors: Annotated[ list[MarketplaceLoadErrorInfo] | None, Field(alias="marketplaceLoadErrors") ] = [] @@ -8660,9 +8150,7 @@ class ThreadStartedServerNotification(BaseModel): model_config = ConfigDict( populate_by_name=True, ) - method: Annotated[ - Literal["thread/started"], Field(title="Thread/startedNotificationMethod") - ] + method: Annotated[Literal["thread/started"], Field(title="Thread/startedNotificationMethod")] params: ThreadStartedNotification diff --git a/sdk/python/tests/app_server_harness.py b/sdk/python/tests/app_server_harness.py index 6fb0f608be..26fa8cf7ef 100644 --- a/sdk/python/tests/app_server_harness.py +++ b/sdk/python/tests/app_server_harness.py @@ -12,7 +12,6 @@ from typing import Any from openai_codex import AppServerConfig - Json = dict[str, Any] diff --git a/sdk/python/tests/app_server_helpers.py b/sdk/python/tests/app_server_helpers.py index e11390d527..10db00901c 100644 --- a/sdk/python/tests/app_server_helpers.py +++ b/sdk/python/tests/app_server_helpers.py @@ -11,6 +11,7 @@ from app_server_harness import ( ev_response_created, sse, ) + from openai_codex.generated.v2_all import ( AgentMessageDeltaNotification, ItemCompletedNotification, diff --git a/sdk/python/tests/test_app_server_approvals.py b/sdk/python/tests/test_app_server_approvals.py index 61e5703dd7..bc8c36a6bf 100644 --- a/sdk/python/tests/test_app_server_approvals.py +++ b/sdk/python/tests/test_app_server_approvals.py @@ -3,9 +3,10 @@ from __future__ import annotations import asyncio from app_server_harness import AppServerHarness +from app_server_helpers import response_approval_policy + from openai_codex import ApprovalMode, AsyncCodex, Codex from openai_codex.generated.v2_all import AskForApprovalValue, ThreadResumeParams -from app_server_helpers import response_approval_policy def test_thread_resume_inherits_deny_all_approval_mode(tmp_path) -> None: diff --git a/sdk/python/tests/test_app_server_inputs.py b/sdk/python/tests/test_app_server_inputs.py index 5e560062e5..56505e4817 100644 --- a/sdk/python/tests/test_app_server_inputs.py +++ b/sdk/python/tests/test_app_server_inputs.py @@ -1,9 +1,10 @@ from __future__ import annotations from app_server_harness import AppServerHarness -from openai_codex import Codex, ImageInput, LocalImageInput, SkillInput, TextInput from app_server_helpers import TINY_PNG_BYTES +from openai_codex import Codex, ImageInput, LocalImageInput, SkillInput, TextInput + def test_remote_image_input_reaches_responses_api( tmp_path, @@ -28,8 +29,7 @@ def test_remote_image_input_reaches_responses_api( assert { "final_response": result.final_response, - "contains_user_prompt": "Describe the remote image." - in request.message_input_texts("user"), + "contains_user_prompt": "Describe the remote image." in request.message_input_texts("user"), "image_urls": request.message_image_urls("user"), } == { "final_response": "remote image received", @@ -62,8 +62,7 @@ def test_local_image_input_reaches_responses_api( assert { "final_response": result.final_response, - "contains_user_prompt": "Describe the local image." - in request.message_input_texts("user"), + "contains_user_prompt": "Describe the local image." in request.message_input_texts("user"), "image_url_is_png_data_url": request.message_image_urls("user")[-1].startswith( "data:image/png;base64," ), @@ -81,9 +80,7 @@ def test_skill_input_injects_loaded_skill_body(tmp_path) -> None: with AppServerHarness(tmp_path) as harness: skill_file = harness.workspace / ".agents" / "skills" / "demo" / "SKILL.md" skill_file.parent.mkdir(parents=True) - skill_file.write_text( - f"---\nname: demo\ndescription: demo skill\n---\n\n{skill_body}\n" - ) + skill_file.write_text(f"---\nname: demo\ndescription: demo skill\n---\n\n{skill_body}\n") skill_path = skill_file.resolve() harness.responses.enqueue_assistant_message( "skill received", @@ -100,9 +97,7 @@ def test_skill_input_injects_loaded_skill_body(tmp_path) -> None: request = harness.responses.single_request() skill_blocks = [ - text - for text in request.message_input_texts("user") - if text.startswith("") + text for text in request.message_input_texts("user") if text.startswith("") ] assert { "final_response": result.final_response, diff --git a/sdk/python/tests/test_app_server_lifecycle.py b/sdk/python/tests/test_app_server_lifecycle.py index 644b97585a..0baddccc57 100644 --- a/sdk/python/tests/test_app_server_lifecycle.py +++ b/sdk/python/tests/test_app_server_lifecycle.py @@ -3,9 +3,10 @@ from __future__ import annotations import asyncio from app_server_harness import AppServerHarness -from openai_codex import AsyncCodex, Codex from app_server_helpers import request_kind +from openai_codex import AsyncCodex, Codex + def _thread_message_summary(read_response) -> list[tuple[str, str]]: """Return persisted user/agent messages from a thread read response.""" @@ -58,9 +59,7 @@ def test_thread_list_filters_archived_threads(tmp_path) -> None: expected_ids = {active_thread.id, archived_thread.id} assert { - "active_ids": sorted( - thread.id for thread in active_list.data if thread.id in expected_ids - ), + "active_ids": sorted(thread.id for thread in active_list.data if thread.id in expected_ids), "archived_ids": sorted( thread.id for thread in archived_list.data if thread.id in expected_ids ), diff --git a/sdk/python/tests/test_app_server_run.py b/sdk/python/tests/test_app_server_run.py index 8a45edf5ef..a0ac3eca16 100644 --- a/sdk/python/tests/test_app_server_run.py +++ b/sdk/python/tests/test_app_server_run.py @@ -3,7 +3,6 @@ from __future__ import annotations import asyncio import pytest - from app_server_harness import ( AppServerHarness, ev_assistant_message, @@ -13,13 +12,14 @@ from app_server_harness import ( ev_response_created, sse, ) -from openai_codex import AsyncCodex, Codex -from openai_codex.generated.v2_all import MessagePhase from app_server_helpers import ( agent_message_texts_from_items, assistant_message_with_phase, ) +from openai_codex import AsyncCodex, Codex +from openai_codex.generated.v2_all import MessagePhase + def test_sync_thread_run_uses_mock_responses( tmp_path, @@ -250,9 +250,7 @@ def test_async_run_result_uses_last_unknown_phase_message(tmp_path) -> None: ) async with AsyncCodex(config=harness.app_server_config()) as codex: - result = await (await codex.thread_start()).run( - "case: async last unknown phase" - ) + result = await (await codex.thread_start()).run("case: async last unknown phase") assert { "final_response": result.final_response, @@ -288,9 +286,7 @@ def test_async_run_result_does_not_promote_commentary_only_to_final( ) async with AsyncCodex(config=harness.app_server_config()) as codex: - result = await (await codex.thread_start()).run( - "case: async commentary only" - ) + result = await (await codex.thread_start()).run("case: async commentary only") assert { "final_response": result.final_response, diff --git a/sdk/python/tests/test_app_server_streaming.py b/sdk/python/tests/test_app_server_streaming.py index 81e2b44d30..ae217adb6a 100644 --- a/sdk/python/tests/test_app_server_streaming.py +++ b/sdk/python/tests/test_app_server_streaming.py @@ -3,12 +3,6 @@ from __future__ import annotations import asyncio from app_server_harness import AppServerHarness -from openai_codex import AsyncCodex, Codex, TextInput -from openai_codex.generated.v2_all import ( - AgentMessageDeltaNotification, - TurnCompletedNotification, - TurnStatus, -) from app_server_helpers import ( agent_message_texts, next_async_delta, @@ -16,13 +10,18 @@ from app_server_helpers import ( streaming_response, ) +from openai_codex import AsyncCodex, Codex, TextInput +from openai_codex.generated.v2_all import ( + AgentMessageDeltaNotification, + TurnCompletedNotification, + TurnStatus, +) + def test_sync_stream_routes_text_deltas_and_completion(tmp_path) -> None: """A sync turn stream should expose deltas, completed items, and completion.""" with AppServerHarness(tmp_path) as harness: - harness.responses.enqueue_sse( - streaming_response("stream-1", "msg-stream-1", ["hel", "lo"]) - ) + harness.responses.enqueue_sse(streaming_response("stream-1", "msg-stream-1", ["he", "llo"])) with Codex(config=harness.app_server_config()) as codex: thread = codex.thread_start() @@ -42,7 +41,7 @@ def test_sync_stream_routes_text_deltas_and_completion(tmp_path) -> None: if isinstance(event.payload, TurnCompletedNotification) ], } == { - "deltas": ["hel", "lo"], + "deltas": ["he", "llo"], "agent_messages": ["hello"], "completed_statuses": [TurnStatus.completed], } diff --git a/sdk/python/tests/test_app_server_turn_controls.py b/sdk/python/tests/test_app_server_turn_controls.py index 40ada74ea3..af02f6b74f 100644 --- a/sdk/python/tests/test_app_server_turn_controls.py +++ b/sdk/python/tests/test_app_server_turn_controls.py @@ -1,9 +1,10 @@ from __future__ import annotations from app_server_harness import AppServerHarness +from app_server_helpers import agent_message_texts, streaming_response + from openai_codex import Codex, TextInput from openai_codex.generated.v2_all import TurnStatus -from app_server_helpers import agent_message_texts, streaming_response def test_turn_steer_adds_follow_up_input(tmp_path) -> None: @@ -30,9 +31,7 @@ def test_turn_steer_adds_follow_up_input(tmp_path) -> None: "steered_turn_id": steer.turn_id, "turn_id": turn.id, "agent_messages": agent_message_texts(events), - "last_user_texts": [ - request.message_input_texts("user")[-1] for request in requests - ], + "last_user_texts": [request.message_input_texts("user")[-1] for request in requests], } == { "steered_turn_id": turn.id, "turn_id": turn.id, diff --git a/sdk/python/tests/test_artifact_workflow_and_binaries.py b/sdk/python/tests/test_artifact_workflow_and_binaries.py index 8cc30f06fd..4a8e4df4d1 100644 --- a/sdk/python/tests/test_artifact_workflow_and_binaries.py +++ b/sdk/python/tests/test_artifact_workflow_and_binaries.py @@ -5,12 +5,12 @@ import importlib.util import io import json import sys -import tomllib import urllib.error from pathlib import Path from typing import Sequence import pytest +import tomllib ROOT = Path(__file__).resolve().parents[1] @@ -32,9 +32,7 @@ def _load_runtime_setup_module(): runtime_setup_path = ROOT / "_runtime_setup.py" spec = importlib.util.spec_from_file_location("_runtime_setup", runtime_setup_path) if spec is None or spec.loader is None: - raise AssertionError( - f"Failed to load runtime setup module: {runtime_setup_path}" - ) + raise AssertionError(f"Failed to load runtime setup module: {runtime_setup_path}") module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) @@ -47,6 +45,40 @@ def test_generation_has_single_maintenance_entrypoint_script() -> None: assert scripts == ["update_sdk_artifacts.py"] +def test_root_fmt_recipe_formats_rust_and_python_sdk() -> None: + """The repo fmt command should work from Rust and Python SDK directories.""" + justfile = ROOT.parents[1] / "justfile" + lines = justfile.read_text().splitlines() + fmt_index = lines.index("fmt:") + next_recipe_index = next( + index + for index in range(fmt_index + 1, len(lines)) + if lines[index] and not lines[index].startswith((" ", "\t", "#")) + ) + fmt_recipe = lines[fmt_index:next_recipe_index] + actual = { + "working_directory": lines[0], + "previous_attribute": lines[fmt_index - 1], + "commands": [line.strip() for line in fmt_recipe[1:] if line.strip()], + } + expected = { + "working_directory": 'set working-directory := "codex-rs"', + "previous_attribute": "# Format Rust and Python SDK code.", + "commands": [ + "cargo fmt -- --config imports_granularity=Item 2>/dev/null", + "uv run --project ../sdk/python --extra dev ruff check --fix --fix-only ../sdk/python", + "uv run --project ../sdk/python --extra dev ruff format ../sdk/python", + ], + } + + assert actual == expected, ( + "The root `just fmt` recipe must run Rust fmt and Python SDK Ruff. " + "Fix the `fmt` recipe in `justfile`, then run `just fmt`.\n" + f"Expected: {json.dumps(expected, indent=2)}\n" + f"Actual: {json.dumps(actual, indent=2)}" + ) + + def test_generate_types_wires_all_generation_steps() -> None: """The type generation command should refresh every schema-derived artifact.""" source = (ROOT / "scripts" / "update_sdk_artifacts.py").read_text() @@ -56,8 +88,7 @@ def test_generate_types_wires_all_generation_steps() -> None: ( node for node in tree.body - if isinstance(node, ast.FunctionDef) - and node.name == "generate_types_from_schema_dir" + if isinstance(node, ast.FunctionDef) and node.name == "generate_types_from_schema_dir" ), None, ) @@ -94,8 +125,7 @@ def test_schema_normalization_only_flattens_string_literal_oneofs( flattened = [ name for name, definition in definitions.items() - if isinstance(definition, dict) - and script._flatten_string_enum_one_of(definition.copy()) + if isinstance(definition, dict) and script._flatten_string_enum_one_of(definition.copy()) ] assert flattened == [ @@ -172,8 +202,7 @@ def test_examples_readme_points_to_runtime_version_source_of_truth() -> None: def test_runtime_distribution_name_is_consistent() -> None: script = _load_update_script_module() runtime_setup = _load_runtime_setup_module() - from openai_codex import client as client_module - from openai_codex import _version + from openai_codex import _version, client as client_module assert script.SDK_DISTRIBUTION_NAME == "openai-codex" assert runtime_setup.SDK_PACKAGE_NAME == "openai-codex" @@ -232,22 +261,6 @@ def test_release_metadata_retries_without_invalid_auth( assert authorizations == ["Bearer invalid-token", None] -def test_source_sdk_package_pins_published_runtime() -> None: - """The source package metadata should pin the runtime wheel that ships schemas.""" - pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text()) - - assert { - "sdk_version": pyproject["project"]["version"], - "dependencies": pyproject["project"]["dependencies"], - } == { - "sdk_version": "0.131.0a4", - "dependencies": [ - "pydantic>=2.12", - "openai-codex-cli-bin==0.131.0a4", - ], - } - - def test_runtime_setup_uses_pep440_package_version_and_codex_release_tags() -> None: """The SDK uses PEP 440 package pins and converts only when fetching releases.""" runtime_setup = _load_runtime_setup_module() @@ -259,17 +272,12 @@ def test_runtime_setup_uses_pep440_package_version_and_codex_release_tags() -> N f"{runtime_setup.PACKAGE_NAME}=={pyproject['project']['version']}" in pyproject["project"]["dependencies"] ) - assert ( - runtime_setup._normalized_package_version("rust-v0.116.0-alpha.1") - == "0.116.0a1" - ) + assert runtime_setup._normalized_package_version("rust-v0.116.0-alpha.1") == "0.116.0a1" assert runtime_setup._release_tag("0.116.0a1") == "rust-v0.116.0-alpha.1" def test_runtime_package_is_wheel_only_and_builds_platform_specific_wheels() -> None: - pyproject = tomllib.loads( - (ROOT.parent / "python-runtime" / "pyproject.toml").read_text() - ) + 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( @@ -411,9 +419,7 @@ def test_stage_runtime_release_copies_resource_binaries(tmp_path: Path) -> None: ) assert { - path.relative_to( - staged / "src" / "codex_cli_bin" / "bin" - ).as_posix(): path.read_text() + path.relative_to(staged / "src" / "codex_cli_bin" / "bin").as_posix(): path.read_text() for path in (staged / "src" / "codex_cli_bin" / "bin").iterdir() } == { script.runtime_binary_name(): "fake codex\n", @@ -502,9 +508,7 @@ def test_staged_sdk_and_runtime_versions_match(tmp_path: Path) -> None: sdk_pyproject = tomllib.loads((sdk_stage / "pyproject.toml").read_text()) runtime_pyproject = tomllib.loads((runtime_stage / "pyproject.toml").read_text()) - assert ( - sdk_pyproject["project"]["version"] == runtime_pyproject["project"]["version"] - ) + assert sdk_pyproject["project"]["version"] == runtime_pyproject["project"]["version"] assert sdk_pyproject["project"]["dependencies"] == [ "pydantic>=2.12", "openai-codex-cli-bin==0.116.0a1", @@ -629,9 +633,7 @@ def test_stage_runtime_stages_binary_without_type_generation(tmp_path: Path) -> script.run_command(args, ops) - assert calls == [ - "stage_runtime:0.116.0a1:musllinux_1_1_x86_64:helper,fallback-helper" - ] + assert calls == ["stage_runtime:0.116.0a1:musllinux_1_1_x86_64:helper,fallback-helper"] def test_default_runtime_is_resolved_from_installed_runtime_package( diff --git a/sdk/python/tests/test_async_client_behavior.py b/sdk/python/tests/test_async_client_behavior.py index 4e48fbbfee..662d0a2716 100644 --- a/sdk/python/tests/test_async_client_behavior.py +++ b/sdk/python/tests/test_async_client_behavior.py @@ -12,6 +12,7 @@ from openai_codex.models import Notification, UnknownNotification def test_async_client_allows_concurrent_transport_calls() -> None: """Async wrappers should offload sync calls so concurrent awaits can overlap.""" + async def scenario() -> int: """Run two blocking sync calls and report peak overlap.""" client = AsyncAppServerClient() @@ -36,6 +37,7 @@ def test_async_client_allows_concurrent_transport_calls() -> None: def test_async_client_turn_notification_methods_delegate_to_sync_client() -> None: """Async turn routing methods should preserve sync-client registration semantics.""" + async def scenario() -> tuple[list[tuple[str, str]], Notification, str]: """Record the sync-client calls made by async turn notification wrappers.""" client = AsyncAppServerClient() diff --git a/sdk/python/tests/test_client_rpc_methods.py b/sdk/python/tests/test_client_rpc_methods.py index f2c5020d55..0a11774baa 100644 --- a/sdk/python/tests/test_client_rpc_methods.py +++ b/sdk/python/tests/test_client_rpc_methods.py @@ -111,9 +111,7 @@ def test_unknown_notifications_fall_back_to_unknown_payloads() -> None: def test_invalid_notification_payload_falls_back_to_unknown() -> None: client = AppServerClient() - event = client._coerce_notification( - "thread/tokenUsage/updated", {"threadId": "missing"} - ) + event = client._coerce_notification("thread/tokenUsage/updated", {"threadId": "missing"}) assert event.method == "thread/tokenUsage/updated" assert isinstance(event.payload, UnknownNotification) diff --git a/sdk/python/tests/test_contract_generation.py b/sdk/python/tests/test_contract_generation.py index 142a68c9a0..f809d05294 100644 --- a/sdk/python/tests/test_contract_generation.py +++ b/sdk/python/tests/test_contract_generation.py @@ -31,10 +31,7 @@ def _snapshot_target(root: Path, rel_path: Path) -> dict[str, bytes] | bytes | N def _snapshot_targets(root: Path) -> dict[str, dict[str, bytes] | bytes | None]: """Capture all checked-in generated artifacts before and after regeneration.""" - return { - str(rel_path): _snapshot_target(root, rel_path) - for rel_path in GENERATED_TARGETS - } + return {str(rel_path): _snapshot_target(root, rel_path) for rel_path in GENERATED_TARGETS} def test_generated_files_are_up_to_date(): diff --git a/sdk/python/tests/test_public_api_runtime_behavior.py b/sdk/python/tests/test_public_api_runtime_behavior.py index fb52da59b3..4e79cb6104 100644 --- a/sdk/python/tests/test_public_api_runtime_behavior.py +++ b/sdk/python/tests/test_public_api_runtime_behavior.py @@ -7,13 +7,13 @@ from typing import Any import pytest import openai_codex.api as public_api_module -from openai_codex.generated.v2_all import TurnStartParams -from openai_codex.models import InitializeResponse from openai_codex.api import ( ApprovalMode, AsyncCodex, Codex, ) +from openai_codex.generated.v2_all import TurnStartParams +from openai_codex.models import InitializeResponse ROOT = Path(__file__).resolve().parents[1] @@ -129,9 +129,7 @@ def test_async_codex_initializes_only_once_under_concurrency() -> None: def _approval_mode_turn_params(approval_mode: ApprovalMode) -> TurnStartParams: """Build real generated turn params from one public approval mode.""" - approval_policy, approvals_reviewer = public_api_module._approval_mode_settings( - approval_mode - ) + approval_policy, approvals_reviewer = public_api_module._approval_mode_settings(approval_mode) return TurnStartParams( thread_id="thread-1", input=[], diff --git a/sdk/python/tests/test_public_api_signatures.py b/sdk/python/tests/test_public_api_signatures.py index f17ec5d4fc..f38c2b8c94 100644 --- a/sdk/python/tests/test_public_api_signatures.py +++ b/sdk/python/tests/test_public_api_signatures.py @@ -2,15 +2,16 @@ from __future__ import annotations import importlib.resources as resources import inspect -import tomllib from pathlib import Path from typing import Any +import tomllib + import openai_codex import openai_codex.types as public_types from openai_codex import ( - AppServerConfig, ApprovalMode, + AppServerConfig, AsyncCodex, AsyncThread, Codex, @@ -107,9 +108,7 @@ def _assert_no_any_annotations(fn: object) -> None: signature = inspect.signature(fn) for param in signature.parameters.values(): if param.annotation is Any: - raise AssertionError( - f"{fn} has public parameter typed as Any: {param.name}" - ) + raise AssertionError(f"{fn} has public parameter typed as Any: {param.name}") if signature.return_annotation is Any: raise AssertionError(f"{fn} has public return annotation typed as Any") @@ -150,9 +149,9 @@ def test_package_includes_py_typed_marker() -> None: def test_package_root_exports_only_public_api() -> None: """The package root should expose the supported SDK surface, not internals.""" assert openai_codex.__all__ == EXPECTED_ROOT_EXPORTS - assert {name: hasattr(openai_codex, name) for name in EXPECTED_ROOT_EXPORTS} == { - name: True for name in EXPECTED_ROOT_EXPORTS - } + assert {name: hasattr(openai_codex, name) for name in EXPECTED_ROOT_EXPORTS} == dict.fromkeys( + EXPECTED_ROOT_EXPORTS, True + ) assert { "AppServerClient": hasattr(openai_codex, "AppServerClient"), "AsyncAppServerClient": hasattr(openai_codex, "AsyncAppServerClient"), @@ -184,9 +183,9 @@ def test_package_star_import_matches_public_api() -> None: def test_types_module_exports_curated_public_types() -> None: """The public type module should be the supported place for app-server models.""" assert public_types.__all__ == EXPECTED_TYPES_EXPORTS - assert {name: hasattr(public_types, name) for name in EXPECTED_TYPES_EXPORTS} == { - name: True for name in EXPECTED_TYPES_EXPORTS - } + assert {name: hasattr(public_types, name) for name in EXPECTED_TYPES_EXPORTS} == dict.fromkeys( + EXPECTED_TYPES_EXPORTS, True + ) def test_types_star_import_matches_public_types() -> None: @@ -390,9 +389,9 @@ def test_new_thread_methods_default_to_auto_review() -> None: AsyncCodex.thread_start, ] - assert {fn: _keyword_default(fn, "approval_mode") for fn in funcs} == { - fn: ApprovalMode.auto_review for fn in funcs - } + assert {fn: _keyword_default(fn, "approval_mode") for fn in funcs} == dict.fromkeys( + funcs, ApprovalMode.auto_review + ) def test_existing_thread_methods_default_to_preserving_approval_settings() -> None: @@ -408,9 +407,7 @@ def test_existing_thread_methods_default_to_preserving_approval_settings() -> No AsyncThread.run, ] - assert {fn: _keyword_default(fn, "approval_mode") for fn in funcs} == { - fn: None for fn in funcs - } + assert {fn: _keyword_default(fn, "approval_mode") for fn in funcs} == dict.fromkeys(funcs) def test_lifecycle_methods_are_codex_scoped() -> None: @@ -462,6 +459,4 @@ def test_initialize_metadata_requires_non_empty_information() -> None: except RuntimeError as exc: assert "missing required metadata" in str(exc) else: - raise AssertionError( - "expected RuntimeError when initialize metadata is missing" - ) + raise AssertionError("expected RuntimeError when initialize metadata is missing") diff --git a/sdk/python/tests/test_real_app_server_integration.py b/sdk/python/tests/test_real_app_server_integration.py index 262c0289fe..292ba9632a 100644 --- a/sdk/python/tests/test_real_app_server_integration.py +++ b/sdk/python/tests/test_real_app_server_integration.py @@ -539,7 +539,9 @@ def test_real_examples_run_and_assert( assert "actions:" in out assert "Items:" in out elif folder == "13_model_select_and_turn_params": - assert "selected.model:" in out and "agent.message.params:" in out and "items.params:" in out + assert ( + "selected.model:" in out and "agent.message.params:" in out and "items.params:" in out + ) elif folder == "14_turn_controls": assert "steer.result:" in out and "steer.final.status:" in out assert "interrupt.result:" in out and "interrupt.final.status:" in out diff --git a/sdk/python/uv.lock b/sdk/python/uv.lock index 6752310310..1bec43ba56 100644 --- a/sdk/python/uv.lock +++ b/sdk/python/uv.lock @@ -302,7 +302,7 @@ requires-dist = [ { name = "openai-codex-cli-bin", specifier = "==0.131.0a4" }, { name = "pydantic", specifier = ">=2.12" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" }, - { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.11" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15.8" }, ] provides-extras = ["dev"]