Files
codex/sdk/python/docs/faq.md
Shaqayeq 6baeec68bd python-sdk: generated type foundation (all v2 schemas) (#13953)
## Summary
Foundation PR only (base for PR #3).

This PR contains the SDK runtime foundation and generated artifacts:

- pinned runtime binary in `sdk/python/bin/` (`codex` or `codex.exe` by
platform)
- single maintenance script:
`sdk/python/scripts/update_sdk_artifacts.py`
- generated protocol/types artifacts under:
  - `sdk/python/src/codex_app_server/generated/protocol_types.py`
  - `sdk/python/src/codex_app_server/generated/schema_types.py`
  - `sdk/python/src/codex_app_server/generated/v2_all/*`
- generation-contract test wiring (`tests/test_contract_generation.py`)

## Release asset behavior
`update_sdk_artifacts.py` now:
- selects latest release by channel (`--channel stable|alpha`)
- resolves the correct asset for current OS/arch
- extracts platform binary (`codex` on macOS/Linux, `codex.exe` on
Windows)
- keeps runtime on single pinned binary source in `sdk/python/bin/`

## Scope boundary
-  PR #2 = binary + generation pipeline + generated types foundation
-  PR #2 does **not** include examples/integration logic polish (that
is PR #3)

## Validation
- Ran: `python scripts/update_sdk_artifacts.py --channel stable`
- Regenerated and committed resulting generated artifacts
- Local tests pass on branch
2026-03-10 01:00:46 -07:00

2.3 KiB

FAQ

Thread vs turn

  • A Thread is conversation state.
  • A Turn is one model execution inside that thread.
  • Multi-turn chat means multiple turns on the same Thread.

run() vs stream()

  • Turn.run() is the easiest path. It consumes events until completion and returns TurnResult.
  • Turn.stream() yields raw notifications (Notification) so you can react event-by-event.

Choose run() for most apps. Choose stream() for progress UIs, custom timeout logic, or custom parsing.

Sync vs async clients

  • Codex is the minimal sync SDK and best default.
  • AsyncAppServerClient wraps the sync transport with asyncio.to_thread(...) for async-friendly call sites.

If your app is not already async, stay with Codex.

thread(...) vs thread_resume(...)

  • codex.thread(thread_id) only binds a local helper to an existing thread ID.
  • codex.thread_resume(thread_id, ...) performs a thread/resume RPC and can apply overrides (model, instructions, sandbox, etc.).

Use thread(...) for simple continuation. Use thread_resume(...) when you need explicit resume semantics or override fields.

Why does constructor fail?

Codex() is eager: it starts transport and calls initialize in __init__.

Common causes:

  • bundled runtime binary missing for your OS/arch under src/codex_app_server/bin/*
  • local auth/session is missing
  • incompatible/old app-server

Maintainers can refresh bundled binaries with:

cd sdk/python
python scripts/update_sdk_artifacts.py --channel stable --bundle-all-platforms

Why does a turn "hang"?

A turn is complete only when turn/completed arrives for that turn ID.

  • run() waits for this automatically.
  • With stream(), make sure you keep consuming notifications until completion.

How do I retry safely?

Use retry_on_overload(...) for transient overload failures (ServerBusyError).

Do not blindly retry all errors. For InvalidParamsError or MethodNotFoundError, fix inputs/version compatibility instead.

Common pitfalls

  • Starting a new thread for every prompt when you wanted continuity.
  • Forgetting to close() (or not using with Codex() as codex:).
  • Ignoring TurnResult.status and TurnResult.error.
  • Mixing SDK input classes with raw dicts incorrectly in minimal API paths.