Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.97.0"
".": "0.98.0"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
configured_endpoints: 145
configured_endpoints: 147
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [0.98.0](https://github.com/kernel/kernel-python-sdk/compare/v0.97.0...v0.98.0) (2026-09-02)


### Features

* Accept browser session name on all /browsers/{id_or_name} sub-resource routes ([a60fa2b](https://github.com/kernel/kernel-python-sdk/commit/a60fa2bd48b06c8ca61005c3e29c42918ee371f2))

## [0.97.0](https://github.com/kernel/kernel-python-sdk/compare/v0.96.0...v0.97.0) (2026-08-31)


Expand Down
110 changes: 66 additions & 44 deletions api.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "kernel"
version = "0.97.0"
version = "0.98.0"
description = "The official Python library for the kernel API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "kernel"
__version__ = "0.97.0" # x-release-please-version
__version__ = "0.98.0" # x-release-please-version
14 changes: 14 additions & 0 deletions src/kernel/resources/browsers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
LogsResourceWithStreamingResponse,
AsyncLogsResourceWithStreamingResponse,
)
from .webmcp import (
WebmcpResource,
AsyncWebmcpResource,
WebmcpResourceWithRawResponse,
AsyncWebmcpResourceWithRawResponse,
WebmcpResourceWithStreamingResponse,
AsyncWebmcpResourceWithStreamingResponse,
)
from .process import (
ProcessResource,
AsyncProcessResource,
Expand Down Expand Up @@ -108,6 +116,12 @@
"AsyncPlaywrightResourceWithRawResponse",
"PlaywrightResourceWithStreamingResponse",
"AsyncPlaywrightResourceWithStreamingResponse",
"WebmcpResource",
"AsyncWebmcpResource",
"WebmcpResourceWithRawResponse",
"AsyncWebmcpResourceWithRawResponse",
"WebmcpResourceWithStreamingResponse",
"AsyncWebmcpResourceWithStreamingResponse",
"BrowsersResource",
"AsyncBrowsersResource",
"BrowsersResourceWithRawResponse",
Expand Down
70 changes: 54 additions & 16 deletions src/kernel/resources/browsers/browsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
FsResourceWithStreamingResponse,
AsyncFsResourceWithStreamingResponse,
)
from .webmcp import (
WebmcpResource,
AsyncWebmcpResource,
WebmcpResourceWithRawResponse,
AsyncWebmcpResourceWithRawResponse,
WebmcpResourceWithStreamingResponse,
AsyncWebmcpResourceWithStreamingResponse,
)
from ...types import (
BrowserMemoryRequest,
browser_curl_params,
Expand Down Expand Up @@ -148,6 +156,11 @@ def playwright(self) -> PlaywrightResource:
"""Execute Playwright code against the browser instance."""
return PlaywrightResource(self._client)

@cached_property
def webmcp(self) -> WebmcpResource:
"""Discover and invoke native page tools across the browser instance."""
return WebmcpResource(self._client)

@cached_property
def with_raw_response(self) -> BrowsersResourceWithRawResponse:
"""
Expand Down Expand Up @@ -527,7 +540,7 @@ def list(

def curl(
self,
id: str,
id_or_name: str,
*,
url: str,
body: str | Omit = omit,
Expand Down Expand Up @@ -568,10 +581,10 @@ def curl(

timeout: Override the client-level default timeout for this request, in seconds
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
if not id_or_name:
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
return self._post(
path_template("/browsers/{id}/curl", id=id),
path_template("/browsers/{id_or_name}/curl", id_or_name=id_or_name),
body=maybe_transform(
{
"url": url,
Expand Down Expand Up @@ -683,7 +696,7 @@ def delete_by_id(

def load_extensions(
self,
id: str,
id_or_name: str,
*,
extensions: Iterable[browser_load_extensions_params.Extension],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
Expand All @@ -708,8 +721,8 @@ def load_extensions(

timeout: Override the client-level default timeout for this request, in seconds
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
if not id_or_name:
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
body = deepcopy_with_paths({"extensions": extensions}, [["extensions", "<array>", "zip_file"]])
files = extract_files(cast(Mapping[str, object], body), paths=[["extensions", "<array>", "zip_file"]])
Expand All @@ -718,7 +731,7 @@ def load_extensions(
# multipart/form-data; boundary=---abc--
extra_headers["Content-Type"] = "multipart/form-data"
return self._post(
path_template("/browsers/{id}/extensions", id=id),
path_template("/browsers/{id_or_name}/extensions", id_or_name=id_or_name),
body=maybe_transform(body, browser_load_extensions_params.BrowserLoadExtensionsParams),
files=files,
options=make_request_options(
Expand Down Expand Up @@ -768,6 +781,11 @@ def playwright(self) -> AsyncPlaywrightResource:
"""Execute Playwright code against the browser instance."""
return AsyncPlaywrightResource(self._client)

@cached_property
def webmcp(self) -> AsyncWebmcpResource:
"""Discover and invoke native page tools across the browser instance."""
return AsyncWebmcpResource(self._client)

@cached_property
def with_raw_response(self) -> AsyncBrowsersResourceWithRawResponse:
"""
Expand Down Expand Up @@ -1147,7 +1165,7 @@ def list(

async def curl(
self,
id: str,
id_or_name: str,
*,
url: str,
body: str | Omit = omit,
Expand Down Expand Up @@ -1188,10 +1206,10 @@ async def curl(

timeout: Override the client-level default timeout for this request, in seconds
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
if not id_or_name:
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
return await self._post(
path_template("/browsers/{id}/curl", id=id),
path_template("/browsers/{id_or_name}/curl", id_or_name=id_or_name),
body=await async_maybe_transform(
{
"url": url,
Expand Down Expand Up @@ -1303,7 +1321,7 @@ async def delete_by_id(

async def load_extensions(
self,
id: str,
id_or_name: str,
*,
extensions: Iterable[browser_load_extensions_params.Extension],
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
Expand All @@ -1328,8 +1346,8 @@ async def load_extensions(

timeout: Override the client-level default timeout for this request, in seconds
"""
if not id:
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
if not id_or_name:
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
body = deepcopy_with_paths({"extensions": extensions}, [["extensions", "<array>", "zip_file"]])
files = extract_files(cast(Mapping[str, object], body), paths=[["extensions", "<array>", "zip_file"]])
Expand All @@ -1338,7 +1356,7 @@ async def load_extensions(
# multipart/form-data; boundary=---abc--
extra_headers["Content-Type"] = "multipart/form-data"
return await self._post(
path_template("/browsers/{id}/extensions", id=id),
path_template("/browsers/{id_or_name}/extensions", id_or_name=id_or_name),
body=await async_maybe_transform(body, browser_load_extensions_params.BrowserLoadExtensionsParams),
files=files,
options=make_request_options(
Expand Down Expand Up @@ -1411,6 +1429,11 @@ def playwright(self) -> PlaywrightResourceWithRawResponse:
"""Execute Playwright code against the browser instance."""
return PlaywrightResourceWithRawResponse(self._browsers.playwright)

@cached_property
def webmcp(self) -> WebmcpResourceWithRawResponse:
"""Discover and invoke native page tools across the browser instance."""
return WebmcpResourceWithRawResponse(self._browsers.webmcp)


class AsyncBrowsersResourceWithRawResponse:
def __init__(self, browsers: AsyncBrowsersResource) -> None:
Expand Down Expand Up @@ -1475,6 +1498,11 @@ def playwright(self) -> AsyncPlaywrightResourceWithRawResponse:
"""Execute Playwright code against the browser instance."""
return AsyncPlaywrightResourceWithRawResponse(self._browsers.playwright)

@cached_property
def webmcp(self) -> AsyncWebmcpResourceWithRawResponse:
"""Discover and invoke native page tools across the browser instance."""
return AsyncWebmcpResourceWithRawResponse(self._browsers.webmcp)


class BrowsersResourceWithStreamingResponse:
def __init__(self, browsers: BrowsersResource) -> None:
Expand Down Expand Up @@ -1539,6 +1567,11 @@ def playwright(self) -> PlaywrightResourceWithStreamingResponse:
"""Execute Playwright code against the browser instance."""
return PlaywrightResourceWithStreamingResponse(self._browsers.playwright)

@cached_property
def webmcp(self) -> WebmcpResourceWithStreamingResponse:
"""Discover and invoke native page tools across the browser instance."""
return WebmcpResourceWithStreamingResponse(self._browsers.webmcp)


class AsyncBrowsersResourceWithStreamingResponse:
def __init__(self, browsers: AsyncBrowsersResource) -> None:
Expand Down Expand Up @@ -1602,3 +1635,8 @@ def computer(self) -> AsyncComputerResourceWithStreamingResponse:
def playwright(self) -> AsyncPlaywrightResourceWithStreamingResponse:
"""Execute Playwright code against the browser instance."""
return AsyncPlaywrightResourceWithStreamingResponse(self._browsers.playwright)

@cached_property
def webmcp(self) -> AsyncWebmcpResourceWithStreamingResponse:
"""Discover and invoke native page tools across the browser instance."""
return AsyncWebmcpResourceWithStreamingResponse(self._browsers.webmcp)
Loading
Loading