Skip to content

Commit fdeb71f

Browse files
authored
Merge pull request #173 from kernel/release-please--branches--main--changes--next
release: 0.107.0
2 parents f4d2d33 + 7c83d87 commit fdeb71f

19 files changed

Lines changed: 444 additions & 33 deletions

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.106.0"
2+
".": "0.107.0"
33
}

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
configured_endpoints: 164
1+
configured_endpoints: 165

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## [0.107.0](https://github.com/kernel/kernel-python-sdk/compare/v0.106.0...v0.107.0) (2026-09-16)
4+
5+
6+
### Features
7+
8+
* Classify unevaluable config registry targets ([12ced86](https://github.com/kernel/kernel-python-sdk/commit/12ced8647c23aa43c625b288ed48c7cdf8da9125))
9+
* Expose persistent Browser REPL through the API ([755dba5](https://github.com/kernel/kernel-python-sdk/commit/755dba5d1273ef9083ffbc4bc7f4adf30aea2fe9))
10+
* Return Link spend request errors directly ([82d9f84](https://github.com/kernel/kernel-python-sdk/commit/82d9f8400a761a37debabeb79e6e5d8bec2cbe32))
11+
312
## 0.106.0 (2026-09-16)
413

514
Full Changelog: [v0.104.0...v0.106.0](https://github.com/kernel/kernel-python-sdk/compare/v0.104.0...v0.106.0)

api.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ from kernel.types import (
124124
BrowserProxy,
125125
BrowserProxyConfig,
126126
BrowserProxyMode,
127+
BrowserReplContent,
128+
BrowserReplImageContent,
129+
BrowserReplRequest,
130+
BrowserReplResult,
131+
BrowserReplTextContent,
127132
BrowserUsage,
128133
Profile,
129134
Tags,
@@ -145,6 +150,7 @@ Methods:
145150
- <code title="post /browsers/{id_or_name}/curl">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">curl</a>(id_or_name, \*\*<a href="src/kernel/types/browser_curl_params.py">params</a>) -> <a href="./src/kernel/types/browser_curl_response.py">BrowserCurlResponse</a></code>
146151
- <code title="delete /browsers/{id_or_name}">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">delete_by_id</a>(id_or_name) -> None</code>
147152
- <code title="post /browsers/{id_or_name}/extensions">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">load_extensions</a>(id_or_name, \*\*<a href="src/kernel/types/browser_load_extensions_params.py">params</a>) -> None</code>
153+
- <code title="post /browsers/{id_or_name}/repl">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">repl</a>(id_or_name, \*\*<a href="src/kernel/types/browser_repl_params.py">params</a>) -> <a href="./src/kernel/types/browser_repl_result.py">BrowserReplResult</a></code>
148154

149155
## Telemetry
150156

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "kernel"
3-
version = "0.106.0"
3+
version = "0.107.0"
44
description = "The official Python library for the kernel API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"

src/kernel/_client.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ def config_registry(self) -> ConfigRegistryResource:
247247

248248
@cached_property
249249
def browsers(self) -> BrowsersResource:
250-
"""Create and manage browser sessions."""
251250
from .resources.browsers import BrowsersResource
252251

253252
return BrowsersResource(self)
@@ -652,7 +651,6 @@ def config_registry(self) -> AsyncConfigRegistryResource:
652651

653652
@cached_property
654653
def browsers(self) -> AsyncBrowsersResource:
655-
"""Create and manage browser sessions."""
656654
from .resources.browsers import AsyncBrowsersResource
657655

658656
return AsyncBrowsersResource(self)
@@ -959,7 +957,6 @@ def config_registry(self) -> config_registry.ConfigRegistryResourceWithRawRespon
959957

960958
@cached_property
961959
def browsers(self) -> browsers.BrowsersResourceWithRawResponse:
962-
"""Create and manage browser sessions."""
963960
from .resources.browsers import BrowsersResourceWithRawResponse
964961

965962
return BrowsersResourceWithRawResponse(self._client.browsers)
@@ -1098,7 +1095,6 @@ def config_registry(self) -> config_registry.AsyncConfigRegistryResourceWithRawR
10981095

10991096
@cached_property
11001097
def browsers(self) -> browsers.AsyncBrowsersResourceWithRawResponse:
1101-
"""Create and manage browser sessions."""
11021098
from .resources.browsers import AsyncBrowsersResourceWithRawResponse
11031099

11041100
return AsyncBrowsersResourceWithRawResponse(self._client.browsers)
@@ -1237,7 +1233,6 @@ def config_registry(self) -> config_registry.ConfigRegistryResourceWithStreaming
12371233

12381234
@cached_property
12391235
def browsers(self) -> browsers.BrowsersResourceWithStreamingResponse:
1240-
"""Create and manage browser sessions."""
12411236
from .resources.browsers import BrowsersResourceWithStreamingResponse
12421237

12431238
return BrowsersResourceWithStreamingResponse(self._client.browsers)
@@ -1376,7 +1371,6 @@ def config_registry(self) -> config_registry.AsyncConfigRegistryResourceWithStre
13761371

13771372
@cached_property
13781373
def browsers(self) -> browsers.AsyncBrowsersResourceWithStreamingResponse:
1379-
"""Create and manage browser sessions."""
13801374
from .resources.browsers import AsyncBrowsersResourceWithStreamingResponse
13811375

13821376
return AsyncBrowsersResourceWithStreamingResponse(self._client.browsers)

src/kernel/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "kernel"
4-
__version__ = "0.106.0" # x-release-please-version
4+
__version__ = "0.107.0" # x-release-please-version

src/kernel/resources/browsers/browsers.py

Lines changed: 148 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
BrowserMemoryRequest,
3737
browser_curl_params,
3838
browser_list_params,
39+
browser_repl_params,
3940
browser_create_params,
4041
browser_update_params,
4142
browser_retrieve_params,
@@ -95,6 +96,7 @@
9596
from ...pagination import SyncOffsetPagination, AsyncOffsetPagination
9697
from ..._base_client import AsyncPaginator, make_request_options
9798
from ...types.tags_param import TagsParam
99+
from ...types.browser_repl_result import BrowserReplResult
98100
from ...types.browser_curl_response import BrowserCurlResponse
99101
from ...types.browser_list_response import BrowserListResponse
100102
from ...types.vault_reference_param import VaultReferenceParam
@@ -118,8 +120,6 @@
118120

119121

120122
class BrowsersResource(SyncAPIResource):
121-
"""Create and manage browser sessions."""
122-
123123
@cached_property
124124
def telemetry(self) -> TelemetryResource:
125125
"""
@@ -753,10 +753,75 @@ def load_extensions(
753753
cast_to=NoneType,
754754
)
755755

756+
def repl(
757+
self,
758+
id_or_name: str,
759+
*,
760+
code: str,
761+
reset: bool | Omit = omit,
762+
timeout_sec: int | Omit = omit,
763+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
764+
# The extra values given here take precedence over values defined on the client or passed to this method.
765+
extra_headers: Headers | None = None,
766+
extra_query: Query | None = None,
767+
extra_body: Body | None = None,
768+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
769+
) -> BrowserReplResult:
770+
"""
771+
Execute JavaScript in a persistent Node.js runtime inside the browser VM.
772+
Top-level bindings, closures, mutations, and dynamically imported modules
773+
persist across calls until the REPL is reset or replaced. Start with
774+
`repl.help()` to list available methods, or call `repl.help("click")` for
775+
detailed help.
776+
777+
Expression values are ignored. Emit ordered text or image output with
778+
`repl.write(...)`, console methods, or `repl.emitImage(...)`. The runtime also
779+
exposes browser-control helpers, WebMCP, Patchright, Playwright, and raw CDP.
780+
781+
Executions are serialized. A timeout, crash, OOM, or protocol failure terminates
782+
the REPL and changes its `repl_id`. This is unrestricted code execution inside
783+
the browser VM and is not sandboxed.
784+
785+
Args:
786+
code: JavaScript evaluated in a persistent Node.js runtime. Top-level bindings persist
787+
until the browser VM's API process exits, the REPL is reset, or the REPL is
788+
terminated after a crash or timeout. Static top-level imports are unsupported;
789+
use dynamic `import()`. Expression values are ignored; emit output with
790+
`repl.write(...)`, console methods, or `repl.emitImage(...)`. May be empty only
791+
when `reset` is true.
792+
793+
reset: Terminate the current REPL, start a fresh one, and then evaluate code.
794+
795+
timeout_sec: Maximum execution time in seconds. Default is 60.
796+
797+
extra_headers: Send extra headers
798+
799+
extra_query: Add additional query parameters to the request
800+
801+
extra_body: Add additional JSON properties to the request
802+
803+
timeout: Override the client-level default timeout for this request, in seconds
804+
"""
805+
if not id_or_name:
806+
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
807+
return self._post(
808+
path_template("/browsers/{id_or_name}/repl", id_or_name=id_or_name),
809+
body=maybe_transform(
810+
{
811+
"code": code,
812+
"reset": reset,
813+
"timeout_sec": timeout_sec,
814+
},
815+
browser_repl_params.BrowserReplParams,
816+
),
817+
options=make_request_options(
818+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
819+
),
820+
cast_to=BrowserReplResult,
821+
)
756822

757-
class AsyncBrowsersResource(AsyncAPIResource):
758-
"""Create and manage browser sessions."""
759823

824+
class AsyncBrowsersResource(AsyncAPIResource):
760825
@cached_property
761826
def telemetry(self) -> AsyncTelemetryResource:
762827
"""
@@ -1390,6 +1455,73 @@ async def load_extensions(
13901455
cast_to=NoneType,
13911456
)
13921457

1458+
async def repl(
1459+
self,
1460+
id_or_name: str,
1461+
*,
1462+
code: str,
1463+
reset: bool | Omit = omit,
1464+
timeout_sec: int | Omit = omit,
1465+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1466+
# The extra values given here take precedence over values defined on the client or passed to this method.
1467+
extra_headers: Headers | None = None,
1468+
extra_query: Query | None = None,
1469+
extra_body: Body | None = None,
1470+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
1471+
) -> BrowserReplResult:
1472+
"""
1473+
Execute JavaScript in a persistent Node.js runtime inside the browser VM.
1474+
Top-level bindings, closures, mutations, and dynamically imported modules
1475+
persist across calls until the REPL is reset or replaced. Start with
1476+
`repl.help()` to list available methods, or call `repl.help("click")` for
1477+
detailed help.
1478+
1479+
Expression values are ignored. Emit ordered text or image output with
1480+
`repl.write(...)`, console methods, or `repl.emitImage(...)`. The runtime also
1481+
exposes browser-control helpers, WebMCP, Patchright, Playwright, and raw CDP.
1482+
1483+
Executions are serialized. A timeout, crash, OOM, or protocol failure terminates
1484+
the REPL and changes its `repl_id`. This is unrestricted code execution inside
1485+
the browser VM and is not sandboxed.
1486+
1487+
Args:
1488+
code: JavaScript evaluated in a persistent Node.js runtime. Top-level bindings persist
1489+
until the browser VM's API process exits, the REPL is reset, or the REPL is
1490+
terminated after a crash or timeout. Static top-level imports are unsupported;
1491+
use dynamic `import()`. Expression values are ignored; emit output with
1492+
`repl.write(...)`, console methods, or `repl.emitImage(...)`. May be empty only
1493+
when `reset` is true.
1494+
1495+
reset: Terminate the current REPL, start a fresh one, and then evaluate code.
1496+
1497+
timeout_sec: Maximum execution time in seconds. Default is 60.
1498+
1499+
extra_headers: Send extra headers
1500+
1501+
extra_query: Add additional query parameters to the request
1502+
1503+
extra_body: Add additional JSON properties to the request
1504+
1505+
timeout: Override the client-level default timeout for this request, in seconds
1506+
"""
1507+
if not id_or_name:
1508+
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
1509+
return await self._post(
1510+
path_template("/browsers/{id_or_name}/repl", id_or_name=id_or_name),
1511+
body=await async_maybe_transform(
1512+
{
1513+
"code": code,
1514+
"reset": reset,
1515+
"timeout_sec": timeout_sec,
1516+
},
1517+
browser_repl_params.BrowserReplParams,
1518+
),
1519+
options=make_request_options(
1520+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1521+
),
1522+
cast_to=BrowserReplResult,
1523+
)
1524+
13931525

13941526
class BrowsersResourceWithRawResponse:
13951527
def __init__(self, browsers: BrowsersResource) -> None:
@@ -1416,6 +1548,9 @@ def __init__(self, browsers: BrowsersResource) -> None:
14161548
self.load_extensions = to_raw_response_wrapper(
14171549
browsers.load_extensions,
14181550
)
1551+
self.repl = to_raw_response_wrapper(
1552+
browsers.repl,
1553+
)
14191554

14201555
@cached_property
14211556
def telemetry(self) -> TelemetryResourceWithRawResponse:
@@ -1485,6 +1620,9 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None:
14851620
self.load_extensions = async_to_raw_response_wrapper(
14861621
browsers.load_extensions,
14871622
)
1623+
self.repl = async_to_raw_response_wrapper(
1624+
browsers.repl,
1625+
)
14881626

14891627
@cached_property
14901628
def telemetry(self) -> AsyncTelemetryResourceWithRawResponse:
@@ -1554,6 +1692,9 @@ def __init__(self, browsers: BrowsersResource) -> None:
15541692
self.load_extensions = to_streamed_response_wrapper(
15551693
browsers.load_extensions,
15561694
)
1695+
self.repl = to_streamed_response_wrapper(
1696+
browsers.repl,
1697+
)
15571698

15581699
@cached_property
15591700
def telemetry(self) -> TelemetryResourceWithStreamingResponse:
@@ -1623,6 +1764,9 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None:
16231764
self.load_extensions = async_to_streamed_response_wrapper(
16241765
browsers.load_extensions,
16251766
)
1767+
self.repl = async_to_streamed_response_wrapper(
1768+
browsers.repl,
1769+
)
16261770

16271771
@cached_property
16281772
def telemetry(self) -> AsyncTelemetryResourceWithStreamingResponse:

0 commit comments

Comments
 (0)