Add Python SDK thread.run convenience methods (#15088)

## TL;DR
Add `thread.run(...)` / `async thread.run(...)` convenience methods to
the Python SDK for the common case.

- add `RunInput = Input | str` and `RunResult` with `final_response`,
collected `items`, and optional `usage`
- keep `thread.turn(...)` strict and lower-level for streaming,
steering, interrupting, and raw generated `Turn` access
- update Python SDK docs, quickstart examples, and tests for the sync
and async convenience flows

## Validation
- `python3 -m pytest sdk/python/tests/test_public_api_signatures.py
sdk/python/tests/test_public_api_runtime_behavior.py`
- `python3 -m pytest
sdk/python/tests/test_real_app_server_integration.py -k
'thread_run_convenience or async_thread_run_convenience'` (skipped in
this environment)

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Shaqayeq
2026-03-18 17:57:48 -07:00
committed by GitHub
parent 825d09373d
commit 4fd2774614
12 changed files with 760 additions and 103 deletions

View File

@@ -4,7 +4,7 @@ import importlib.resources as resources
import inspect
from typing import Any
from codex_app_server import AppServerConfig
from codex_app_server import AppServerConfig, RunResult
from codex_app_server.models import InitializeResponse
from codex_app_server.api import AsyncCodex, AsyncThread, Codex, Thread
@@ -31,6 +31,10 @@ def test_root_exports_app_server_config() -> None:
assert AppServerConfig.__name__ == "AppServerConfig"
def test_root_exports_run_result() -> None:
assert RunResult.__name__ == "RunResult"
def test_package_includes_py_typed_marker() -> None:
marker = resources.files("codex_app_server").joinpath("py.typed")
assert marker.is_file()
@@ -101,6 +105,18 @@ def test_generated_public_signatures_are_snake_case_and_typed() -> None:
"service_tier",
"summary",
],
Thread.run: [
"approval_policy",
"approvals_reviewer",
"cwd",
"effort",
"model",
"output_schema",
"personality",
"sandbox_policy",
"service_tier",
"summary",
],
AsyncCodex.thread_start: [
"approval_policy",
"approvals_reviewer",
@@ -164,6 +180,18 @@ def test_generated_public_signatures_are_snake_case_and_typed() -> None:
"service_tier",
"summary",
],
AsyncThread.run: [
"approval_policy",
"approvals_reviewer",
"cwd",
"effort",
"model",
"output_schema",
"personality",
"sandbox_policy",
"service_tier",
"summary",
],
}
for fn, expected_kwargs in expected.items():