mirror of
https://github.com/openai/codex.git
synced 2026-10-30 19:18:49 +00:00
Refactor image content to use a shared ImageReference type (#45543)
## What changed Represent images in `ContentItem` and `FunctionCallOutputContentItem` with `ImageReference::Inline`, flattened to preserve the existing `image_url` wire format. Update image producers and consumers and regenerate app-server schemas and SDK artifacts. Preserve the Python SDK's `InputImageContentItem` and `InputImageFunctionCallOutputContentItem` class names during generation. ## Testing Add a regression test for stable Python image class names and adapt existing image tests to the shared representation. GitOrigin-RevId: c38a780ac3314c2ac2deb3afc1b93b94b6f93fec
This commit is contained in:
committed by
copyberry
parent
6ae5e71458
commit
5a66d460d3
@@ -575,6 +575,7 @@ def generate_v2_all(schema_dir: Path) -> None:
|
||||
],
|
||||
cwd=sdk_root(),
|
||||
)
|
||||
_preserve_inline_image_class_names(out_path)
|
||||
_require_nullable_chatgpt_account_email(out_path)
|
||||
_preserve_reasoning_effort_enum(out_path)
|
||||
_preserve_thread_source_enum(out_path)
|
||||
@@ -582,6 +583,23 @@ def generate_v2_all(schema_dir: Path) -> None:
|
||||
_normalize_generated_timestamps(out_path)
|
||||
|
||||
|
||||
def _preserve_inline_image_class_names(out_path: Path) -> None:
|
||||
"""Keep the public class names used before ImageReference was introduced."""
|
||||
source = out_path.read_text()
|
||||
stable_names = {
|
||||
"ImageUrlContentItem": "InputImageContentItem",
|
||||
"ImageUrlFunctionCallOutputContentItem": "InputImageFunctionCallOutputContentItem",
|
||||
}
|
||||
for generated_name, stable_name in stable_names.items():
|
||||
if source.count(f"class {generated_name}(") != 1:
|
||||
raise RuntimeError(f"Generated SDK is missing a unique {generated_name} class")
|
||||
if re.search(rf"\b{re.escape(stable_name)}\b", source):
|
||||
raise RuntimeError(f"Generated SDK already defines {stable_name}")
|
||||
source = re.sub(rf"\b{re.escape(generated_name)}\b", stable_name, source)
|
||||
|
||||
out_path.write_text(source)
|
||||
|
||||
|
||||
def _require_nullable_chatgpt_account_email(out_path: Path) -> None:
|
||||
"""Preserve required-but-nullable email semantics in the generated SDK model."""
|
||||
source = out_path.read_text()
|
||||
|
||||
@@ -7784,8 +7784,8 @@ class InputImageContentItem(BaseModel):
|
||||
populate_by_name=True,
|
||||
)
|
||||
detail: ImageDetail | None = None
|
||||
image_url: str
|
||||
type: Annotated[Literal["input_image"], Field(title="InputImageContentItemType")]
|
||||
image_url: str
|
||||
|
||||
|
||||
class ContentItem(
|
||||
@@ -7796,9 +7796,7 @@ class ContentItem(
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
)
|
||||
root: (
|
||||
InputTextContentItem | InputImageContentItem | InputAudioContentItem | OutputTextContentItem
|
||||
)
|
||||
root: InputTextContentItem | InputImageContentItem | InputAudioContentItem | OutputTextContentItem
|
||||
|
||||
|
||||
class ExperimentalFeature(BaseModel):
|
||||
@@ -7980,10 +7978,10 @@ class InputImageFunctionCallOutputContentItem(BaseModel):
|
||||
populate_by_name=True,
|
||||
)
|
||||
detail: ImageDetail | None = None
|
||||
image_url: str
|
||||
type: Annotated[
|
||||
Literal["input_image"], Field(title="InputImageFunctionCallOutputContentItemType")
|
||||
]
|
||||
image_url: str
|
||||
|
||||
|
||||
class FunctionCallOutputContentItem(
|
||||
|
||||
@@ -536,6 +536,20 @@ def test_generated_chatgpt_account_email_is_required_nullable() -> None:
|
||||
ChatgptAccount.model_validate({"planType": "pro", "type": "chatgpt"})
|
||||
|
||||
|
||||
def test_generated_inline_image_class_names_remain_stable() -> None:
|
||||
"""Keep the existing Python class names when image references expand."""
|
||||
from openai_codex.generated.v2_all import (
|
||||
InputImageContentItem,
|
||||
InputImageFunctionCallOutputContentItem,
|
||||
)
|
||||
|
||||
assert InputImageContentItem.__name__ == "InputImageContentItem"
|
||||
assert (
|
||||
InputImageFunctionCallOutputContentItem.__name__
|
||||
== "InputImageFunctionCallOutputContentItem"
|
||||
)
|
||||
|
||||
|
||||
def test_runtime_package_template_has_no_checked_in_binaries() -> None:
|
||||
runtime_root = ROOT.parent / "python-runtime" / "src" / "codex_cli_bin"
|
||||
assert sorted(
|
||||
|
||||
Reference in New Issue
Block a user