Skip to content
4 changes: 2 additions & 2 deletions src/openai/types/beta/beta_response_function_web_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class ActionFindInPage(BaseModel):
type: Literal["find_in_page"]
"""The action type."""

url: str
"""The URL of the page searched for the pattern."""
url: Optional[str] = None
"""The URL of the page searched for the pattern, when provided."""


Action: TypeAlias = Annotated[Union[ActionSearch, ActionOpenPage, ActionFindInPage], PropertyInfo(discriminator="type")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class ActionFindInPage(TypedDict, total=False):
type: Required[Literal["find_in_page"]]
"""The action type."""

url: Required[str]
"""The URL of the page searched for the pattern."""
url: Optional[str]
"""The URL of the page searched for the pattern, when provided."""


Action: TypeAlias = Union[ActionSearch, ActionOpenPage, ActionFindInPage]
Expand Down
4 changes: 2 additions & 2 deletions src/openai/types/responses/response_function_web_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ class ActionFind(BaseModel):
type: Literal["find_in_page"]
"""The action type."""

url: str
"""The URL of the page searched for the pattern."""
url: Optional[str] = None
"""The URL of the page searched for the pattern, when provided."""


Action: TypeAlias = Annotated[Union[ActionSearch, ActionOpenPage, ActionFind], PropertyInfo(discriminator="type")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class ActionFind(TypedDict, total=False):
type: Required[Literal["find_in_page"]]
"""The action type."""

url: Required[str]
"""The URL of the page searched for the pattern."""
url: Optional[str]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep present URLs non-nullable

The reported API discrepancy is that url may be omitted, not that a present url may be null; the checked-in contract still defines it as a non-null string URI in api_reference/openapi.transformed.yml:60837-60841. Because this TypedDict already has total=False, declaring url: str makes the key optional while continuing to reject None; using Optional[str] instead exposes null as a valid request value to type-checked callers even though the API may reject it. The beta parameter type has the same problem.

Useful? React with 👍 / 👎.

"""The URL of the page searched for the pattern, when provided."""


Action: TypeAlias = Union[ActionSearch, ActionOpenPage, ActionFind]
Expand Down
30 changes: 30 additions & 0 deletions tests/test_web_search_action_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from openai._compat import model_parse
from openai.types.beta.beta_response_function_web_search import BetaResponseFunctionWebSearch
from openai.types.beta.beta_response_function_web_search_param import ActionFindInPage as BetaActionFindParam
from openai.types.responses.response_function_web_search import ResponseFunctionWebSearch
from openai.types.responses.response_function_web_search_param import ActionFind as ActionFindParam


def _find_payload() -> dict[str, object]:
return {
"id": "ws_test",
"type": "web_search_call",
"status": "completed",
"action": {"type": "find_in_page", "pattern": "og:image"},
}


def test_find_in_page_action_allows_missing_url() -> None:
item = model_parse(ResponseFunctionWebSearch, _find_payload())

assert item.action.type == "find_in_page"
assert item.action.url is None
assert "url" not in ActionFindParam.__required_keys__

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exercise optional keys without __required_keys__

This assertion does not verify the intended TypedDict change: both parameter modules use postponed annotations, so typing_extensions records Required[str] as a forward reference and __required_keys__ omits url even with the old broken url: Required[str] declaration. The beta assertion has the same false-positive behavior; add a statically checked assignment that omits url, or resolve and inspect the annotation, so reverting the parameter fix would actually fail validation.

Useful? React with 👍 / 👎.



def test_beta_find_in_page_action_allows_missing_url() -> None:
item = model_parse(BetaResponseFunctionWebSearch, _find_payload())

assert item.action.type == "find_in_page"
assert item.action.url is None
assert "url" not in BetaActionFindParam.__required_keys__