diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index caf5ca3..59acac4 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.26.0"
+ ".": "0.27.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 2857ba8..9ec6fcc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 91
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-fc2c80b398a8dd511010ae7cda5e21c353e388ee130aa288974b47af4208b5b8.yml
-openapi_spec_hash: 5e06586dbbb9fce12b907f4e32497006
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-59d2925a3cb93809cc762a3ac350691b365898e284f2c66a5999b9a6a37a35e5.yml
+openapi_spec_hash: dfcb0a49e657426d0c0f44cfa3e89430
config_hash: cc7fdd701d995d4b3456d77041c604cf
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 09a63d3..2fc4eb9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.27.0 (2026-01-19)
+
+Full Changelog: [v0.26.0...v0.27.0](https://github.com/kernel/kernel-python-sdk/compare/v0.26.0...v0.27.0)
+
+### Features
+
+* **dashboard:** add browser replays support for past browsers ([9d81781](https://github.com/kernel/kernel-python-sdk/commit/9d81781970ed6230844d479bc27893453b34a05e))
+
## 0.26.0 (2026-01-17)
Full Changelog: [v0.25.0...v0.26.0](https://github.com/kernel/kernel-python-sdk/compare/v0.25.0...v0.26.0)
diff --git a/api.md b/api.md
index 51f8cdb..a665bc2 100644
--- a/api.md
+++ b/api.md
@@ -89,7 +89,7 @@ from kernel.types import (
Methods:
- client.browsers.create(\*\*params) -> BrowserCreateResponse
-- client.browsers.retrieve(id) -> BrowserRetrieveResponse
+- client.browsers.retrieve(id, \*\*params) -> BrowserRetrieveResponse
- client.browsers.update(id, \*\*params) -> BrowserUpdateResponse
- client.browsers.list(\*\*params) -> SyncOffsetPagination[BrowserListResponse]
- client.browsers.delete(\*\*params) -> None
diff --git a/pyproject.toml b/pyproject.toml
index cad7dd2..7ac03dc 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "kernel"
-version = "0.26.0"
+version = "0.27.0"
description = "The official Python library for the kernel API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/kernel/_version.py b/src/kernel/_version.py
index 0c46e78..b962ca5 100644
--- a/src/kernel/_version.py
+++ b/src/kernel/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "kernel"
-__version__ = "0.26.0" # x-release-please-version
+__version__ = "0.27.0" # x-release-please-version
diff --git a/src/kernel/resources/browsers/browsers.py b/src/kernel/resources/browsers/browsers.py
index ab57854..d835f7a 100644
--- a/src/kernel/resources/browsers/browsers.py
+++ b/src/kernel/resources/browsers/browsers.py
@@ -4,6 +4,7 @@
import typing_extensions
from typing import Mapping, Iterable, Optional, cast
+from typing_extensions import Literal
import httpx
@@ -28,6 +29,7 @@
browser_create_params,
browser_delete_params,
browser_update_params,
+ browser_retrieve_params,
browser_load_extensions_params,
)
from .process import (
@@ -226,6 +228,7 @@ def retrieve(
self,
id: str,
*,
+ include_deleted: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -237,6 +240,8 @@ def retrieve(
Get information about a browser session.
Args:
+ include_deleted: When true, includes soft-deleted browser sessions in the lookup.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -250,7 +255,13 @@ def retrieve(
return self._get(
f"/browsers/{id}",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"include_deleted": include_deleted}, browser_retrieve_params.BrowserRetrieveParams
+ ),
),
cast_to=BrowserRetrieveResponse,
)
@@ -300,6 +311,7 @@ def list(
include_deleted: bool | Omit = omit,
limit: int | Omit = omit,
offset: int | Omit = omit,
+ status: Literal["active", "deleted", "all"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -309,17 +321,20 @@ def list(
) -> SyncOffsetPagination[BrowserListResponse]:
"""List all browser sessions with pagination support.
- Use include_deleted=true to
- include soft-deleted sessions in the results.
+ Use status parameter to
+ filter by session state.
Args:
- include_deleted: When true, includes soft-deleted browser sessions in the results alongside
- active sessions.
+ include_deleted: Deprecated: Use status=all instead. When true, includes soft-deleted browser
+ sessions in the results alongside active sessions.
limit: Maximum number of results to return. Defaults to 20, maximum 100.
offset: Number of results to skip. Defaults to 0.
+ status: Filter sessions by status. "active" returns only active sessions (default),
+ "deleted" returns only soft-deleted sessions, "all" returns both.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -341,6 +356,7 @@ def list(
"include_deleted": include_deleted,
"limit": limit,
"offset": offset,
+ "status": status,
},
browser_list_params.BrowserListParams,
),
@@ -610,6 +626,7 @@ async def retrieve(
self,
id: str,
*,
+ include_deleted: bool | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -621,6 +638,8 @@ async def retrieve(
Get information about a browser session.
Args:
+ include_deleted: When true, includes soft-deleted browser sessions in the lookup.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -634,7 +653,13 @@ async def retrieve(
return await self._get(
f"/browsers/{id}",
options=make_request_options(
- extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"include_deleted": include_deleted}, browser_retrieve_params.BrowserRetrieveParams
+ ),
),
cast_to=BrowserRetrieveResponse,
)
@@ -684,6 +709,7 @@ def list(
include_deleted: bool | Omit = omit,
limit: int | Omit = omit,
offset: int | Omit = omit,
+ status: Literal["active", "deleted", "all"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -693,17 +719,20 @@ def list(
) -> AsyncPaginator[BrowserListResponse, AsyncOffsetPagination[BrowserListResponse]]:
"""List all browser sessions with pagination support.
- Use include_deleted=true to
- include soft-deleted sessions in the results.
+ Use status parameter to
+ filter by session state.
Args:
- include_deleted: When true, includes soft-deleted browser sessions in the results alongside
- active sessions.
+ include_deleted: Deprecated: Use status=all instead. When true, includes soft-deleted browser
+ sessions in the results alongside active sessions.
limit: Maximum number of results to return. Defaults to 20, maximum 100.
offset: Number of results to skip. Defaults to 0.
+ status: Filter sessions by status. "active" returns only active sessions (default),
+ "deleted" returns only soft-deleted sessions, "all" returns both.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -725,6 +754,7 @@ def list(
"include_deleted": include_deleted,
"limit": limit,
"offset": offset,
+ "status": status,
},
browser_list_params.BrowserListParams,
),
diff --git a/src/kernel/types/__init__.py b/src/kernel/types/__init__.py
index d037578..016e17c 100644
--- a/src/kernel/types/__init__.py
+++ b/src/kernel/types/__init__.py
@@ -36,6 +36,7 @@
from .invocation_list_params import InvocationListParams as InvocationListParams
from .invocation_state_event import InvocationStateEvent as InvocationStateEvent
from .browser_create_response import BrowserCreateResponse as BrowserCreateResponse
+from .browser_retrieve_params import BrowserRetrieveParams as BrowserRetrieveParams
from .browser_update_response import BrowserUpdateResponse as BrowserUpdateResponse
from .extension_list_response import ExtensionListResponse as ExtensionListResponse
from .extension_upload_params import ExtensionUploadParams as ExtensionUploadParams
diff --git a/src/kernel/types/browser_list_params.py b/src/kernel/types/browser_list_params.py
index 20837be..02aa97a 100644
--- a/src/kernel/types/browser_list_params.py
+++ b/src/kernel/types/browser_list_params.py
@@ -2,14 +2,15 @@
from __future__ import annotations
-from typing_extensions import TypedDict
+from typing_extensions import Literal, TypedDict
__all__ = ["BrowserListParams"]
class BrowserListParams(TypedDict, total=False):
include_deleted: bool
- """
+ """Deprecated: Use status=all instead.
+
When true, includes soft-deleted browser sessions in the results alongside
active sessions.
"""
@@ -19,3 +20,10 @@ class BrowserListParams(TypedDict, total=False):
offset: int
"""Number of results to skip. Defaults to 0."""
+
+ status: Literal["active", "deleted", "all"]
+ """Filter sessions by status.
+
+ "active" returns only active sessions (default), "deleted" returns only
+ soft-deleted sessions, "all" returns both.
+ """
diff --git a/src/kernel/types/browser_retrieve_params.py b/src/kernel/types/browser_retrieve_params.py
new file mode 100644
index 0000000..ec5e8aa
--- /dev/null
+++ b/src/kernel/types/browser_retrieve_params.py
@@ -0,0 +1,12 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["BrowserRetrieveParams"]
+
+
+class BrowserRetrieveParams(TypedDict, total=False):
+ include_deleted: bool
+ """When true, includes soft-deleted browser sessions in the lookup."""
diff --git a/tests/api_resources/test_browsers.py b/tests/api_resources/test_browsers.py
index 5eec9de..139cf14 100644
--- a/tests/api_resources/test_browsers.py
+++ b/tests/api_resources/test_browsers.py
@@ -87,7 +87,16 @@ def test_streaming_response_create(self, client: Kernel) -> None:
@parametrize
def test_method_retrieve(self, client: Kernel) -> None:
browser = client.browsers.retrieve(
- "htzv5orfit78e1m2biiifpbv",
+ id="htzv5orfit78e1m2biiifpbv",
+ )
+ assert_matches_type(BrowserRetrieveResponse, browser, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ def test_method_retrieve_with_all_params(self, client: Kernel) -> None:
+ browser = client.browsers.retrieve(
+ id="htzv5orfit78e1m2biiifpbv",
+ include_deleted=True,
)
assert_matches_type(BrowserRetrieveResponse, browser, path=["response"])
@@ -95,7 +104,7 @@ def test_method_retrieve(self, client: Kernel) -> None:
@parametrize
def test_raw_response_retrieve(self, client: Kernel) -> None:
response = client.browsers.with_raw_response.retrieve(
- "htzv5orfit78e1m2biiifpbv",
+ id="htzv5orfit78e1m2biiifpbv",
)
assert response.is_closed is True
@@ -107,7 +116,7 @@ def test_raw_response_retrieve(self, client: Kernel) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: Kernel) -> None:
with client.browsers.with_streaming_response.retrieve(
- "htzv5orfit78e1m2biiifpbv",
+ id="htzv5orfit78e1m2biiifpbv",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -122,7 +131,7 @@ def test_streaming_response_retrieve(self, client: Kernel) -> None:
def test_path_params_retrieve(self, client: Kernel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
client.browsers.with_raw_response.retrieve(
- "",
+ id="",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@@ -189,6 +198,7 @@ def test_method_list_with_all_params(self, client: Kernel) -> None:
include_deleted=True,
limit=1,
offset=0,
+ status="active",
)
assert_matches_type(SyncOffsetPagination[BrowserListResponse], browser, path=["response"])
@@ -428,7 +438,16 @@ async def test_streaming_response_create(self, async_client: AsyncKernel) -> Non
@parametrize
async def test_method_retrieve(self, async_client: AsyncKernel) -> None:
browser = await async_client.browsers.retrieve(
- "htzv5orfit78e1m2biiifpbv",
+ id="htzv5orfit78e1m2biiifpbv",
+ )
+ assert_matches_type(BrowserRetrieveResponse, browser, path=["response"])
+
+ @pytest.mark.skip(reason="Prism tests are disabled")
+ @parametrize
+ async def test_method_retrieve_with_all_params(self, async_client: AsyncKernel) -> None:
+ browser = await async_client.browsers.retrieve(
+ id="htzv5orfit78e1m2biiifpbv",
+ include_deleted=True,
)
assert_matches_type(BrowserRetrieveResponse, browser, path=["response"])
@@ -436,7 +455,7 @@ async def test_method_retrieve(self, async_client: AsyncKernel) -> None:
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncKernel) -> None:
response = await async_client.browsers.with_raw_response.retrieve(
- "htzv5orfit78e1m2biiifpbv",
+ id="htzv5orfit78e1m2biiifpbv",
)
assert response.is_closed is True
@@ -448,7 +467,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncKernel) -> None:
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncKernel) -> None:
async with async_client.browsers.with_streaming_response.retrieve(
- "htzv5orfit78e1m2biiifpbv",
+ id="htzv5orfit78e1m2biiifpbv",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -463,7 +482,7 @@ async def test_streaming_response_retrieve(self, async_client: AsyncKernel) -> N
async def test_path_params_retrieve(self, async_client: AsyncKernel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
await async_client.browsers.with_raw_response.retrieve(
- "",
+ id="",
)
@pytest.mark.skip(reason="Prism tests are disabled")
@@ -530,6 +549,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncKernel) -> N
include_deleted=True,
limit=1,
offset=0,
+ status="active",
)
assert_matches_type(AsyncOffsetPagination[BrowserListResponse], browser, path=["response"])