mirror of
https://github.com/openai/codex.git
synced 2026-05-23 20:44:50 +00:00
[codex] Split Python SDK helper logic (#22939)
## Summary - Move approval-mode mapping into `sdk/python/src/openai_codex/_approval_mode.py`. - Move initialize metadata parsing and normalization into `sdk/python/src/openai_codex/_initialize_metadata.py`. - Keep the public `ApprovalMode` export stable and retarget direct metadata helper coverage. ## Integration coverage - Add an app-server harness smoke that exercises sync and async SDK initialization plus thread creation. ## Validation - Local tests were not run per repo guidance. CI should validate this branch once the PR is online.
This commit is contained in:
@@ -39,6 +39,61 @@ def test_thread_set_name_and_read(tmp_path) -> None:
|
||||
}
|
||||
|
||||
|
||||
def test_sync_and_async_initialization_round_trip_metadata(tmp_path) -> None:
|
||||
"""Public clients should initialize and start threads through app-server."""
|
||||
|
||||
async def async_scenario(harness: AppServerHarness) -> dict[str, object]:
|
||||
async with AsyncCodex(config=harness.app_server_config()) as codex:
|
||||
thread = await codex.thread_start()
|
||||
server = codex.metadata.serverInfo
|
||||
return {
|
||||
"thread_id": thread.id,
|
||||
"user_agent": codex.metadata.userAgent,
|
||||
"server_name": None if server is None else server.name,
|
||||
"server_version": None if server is None else server.version,
|
||||
}
|
||||
|
||||
with AppServerHarness(tmp_path) as harness:
|
||||
with Codex(config=harness.app_server_config()) as codex:
|
||||
thread = codex.thread_start()
|
||||
server = codex.metadata.serverInfo
|
||||
sync_summary = {
|
||||
"thread_id": thread.id,
|
||||
"user_agent": codex.metadata.userAgent,
|
||||
"server_name": None if server is None else server.name,
|
||||
"server_version": None if server is None else server.version,
|
||||
}
|
||||
async_summary = asyncio.run(async_scenario(harness))
|
||||
|
||||
assert {
|
||||
"sync": {
|
||||
"thread_id_present": bool(sync_summary["thread_id"]),
|
||||
"user_agent_present": bool(sync_summary["user_agent"]),
|
||||
"server_name_present": bool(sync_summary["server_name"]),
|
||||
"server_version_present": bool(sync_summary["server_version"]),
|
||||
},
|
||||
"async": {
|
||||
"thread_id_present": bool(async_summary["thread_id"]),
|
||||
"user_agent_present": bool(async_summary["user_agent"]),
|
||||
"server_name_present": bool(async_summary["server_name"]),
|
||||
"server_version_present": bool(async_summary["server_version"]),
|
||||
},
|
||||
} == {
|
||||
"sync": {
|
||||
"thread_id_present": True,
|
||||
"user_agent_present": True,
|
||||
"server_name_present": True,
|
||||
"server_version_present": True,
|
||||
},
|
||||
"async": {
|
||||
"thread_id_present": True,
|
||||
"user_agent_present": True,
|
||||
"server_name_present": True,
|
||||
"server_version_present": True,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def test_thread_list_filters_archived_threads(tmp_path) -> None:
|
||||
"""Thread listing should reflect archive state through app-server."""
|
||||
with AppServerHarness(tmp_path) as harness:
|
||||
|
||||
@@ -18,6 +18,7 @@ from openai_codex import (
|
||||
RunResult,
|
||||
Thread,
|
||||
)
|
||||
from openai_codex._initialize_metadata import validate_initialize_metadata
|
||||
from openai_codex.types import InitializeResponse
|
||||
|
||||
EXPECTED_ROOT_EXPORTS = [
|
||||
@@ -444,7 +445,7 @@ def test_lifecycle_methods_are_codex_scoped() -> None:
|
||||
def test_initialize_metadata_parses_user_agent_shape() -> None:
|
||||
"""Initialize metadata should accept the legacy user-agent-only payload shape."""
|
||||
payload = InitializeResponse.model_validate({"userAgent": "codex-cli/1.2.3"})
|
||||
parsed = Codex._validate_initialize(payload)
|
||||
parsed = validate_initialize_metadata(payload)
|
||||
assert parsed is payload
|
||||
assert parsed.userAgent == "codex-cli/1.2.3"
|
||||
assert parsed.serverInfo is not None
|
||||
@@ -455,7 +456,7 @@ def test_initialize_metadata_parses_user_agent_shape() -> None:
|
||||
def test_initialize_metadata_requires_non_empty_information() -> None:
|
||||
"""Initialize metadata should fail when the runtime gives no identity signal."""
|
||||
try:
|
||||
Codex._validate_initialize(InitializeResponse.model_validate({}))
|
||||
validate_initialize_metadata(InitializeResponse.model_validate({}))
|
||||
except RuntimeError as exc:
|
||||
assert "missing required metadata" in str(exc)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user