diff --git a/.release-please-manifest.json b/.release-please-manifest.json index de61293b..54ee57dc 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.19.2" + ".": "3.19.3" } diff --git a/.stats.yml b/.stats.yml index 129faad5..ac9e78a6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 8 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-bc309fd00fe0507f4cbe3bc77fa27d0fbffeaa6e71998778da34de42608a67e8.yml -openapi_spec_hash: 1db1af5c1b068bba1d652102f4454668 -config_hash: d6c6f623d03971bdba921650e5eb7e5f +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/browserbase%2Fstagehand-b969ce378479c79ee64c05127c0ed6c6ce2edbee017ecd037242fb618a5ebc9f.yml +openapi_spec_hash: a24aabaa5214effb679808b7f2be0ad4 +config_hash: a962ae71493deb11a1c903256fb25386 diff --git a/CHANGELOG.md b/CHANGELOG.md index 66a47f95..584d6fb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 3.19.3 (2026-04-03) + +Full Changelog: [v3.19.2...v3.19.3](https://github.com/browserbase/stagehand-python/compare/v3.19.2...v3.19.3) + +### Features + +* Replace default model used in server-v3 api spec examples ([fb347d2](https://github.com/browserbase/stagehand-python/commit/fb347d256fea9453c9eb23d935558bd43405f934)) + ## 3.19.2 (2026-04-03) Full Changelog: [v3.19.1...v3.19.2](https://github.com/browserbase/stagehand-python/compare/v3.19.1...v3.19.2) diff --git a/pyproject.toml b/pyproject.toml index cbade981..7853f99b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "stagehand" -version = "3.19.2" +version = "3.19.3" description = "The official Python library for the stagehand API" dynamic = ["readme"] license = "MIT" diff --git a/src/stagehand/_version.py b/src/stagehand/_version.py index 26a036e4..37c72699 100644 --- a/src/stagehand/_version.py +++ b/src/stagehand/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "stagehand" -__version__ = "3.19.2" # x-release-please-version +__version__ = "3.19.3" # x-release-please-version diff --git a/tests/api_resources/test_sessions.py b/tests/api_resources/test_sessions.py index 65125733..8dfddbe2 100644 --- a/tests/api_resources/test_sessions.py +++ b/tests/api_resources/test_sessions.py @@ -44,7 +44,7 @@ def test_method_act_with_all_params_overload_1(self, client: Stagehand) -> None: frame_id="frameId", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -121,7 +121,7 @@ def test_method_act_with_all_params_overload_2(self, client: Stagehand) -> None: frame_id="frameId", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -250,7 +250,7 @@ def test_method_execute_with_all_params_overload_1(self, client: Stagehand) -> N agent_config={ "cua": True, "execution_model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -258,7 +258,7 @@ def test_method_execute_with_all_params_overload_1(self, client: Stagehand) -> N }, "mode": "cua", "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -348,7 +348,7 @@ def test_method_execute_with_all_params_overload_2(self, client: Stagehand) -> N agent_config={ "cua": True, "execution_model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -356,7 +356,7 @@ def test_method_execute_with_all_params_overload_2(self, client: Stagehand) -> N }, "mode": "cua", "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -444,7 +444,7 @@ def test_method_extract_with_all_params_overload_1(self, client: Stagehand) -> N instruction="Extract all product names and prices from the page", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -512,7 +512,7 @@ def test_method_extract_with_all_params_overload_2(self, client: Stagehand) -> N instruction="Extract all product names and prices from the page", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -642,7 +642,7 @@ def test_method_observe_with_all_params_overload_1(self, client: Stagehand) -> N instruction="Find all clickable navigation links", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -716,7 +716,7 @@ def test_method_observe_with_all_params_overload_2(self, client: Stagehand) -> N instruction="Find all clickable navigation links", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -827,7 +827,7 @@ def test_path_params_replay(self, client: Stagehand) -> None: @parametrize def test_method_start(self, client: Stagehand) -> None: session = client.sessions.start( - model_name="openai/gpt-4o", + model_name="openai/gpt-5.4-mini", ) assert_matches_type(SessionStartResponse, session, path=["response"]) @@ -835,7 +835,7 @@ def test_method_start(self, client: Stagehand) -> None: @parametrize def test_method_start_with_all_params(self, client: Stagehand) -> None: session = client.sessions.start( - model_name="openai/gpt-4o", + model_name="openai/gpt-5.4-mini", act_timeout_ms=0, browser={ "cdp_url": "ws://localhost:9222", @@ -924,7 +924,7 @@ def test_method_start_with_all_params(self, client: Stagehand) -> None: @parametrize def test_raw_response_start(self, client: Stagehand) -> None: response = client.sessions.with_raw_response.start( - model_name="openai/gpt-4o", + model_name="openai/gpt-5.4-mini", ) assert response.is_closed is True @@ -936,7 +936,7 @@ def test_raw_response_start(self, client: Stagehand) -> None: @parametrize def test_streaming_response_start(self, client: Stagehand) -> None: with client.sessions.with_streaming_response.start( - model_name="openai/gpt-4o", + model_name="openai/gpt-5.4-mini", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -970,7 +970,7 @@ async def test_method_act_with_all_params_overload_1(self, async_client: AsyncSt frame_id="frameId", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1047,7 +1047,7 @@ async def test_method_act_with_all_params_overload_2(self, async_client: AsyncSt frame_id="frameId", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1176,7 +1176,7 @@ async def test_method_execute_with_all_params_overload_1(self, async_client: Asy agent_config={ "cua": True, "execution_model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1184,7 +1184,7 @@ async def test_method_execute_with_all_params_overload_1(self, async_client: Asy }, "mode": "cua", "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1274,7 +1274,7 @@ async def test_method_execute_with_all_params_overload_2(self, async_client: Asy agent_config={ "cua": True, "execution_model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1282,7 +1282,7 @@ async def test_method_execute_with_all_params_overload_2(self, async_client: Asy }, "mode": "cua", "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1370,7 +1370,7 @@ async def test_method_extract_with_all_params_overload_1(self, async_client: Asy instruction="Extract all product names and prices from the page", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1438,7 +1438,7 @@ async def test_method_extract_with_all_params_overload_2(self, async_client: Asy instruction="Extract all product names and prices from the page", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1568,7 +1568,7 @@ async def test_method_observe_with_all_params_overload_1(self, async_client: Asy instruction="Find all clickable navigation links", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1642,7 +1642,7 @@ async def test_method_observe_with_all_params_overload_2(self, async_client: Asy instruction="Find all clickable navigation links", options={ "model": { - "model_name": "openai/gpt-5-nano", + "model_name": "openai/gpt-5.4-mini", "api_key": "sk-some-openai-api-key", "base_url": "https://api.openai.com/v1", "headers": {"foo": "string"}, @@ -1753,7 +1753,7 @@ async def test_path_params_replay(self, async_client: AsyncStagehand) -> None: @parametrize async def test_method_start(self, async_client: AsyncStagehand) -> None: session = await async_client.sessions.start( - model_name="openai/gpt-4o", + model_name="openai/gpt-5.4-mini", ) assert_matches_type(SessionStartResponse, session, path=["response"]) @@ -1761,7 +1761,7 @@ async def test_method_start(self, async_client: AsyncStagehand) -> None: @parametrize async def test_method_start_with_all_params(self, async_client: AsyncStagehand) -> None: session = await async_client.sessions.start( - model_name="openai/gpt-4o", + model_name="openai/gpt-5.4-mini", act_timeout_ms=0, browser={ "cdp_url": "ws://localhost:9222", @@ -1850,7 +1850,7 @@ async def test_method_start_with_all_params(self, async_client: AsyncStagehand) @parametrize async def test_raw_response_start(self, async_client: AsyncStagehand) -> None: response = await async_client.sessions.with_raw_response.start( - model_name="openai/gpt-4o", + model_name="openai/gpt-5.4-mini", ) assert response.is_closed is True @@ -1862,7 +1862,7 @@ async def test_raw_response_start(self, async_client: AsyncStagehand) -> None: @parametrize async def test_streaming_response_start(self, async_client: AsyncStagehand) -> None: async with async_client.sessions.with_streaming_response.start( - model_name="openai/gpt-4o", + model_name="openai/gpt-5.4-mini", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/test_client.py b/tests/test_client.py index 42cb3374..e962cdba 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1009,7 +1009,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, clien respx_mock.post("/v1/sessions/start").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - client.sessions.with_streaming_response.start(model_name="openai/gpt-4o").__enter__() + client.sessions.with_streaming_response.start(model_name="openai/gpt-5.4-mini").__enter__() assert _get_open_connections(client) == 0 @@ -1019,7 +1019,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client respx_mock.post("/v1/sessions/start").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - client.sessions.with_streaming_response.start(model_name="openai/gpt-4o").__enter__() + client.sessions.with_streaming_response.start(model_name="openai/gpt-5.4-mini").__enter__() assert _get_open_connections(client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -1048,7 +1048,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v1/sessions/start").mock(side_effect=retry_handler) - response = client.sessions.with_raw_response.start(model_name="openai/gpt-4o") + response = client.sessions.with_raw_response.start(model_name="openai/gpt-5.4-mini") assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -1073,7 +1073,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v1/sessions/start").mock(side_effect=retry_handler) response = client.sessions.with_raw_response.start( - model_name="openai/gpt-4o", extra_headers={"x-stainless-retry-count": Omit()} + model_name="openai/gpt-5.4-mini", extra_headers={"x-stainless-retry-count": Omit()} ) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -1098,7 +1098,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v1/sessions/start").mock(side_effect=retry_handler) response = client.sessions.with_raw_response.start( - model_name="openai/gpt-4o", extra_headers={"x-stainless-retry-count": "42"} + model_name="openai/gpt-5.4-mini", extra_headers={"x-stainless-retry-count": "42"} ) assert response.http_request.headers.get("x-stainless-retry-count") == "42" @@ -2063,7 +2063,7 @@ async def test_retrying_timeout_errors_doesnt_leak( respx_mock.post("/v1/sessions/start").mock(side_effect=httpx.TimeoutException("Test timeout error")) with pytest.raises(APITimeoutError): - await async_client.sessions.with_streaming_response.start(model_name="openai/gpt-4o").__aenter__() + await async_client.sessions.with_streaming_response.start(model_name="openai/gpt-5.4-mini").__aenter__() assert _get_open_connections(async_client) == 0 @@ -2075,7 +2075,7 @@ async def test_retrying_status_errors_doesnt_leak( respx_mock.post("/v1/sessions/start").mock(return_value=httpx.Response(500)) with pytest.raises(APIStatusError): - await async_client.sessions.with_streaming_response.start(model_name="openai/gpt-4o").__aenter__() + await async_client.sessions.with_streaming_response.start(model_name="openai/gpt-5.4-mini").__aenter__() assert _get_open_connections(async_client) == 0 @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @@ -2104,7 +2104,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v1/sessions/start").mock(side_effect=retry_handler) - response = await client.sessions.with_raw_response.start(model_name="openai/gpt-4o") + response = await client.sessions.with_raw_response.start(model_name="openai/gpt-5.4-mini") assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success @@ -2129,7 +2129,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v1/sessions/start").mock(side_effect=retry_handler) response = await client.sessions.with_raw_response.start( - model_name="openai/gpt-4o", extra_headers={"x-stainless-retry-count": Omit()} + model_name="openai/gpt-5.4-mini", extra_headers={"x-stainless-retry-count": Omit()} ) assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 @@ -2154,7 +2154,7 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: respx_mock.post("/v1/sessions/start").mock(side_effect=retry_handler) response = await client.sessions.with_raw_response.start( - model_name="openai/gpt-4o", extra_headers={"x-stainless-retry-count": "42"} + model_name="openai/gpt-5.4-mini", extra_headers={"x-stainless-retry-count": "42"} ) assert response.http_request.headers.get("x-stainless-retry-count") == "42"