From e9265c4ffba59e8cfd8a02e12653b83a471aced3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 3 Mar 2026 03:49:08 +0000
Subject: [PATCH 1/5] chore(internal): codegen related update
---
src/kernel/_client.py | 60 ++++++++++++++++++++
src/kernel/resources/apps.py | 4 ++
src/kernel/resources/auth/auth.py | 6 ++
src/kernel/resources/auth/connections.py | 4 ++
src/kernel/resources/browser_pools.py | 4 ++
src/kernel/resources/browsers/browsers.py | 34 +++++++++++
src/kernel/resources/browsers/fs/fs.py | 10 ++++
src/kernel/resources/browsers/fs/watch.py | 4 ++
src/kernel/resources/browsers/logs.py | 4 ++
src/kernel/resources/browsers/playwright.py | 4 ++
src/kernel/resources/browsers/process.py | 4 ++
src/kernel/resources/browsers/replays.py | 4 ++
src/kernel/resources/credential_providers.py | 4 ++
src/kernel/resources/credentials.py | 4 ++
src/kernel/resources/deployments.py | 4 ++
src/kernel/resources/extensions.py | 4 ++
src/kernel/resources/invocations.py | 4 ++
src/kernel/resources/profiles.py | 4 ++
src/kernel/resources/proxies.py | 4 ++
19 files changed, 170 insertions(+)
diff --git a/src/kernel/_client.py b/src/kernel/_client.py
index df7fd255..84fc48dd 100644
--- a/src/kernel/_client.py
+++ b/src/kernel/_client.py
@@ -155,30 +155,35 @@ def __init__(
@cached_property
def deployments(self) -> DeploymentsResource:
+ """Create and manage app deployments and stream deployment events."""
from .resources.deployments import DeploymentsResource
return DeploymentsResource(self)
@cached_property
def apps(self) -> AppsResource:
+ """List applications and versions."""
from .resources.apps import AppsResource
return AppsResource(self)
@cached_property
def invocations(self) -> InvocationsResource:
+ """Invoke actions and stream or query invocation status and events."""
from .resources.invocations import InvocationsResource
return InvocationsResource(self)
@cached_property
def browsers(self) -> BrowsersResource:
+ """Create and manage browser sessions."""
from .resources.browsers import BrowsersResource
return BrowsersResource(self)
@cached_property
def profiles(self) -> ProfilesResource:
+ """Create, list, retrieve, and delete browser profiles."""
from .resources.profiles import ProfilesResource
return ProfilesResource(self)
@@ -191,30 +196,35 @@ def auth(self) -> AuthResource:
@cached_property
def proxies(self) -> ProxiesResource:
+ """Create and manage proxy configurations for routing browser traffic."""
from .resources.proxies import ProxiesResource
return ProxiesResource(self)
@cached_property
def extensions(self) -> ExtensionsResource:
+ """Create, list, retrieve, and delete browser extensions."""
from .resources.extensions import ExtensionsResource
return ExtensionsResource(self)
@cached_property
def browser_pools(self) -> BrowserPoolsResource:
+ """Create and manage browser pools for acquiring and releasing browsers."""
from .resources.browser_pools import BrowserPoolsResource
return BrowserPoolsResource(self)
@cached_property
def credentials(self) -> CredentialsResource:
+ """Create and manage credentials for authentication."""
from .resources.credentials import CredentialsResource
return CredentialsResource(self)
@cached_property
def credential_providers(self) -> CredentialProvidersResource:
+ """Configure external credential providers like 1Password."""
from .resources.credential_providers import CredentialProvidersResource
return CredentialProvidersResource(self)
@@ -415,30 +425,35 @@ def __init__(
@cached_property
def deployments(self) -> AsyncDeploymentsResource:
+ """Create and manage app deployments and stream deployment events."""
from .resources.deployments import AsyncDeploymentsResource
return AsyncDeploymentsResource(self)
@cached_property
def apps(self) -> AsyncAppsResource:
+ """List applications and versions."""
from .resources.apps import AsyncAppsResource
return AsyncAppsResource(self)
@cached_property
def invocations(self) -> AsyncInvocationsResource:
+ """Invoke actions and stream or query invocation status and events."""
from .resources.invocations import AsyncInvocationsResource
return AsyncInvocationsResource(self)
@cached_property
def browsers(self) -> AsyncBrowsersResource:
+ """Create and manage browser sessions."""
from .resources.browsers import AsyncBrowsersResource
return AsyncBrowsersResource(self)
@cached_property
def profiles(self) -> AsyncProfilesResource:
+ """Create, list, retrieve, and delete browser profiles."""
from .resources.profiles import AsyncProfilesResource
return AsyncProfilesResource(self)
@@ -451,30 +466,35 @@ def auth(self) -> AsyncAuthResource:
@cached_property
def proxies(self) -> AsyncProxiesResource:
+ """Create and manage proxy configurations for routing browser traffic."""
from .resources.proxies import AsyncProxiesResource
return AsyncProxiesResource(self)
@cached_property
def extensions(self) -> AsyncExtensionsResource:
+ """Create, list, retrieve, and delete browser extensions."""
from .resources.extensions import AsyncExtensionsResource
return AsyncExtensionsResource(self)
@cached_property
def browser_pools(self) -> AsyncBrowserPoolsResource:
+ """Create and manage browser pools for acquiring and releasing browsers."""
from .resources.browser_pools import AsyncBrowserPoolsResource
return AsyncBrowserPoolsResource(self)
@cached_property
def credentials(self) -> AsyncCredentialsResource:
+ """Create and manage credentials for authentication."""
from .resources.credentials import AsyncCredentialsResource
return AsyncCredentialsResource(self)
@cached_property
def credential_providers(self) -> AsyncCredentialProvidersResource:
+ """Configure external credential providers like 1Password."""
from .resources.credential_providers import AsyncCredentialProvidersResource
return AsyncCredentialProvidersResource(self)
@@ -602,30 +622,35 @@ def __init__(self, client: Kernel) -> None:
@cached_property
def deployments(self) -> deployments.DeploymentsResourceWithRawResponse:
+ """Create and manage app deployments and stream deployment events."""
from .resources.deployments import DeploymentsResourceWithRawResponse
return DeploymentsResourceWithRawResponse(self._client.deployments)
@cached_property
def apps(self) -> apps.AppsResourceWithRawResponse:
+ """List applications and versions."""
from .resources.apps import AppsResourceWithRawResponse
return AppsResourceWithRawResponse(self._client.apps)
@cached_property
def invocations(self) -> invocations.InvocationsResourceWithRawResponse:
+ """Invoke actions and stream or query invocation status and events."""
from .resources.invocations import InvocationsResourceWithRawResponse
return InvocationsResourceWithRawResponse(self._client.invocations)
@cached_property
def browsers(self) -> browsers.BrowsersResourceWithRawResponse:
+ """Create and manage browser sessions."""
from .resources.browsers import BrowsersResourceWithRawResponse
return BrowsersResourceWithRawResponse(self._client.browsers)
@cached_property
def profiles(self) -> profiles.ProfilesResourceWithRawResponse:
+ """Create, list, retrieve, and delete browser profiles."""
from .resources.profiles import ProfilesResourceWithRawResponse
return ProfilesResourceWithRawResponse(self._client.profiles)
@@ -638,30 +663,35 @@ def auth(self) -> auth.AuthResourceWithRawResponse:
@cached_property
def proxies(self) -> proxies.ProxiesResourceWithRawResponse:
+ """Create and manage proxy configurations for routing browser traffic."""
from .resources.proxies import ProxiesResourceWithRawResponse
return ProxiesResourceWithRawResponse(self._client.proxies)
@cached_property
def extensions(self) -> extensions.ExtensionsResourceWithRawResponse:
+ """Create, list, retrieve, and delete browser extensions."""
from .resources.extensions import ExtensionsResourceWithRawResponse
return ExtensionsResourceWithRawResponse(self._client.extensions)
@cached_property
def browser_pools(self) -> browser_pools.BrowserPoolsResourceWithRawResponse:
+ """Create and manage browser pools for acquiring and releasing browsers."""
from .resources.browser_pools import BrowserPoolsResourceWithRawResponse
return BrowserPoolsResourceWithRawResponse(self._client.browser_pools)
@cached_property
def credentials(self) -> credentials.CredentialsResourceWithRawResponse:
+ """Create and manage credentials for authentication."""
from .resources.credentials import CredentialsResourceWithRawResponse
return CredentialsResourceWithRawResponse(self._client.credentials)
@cached_property
def credential_providers(self) -> credential_providers.CredentialProvidersResourceWithRawResponse:
+ """Configure external credential providers like 1Password."""
from .resources.credential_providers import CredentialProvidersResourceWithRawResponse
return CredentialProvidersResourceWithRawResponse(self._client.credential_providers)
@@ -675,30 +705,35 @@ def __init__(self, client: AsyncKernel) -> None:
@cached_property
def deployments(self) -> deployments.AsyncDeploymentsResourceWithRawResponse:
+ """Create and manage app deployments and stream deployment events."""
from .resources.deployments import AsyncDeploymentsResourceWithRawResponse
return AsyncDeploymentsResourceWithRawResponse(self._client.deployments)
@cached_property
def apps(self) -> apps.AsyncAppsResourceWithRawResponse:
+ """List applications and versions."""
from .resources.apps import AsyncAppsResourceWithRawResponse
return AsyncAppsResourceWithRawResponse(self._client.apps)
@cached_property
def invocations(self) -> invocations.AsyncInvocationsResourceWithRawResponse:
+ """Invoke actions and stream or query invocation status and events."""
from .resources.invocations import AsyncInvocationsResourceWithRawResponse
return AsyncInvocationsResourceWithRawResponse(self._client.invocations)
@cached_property
def browsers(self) -> browsers.AsyncBrowsersResourceWithRawResponse:
+ """Create and manage browser sessions."""
from .resources.browsers import AsyncBrowsersResourceWithRawResponse
return AsyncBrowsersResourceWithRawResponse(self._client.browsers)
@cached_property
def profiles(self) -> profiles.AsyncProfilesResourceWithRawResponse:
+ """Create, list, retrieve, and delete browser profiles."""
from .resources.profiles import AsyncProfilesResourceWithRawResponse
return AsyncProfilesResourceWithRawResponse(self._client.profiles)
@@ -711,30 +746,35 @@ def auth(self) -> auth.AsyncAuthResourceWithRawResponse:
@cached_property
def proxies(self) -> proxies.AsyncProxiesResourceWithRawResponse:
+ """Create and manage proxy configurations for routing browser traffic."""
from .resources.proxies import AsyncProxiesResourceWithRawResponse
return AsyncProxiesResourceWithRawResponse(self._client.proxies)
@cached_property
def extensions(self) -> extensions.AsyncExtensionsResourceWithRawResponse:
+ """Create, list, retrieve, and delete browser extensions."""
from .resources.extensions import AsyncExtensionsResourceWithRawResponse
return AsyncExtensionsResourceWithRawResponse(self._client.extensions)
@cached_property
def browser_pools(self) -> browser_pools.AsyncBrowserPoolsResourceWithRawResponse:
+ """Create and manage browser pools for acquiring and releasing browsers."""
from .resources.browser_pools import AsyncBrowserPoolsResourceWithRawResponse
return AsyncBrowserPoolsResourceWithRawResponse(self._client.browser_pools)
@cached_property
def credentials(self) -> credentials.AsyncCredentialsResourceWithRawResponse:
+ """Create and manage credentials for authentication."""
from .resources.credentials import AsyncCredentialsResourceWithRawResponse
return AsyncCredentialsResourceWithRawResponse(self._client.credentials)
@cached_property
def credential_providers(self) -> credential_providers.AsyncCredentialProvidersResourceWithRawResponse:
+ """Configure external credential providers like 1Password."""
from .resources.credential_providers import AsyncCredentialProvidersResourceWithRawResponse
return AsyncCredentialProvidersResourceWithRawResponse(self._client.credential_providers)
@@ -748,30 +788,35 @@ def __init__(self, client: Kernel) -> None:
@cached_property
def deployments(self) -> deployments.DeploymentsResourceWithStreamingResponse:
+ """Create and manage app deployments and stream deployment events."""
from .resources.deployments import DeploymentsResourceWithStreamingResponse
return DeploymentsResourceWithStreamingResponse(self._client.deployments)
@cached_property
def apps(self) -> apps.AppsResourceWithStreamingResponse:
+ """List applications and versions."""
from .resources.apps import AppsResourceWithStreamingResponse
return AppsResourceWithStreamingResponse(self._client.apps)
@cached_property
def invocations(self) -> invocations.InvocationsResourceWithStreamingResponse:
+ """Invoke actions and stream or query invocation status and events."""
from .resources.invocations import InvocationsResourceWithStreamingResponse
return InvocationsResourceWithStreamingResponse(self._client.invocations)
@cached_property
def browsers(self) -> browsers.BrowsersResourceWithStreamingResponse:
+ """Create and manage browser sessions."""
from .resources.browsers import BrowsersResourceWithStreamingResponse
return BrowsersResourceWithStreamingResponse(self._client.browsers)
@cached_property
def profiles(self) -> profiles.ProfilesResourceWithStreamingResponse:
+ """Create, list, retrieve, and delete browser profiles."""
from .resources.profiles import ProfilesResourceWithStreamingResponse
return ProfilesResourceWithStreamingResponse(self._client.profiles)
@@ -784,30 +829,35 @@ def auth(self) -> auth.AuthResourceWithStreamingResponse:
@cached_property
def proxies(self) -> proxies.ProxiesResourceWithStreamingResponse:
+ """Create and manage proxy configurations for routing browser traffic."""
from .resources.proxies import ProxiesResourceWithStreamingResponse
return ProxiesResourceWithStreamingResponse(self._client.proxies)
@cached_property
def extensions(self) -> extensions.ExtensionsResourceWithStreamingResponse:
+ """Create, list, retrieve, and delete browser extensions."""
from .resources.extensions import ExtensionsResourceWithStreamingResponse
return ExtensionsResourceWithStreamingResponse(self._client.extensions)
@cached_property
def browser_pools(self) -> browser_pools.BrowserPoolsResourceWithStreamingResponse:
+ """Create and manage browser pools for acquiring and releasing browsers."""
from .resources.browser_pools import BrowserPoolsResourceWithStreamingResponse
return BrowserPoolsResourceWithStreamingResponse(self._client.browser_pools)
@cached_property
def credentials(self) -> credentials.CredentialsResourceWithStreamingResponse:
+ """Create and manage credentials for authentication."""
from .resources.credentials import CredentialsResourceWithStreamingResponse
return CredentialsResourceWithStreamingResponse(self._client.credentials)
@cached_property
def credential_providers(self) -> credential_providers.CredentialProvidersResourceWithStreamingResponse:
+ """Configure external credential providers like 1Password."""
from .resources.credential_providers import CredentialProvidersResourceWithStreamingResponse
return CredentialProvidersResourceWithStreamingResponse(self._client.credential_providers)
@@ -821,30 +871,35 @@ def __init__(self, client: AsyncKernel) -> None:
@cached_property
def deployments(self) -> deployments.AsyncDeploymentsResourceWithStreamingResponse:
+ """Create and manage app deployments and stream deployment events."""
from .resources.deployments import AsyncDeploymentsResourceWithStreamingResponse
return AsyncDeploymentsResourceWithStreamingResponse(self._client.deployments)
@cached_property
def apps(self) -> apps.AsyncAppsResourceWithStreamingResponse:
+ """List applications and versions."""
from .resources.apps import AsyncAppsResourceWithStreamingResponse
return AsyncAppsResourceWithStreamingResponse(self._client.apps)
@cached_property
def invocations(self) -> invocations.AsyncInvocationsResourceWithStreamingResponse:
+ """Invoke actions and stream or query invocation status and events."""
from .resources.invocations import AsyncInvocationsResourceWithStreamingResponse
return AsyncInvocationsResourceWithStreamingResponse(self._client.invocations)
@cached_property
def browsers(self) -> browsers.AsyncBrowsersResourceWithStreamingResponse:
+ """Create and manage browser sessions."""
from .resources.browsers import AsyncBrowsersResourceWithStreamingResponse
return AsyncBrowsersResourceWithStreamingResponse(self._client.browsers)
@cached_property
def profiles(self) -> profiles.AsyncProfilesResourceWithStreamingResponse:
+ """Create, list, retrieve, and delete browser profiles."""
from .resources.profiles import AsyncProfilesResourceWithStreamingResponse
return AsyncProfilesResourceWithStreamingResponse(self._client.profiles)
@@ -857,30 +912,35 @@ def auth(self) -> auth.AsyncAuthResourceWithStreamingResponse:
@cached_property
def proxies(self) -> proxies.AsyncProxiesResourceWithStreamingResponse:
+ """Create and manage proxy configurations for routing browser traffic."""
from .resources.proxies import AsyncProxiesResourceWithStreamingResponse
return AsyncProxiesResourceWithStreamingResponse(self._client.proxies)
@cached_property
def extensions(self) -> extensions.AsyncExtensionsResourceWithStreamingResponse:
+ """Create, list, retrieve, and delete browser extensions."""
from .resources.extensions import AsyncExtensionsResourceWithStreamingResponse
return AsyncExtensionsResourceWithStreamingResponse(self._client.extensions)
@cached_property
def browser_pools(self) -> browser_pools.AsyncBrowserPoolsResourceWithStreamingResponse:
+ """Create and manage browser pools for acquiring and releasing browsers."""
from .resources.browser_pools import AsyncBrowserPoolsResourceWithStreamingResponse
return AsyncBrowserPoolsResourceWithStreamingResponse(self._client.browser_pools)
@cached_property
def credentials(self) -> credentials.AsyncCredentialsResourceWithStreamingResponse:
+ """Create and manage credentials for authentication."""
from .resources.credentials import AsyncCredentialsResourceWithStreamingResponse
return AsyncCredentialsResourceWithStreamingResponse(self._client.credentials)
@cached_property
def credential_providers(self) -> credential_providers.AsyncCredentialProvidersResourceWithStreamingResponse:
+ """Configure external credential providers like 1Password."""
from .resources.credential_providers import AsyncCredentialProvidersResourceWithStreamingResponse
return AsyncCredentialProvidersResourceWithStreamingResponse(self._client.credential_providers)
diff --git a/src/kernel/resources/apps.py b/src/kernel/resources/apps.py
index 7383c29e..4290f3f6 100644
--- a/src/kernel/resources/apps.py
+++ b/src/kernel/resources/apps.py
@@ -23,6 +23,8 @@
class AppsResource(SyncAPIResource):
+ """List applications and versions."""
+
@cached_property
def with_raw_response(self) -> AppsResourceWithRawResponse:
"""
@@ -104,6 +106,8 @@ def list(
class AsyncAppsResource(AsyncAPIResource):
+ """List applications and versions."""
+
@cached_property
def with_raw_response(self) -> AsyncAppsResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/auth/auth.py b/src/kernel/resources/auth/auth.py
index b5980e6b..f8744950 100644
--- a/src/kernel/resources/auth/auth.py
+++ b/src/kernel/resources/auth/auth.py
@@ -19,6 +19,7 @@
class AuthResource(SyncAPIResource):
@cached_property
def connections(self) -> ConnectionsResource:
+ """Create and manage auth connections for automated credential capture and login."""
return ConnectionsResource(self._client)
@cached_property
@@ -44,6 +45,7 @@ def with_streaming_response(self) -> AuthResourceWithStreamingResponse:
class AsyncAuthResource(AsyncAPIResource):
@cached_property
def connections(self) -> AsyncConnectionsResource:
+ """Create and manage auth connections for automated credential capture and login."""
return AsyncConnectionsResource(self._client)
@cached_property
@@ -72,6 +74,7 @@ def __init__(self, auth: AuthResource) -> None:
@cached_property
def connections(self) -> ConnectionsResourceWithRawResponse:
+ """Create and manage auth connections for automated credential capture and login."""
return ConnectionsResourceWithRawResponse(self._auth.connections)
@@ -81,6 +84,7 @@ def __init__(self, auth: AsyncAuthResource) -> None:
@cached_property
def connections(self) -> AsyncConnectionsResourceWithRawResponse:
+ """Create and manage auth connections for automated credential capture and login."""
return AsyncConnectionsResourceWithRawResponse(self._auth.connections)
@@ -90,6 +94,7 @@ def __init__(self, auth: AuthResource) -> None:
@cached_property
def connections(self) -> ConnectionsResourceWithStreamingResponse:
+ """Create and manage auth connections for automated credential capture and login."""
return ConnectionsResourceWithStreamingResponse(self._auth.connections)
@@ -99,4 +104,5 @@ def __init__(self, auth: AsyncAuthResource) -> None:
@cached_property
def connections(self) -> AsyncConnectionsResourceWithStreamingResponse:
+ """Create and manage auth connections for automated credential capture and login."""
return AsyncConnectionsResourceWithStreamingResponse(self._auth.connections)
diff --git a/src/kernel/resources/auth/connections.py b/src/kernel/resources/auth/connections.py
index 93b6cf6a..fed66797 100644
--- a/src/kernel/resources/auth/connections.py
+++ b/src/kernel/resources/auth/connections.py
@@ -34,6 +34,8 @@
class ConnectionsResource(SyncAPIResource):
+ """Create and manage auth connections for automated credential capture and login."""
+
@cached_property
def with_raw_response(self) -> ConnectionsResourceWithRawResponse:
"""
@@ -413,6 +415,8 @@ def submit(
class AsyncConnectionsResource(AsyncAPIResource):
+ """Create and manage auth connections for automated credential capture and login."""
+
@cached_property
def with_raw_response(self) -> AsyncConnectionsResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/browser_pools.py b/src/kernel/resources/browser_pools.py
index 9177d678..a5b6e59a 100644
--- a/src/kernel/resources/browser_pools.py
+++ b/src/kernel/resources/browser_pools.py
@@ -35,6 +35,8 @@
class BrowserPoolsResource(SyncAPIResource):
+ """Create and manage browser pools for acquiring and releasing browsers."""
+
@cached_property
def with_raw_response(self) -> BrowserPoolsResourceWithRawResponse:
"""
@@ -473,6 +475,8 @@ def release(
class AsyncBrowserPoolsResource(AsyncAPIResource):
+ """Create and manage browser pools for acquiring and releasing browsers."""
+
@cached_property
def with_raw_response(self) -> AsyncBrowserPoolsResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/browsers/browsers.py b/src/kernel/resources/browsers/browsers.py
index 59cecda1..32855ee8 100644
--- a/src/kernel/resources/browsers/browsers.py
+++ b/src/kernel/resources/browsers/browsers.py
@@ -89,20 +89,26 @@
class BrowsersResource(SyncAPIResource):
+ """Create and manage browser sessions."""
+
@cached_property
def replays(self) -> ReplaysResource:
+ """Record and manage browser session video replays."""
return ReplaysResource(self._client)
@cached_property
def fs(self) -> FsResource:
+ """Read, write, and manage files on the browser instance."""
return FsResource(self._client)
@cached_property
def process(self) -> ProcessResource:
+ """Execute and manage processes on the browser instance."""
return ProcessResource(self._client)
@cached_property
def logs(self) -> LogsResource:
+ """Stream logs from the browser instance."""
return LogsResource(self._client)
@cached_property
@@ -111,6 +117,7 @@ def computer(self) -> ComputerResource:
@cached_property
def playwright(self) -> PlaywrightResource:
+ """Execute Playwright code against the browser instance."""
return PlaywrightResource(self._client)
@cached_property
@@ -509,20 +516,26 @@ def load_extensions(
class AsyncBrowsersResource(AsyncAPIResource):
+ """Create and manage browser sessions."""
+
@cached_property
def replays(self) -> AsyncReplaysResource:
+ """Record and manage browser session video replays."""
return AsyncReplaysResource(self._client)
@cached_property
def fs(self) -> AsyncFsResource:
+ """Read, write, and manage files on the browser instance."""
return AsyncFsResource(self._client)
@cached_property
def process(self) -> AsyncProcessResource:
+ """Execute and manage processes on the browser instance."""
return AsyncProcessResource(self._client)
@cached_property
def logs(self) -> AsyncLogsResource:
+ """Stream logs from the browser instance."""
return AsyncLogsResource(self._client)
@cached_property
@@ -531,6 +544,7 @@ def computer(self) -> AsyncComputerResource:
@cached_property
def playwright(self) -> AsyncPlaywrightResource:
+ """Execute Playwright code against the browser instance."""
return AsyncPlaywrightResource(self._client)
@cached_property
@@ -960,18 +974,22 @@ def __init__(self, browsers: BrowsersResource) -> None:
@cached_property
def replays(self) -> ReplaysResourceWithRawResponse:
+ """Record and manage browser session video replays."""
return ReplaysResourceWithRawResponse(self._browsers.replays)
@cached_property
def fs(self) -> FsResourceWithRawResponse:
+ """Read, write, and manage files on the browser instance."""
return FsResourceWithRawResponse(self._browsers.fs)
@cached_property
def process(self) -> ProcessResourceWithRawResponse:
+ """Execute and manage processes on the browser instance."""
return ProcessResourceWithRawResponse(self._browsers.process)
@cached_property
def logs(self) -> LogsResourceWithRawResponse:
+ """Stream logs from the browser instance."""
return LogsResourceWithRawResponse(self._browsers.logs)
@cached_property
@@ -980,6 +998,7 @@ def computer(self) -> ComputerResourceWithRawResponse:
@cached_property
def playwright(self) -> PlaywrightResourceWithRawResponse:
+ """Execute Playwright code against the browser instance."""
return PlaywrightResourceWithRawResponse(self._browsers.playwright)
@@ -1013,18 +1032,22 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None:
@cached_property
def replays(self) -> AsyncReplaysResourceWithRawResponse:
+ """Record and manage browser session video replays."""
return AsyncReplaysResourceWithRawResponse(self._browsers.replays)
@cached_property
def fs(self) -> AsyncFsResourceWithRawResponse:
+ """Read, write, and manage files on the browser instance."""
return AsyncFsResourceWithRawResponse(self._browsers.fs)
@cached_property
def process(self) -> AsyncProcessResourceWithRawResponse:
+ """Execute and manage processes on the browser instance."""
return AsyncProcessResourceWithRawResponse(self._browsers.process)
@cached_property
def logs(self) -> AsyncLogsResourceWithRawResponse:
+ """Stream logs from the browser instance."""
return AsyncLogsResourceWithRawResponse(self._browsers.logs)
@cached_property
@@ -1033,6 +1056,7 @@ def computer(self) -> AsyncComputerResourceWithRawResponse:
@cached_property
def playwright(self) -> AsyncPlaywrightResourceWithRawResponse:
+ """Execute Playwright code against the browser instance."""
return AsyncPlaywrightResourceWithRawResponse(self._browsers.playwright)
@@ -1066,18 +1090,22 @@ def __init__(self, browsers: BrowsersResource) -> None:
@cached_property
def replays(self) -> ReplaysResourceWithStreamingResponse:
+ """Record and manage browser session video replays."""
return ReplaysResourceWithStreamingResponse(self._browsers.replays)
@cached_property
def fs(self) -> FsResourceWithStreamingResponse:
+ """Read, write, and manage files on the browser instance."""
return FsResourceWithStreamingResponse(self._browsers.fs)
@cached_property
def process(self) -> ProcessResourceWithStreamingResponse:
+ """Execute and manage processes on the browser instance."""
return ProcessResourceWithStreamingResponse(self._browsers.process)
@cached_property
def logs(self) -> LogsResourceWithStreamingResponse:
+ """Stream logs from the browser instance."""
return LogsResourceWithStreamingResponse(self._browsers.logs)
@cached_property
@@ -1086,6 +1114,7 @@ def computer(self) -> ComputerResourceWithStreamingResponse:
@cached_property
def playwright(self) -> PlaywrightResourceWithStreamingResponse:
+ """Execute Playwright code against the browser instance."""
return PlaywrightResourceWithStreamingResponse(self._browsers.playwright)
@@ -1119,18 +1148,22 @@ def __init__(self, browsers: AsyncBrowsersResource) -> None:
@cached_property
def replays(self) -> AsyncReplaysResourceWithStreamingResponse:
+ """Record and manage browser session video replays."""
return AsyncReplaysResourceWithStreamingResponse(self._browsers.replays)
@cached_property
def fs(self) -> AsyncFsResourceWithStreamingResponse:
+ """Read, write, and manage files on the browser instance."""
return AsyncFsResourceWithStreamingResponse(self._browsers.fs)
@cached_property
def process(self) -> AsyncProcessResourceWithStreamingResponse:
+ """Execute and manage processes on the browser instance."""
return AsyncProcessResourceWithStreamingResponse(self._browsers.process)
@cached_property
def logs(self) -> AsyncLogsResourceWithStreamingResponse:
+ """Stream logs from the browser instance."""
return AsyncLogsResourceWithStreamingResponse(self._browsers.logs)
@cached_property
@@ -1139,4 +1172,5 @@ def computer(self) -> AsyncComputerResourceWithStreamingResponse:
@cached_property
def playwright(self) -> AsyncPlaywrightResourceWithStreamingResponse:
+ """Execute Playwright code against the browser instance."""
return AsyncPlaywrightResourceWithStreamingResponse(self._browsers.playwright)
diff --git a/src/kernel/resources/browsers/fs/fs.py b/src/kernel/resources/browsers/fs/fs.py
index 3501a2a6..1bd16afb 100644
--- a/src/kernel/resources/browsers/fs/fs.py
+++ b/src/kernel/resources/browsers/fs/fs.py
@@ -69,8 +69,11 @@
class FsResource(SyncAPIResource):
+ """Read, write, and manage files on the browser instance."""
+
@cached_property
def watch(self) -> WatchResource:
+ """Read, write, and manage files on the browser instance."""
return WatchResource(self._client)
@cached_property
@@ -628,8 +631,11 @@ def write_file(
class AsyncFsResource(AsyncAPIResource):
+ """Read, write, and manage files on the browser instance."""
+
@cached_property
def watch(self) -> AsyncWatchResource:
+ """Read, write, and manage files on the browser instance."""
return AsyncWatchResource(self._client)
@cached_property
@@ -1231,6 +1237,7 @@ def __init__(self, fs: FsResource) -> None:
@cached_property
def watch(self) -> WatchResourceWithRawResponse:
+ """Read, write, and manage files on the browser instance."""
return WatchResourceWithRawResponse(self._fs.watch)
@@ -1279,6 +1286,7 @@ def __init__(self, fs: AsyncFsResource) -> None:
@cached_property
def watch(self) -> AsyncWatchResourceWithRawResponse:
+ """Read, write, and manage files on the browser instance."""
return AsyncWatchResourceWithRawResponse(self._fs.watch)
@@ -1327,6 +1335,7 @@ def __init__(self, fs: FsResource) -> None:
@cached_property
def watch(self) -> WatchResourceWithStreamingResponse:
+ """Read, write, and manage files on the browser instance."""
return WatchResourceWithStreamingResponse(self._fs.watch)
@@ -1375,4 +1384,5 @@ def __init__(self, fs: AsyncFsResource) -> None:
@cached_property
def watch(self) -> AsyncWatchResourceWithStreamingResponse:
+ """Read, write, and manage files on the browser instance."""
return AsyncWatchResourceWithStreamingResponse(self._fs.watch)
diff --git a/src/kernel/resources/browsers/fs/watch.py b/src/kernel/resources/browsers/fs/watch.py
index 2a5c1e30..ca438673 100644
--- a/src/kernel/resources/browsers/fs/watch.py
+++ b/src/kernel/resources/browsers/fs/watch.py
@@ -24,6 +24,8 @@
class WatchResource(SyncAPIResource):
+ """Read, write, and manage files on the browser instance."""
+
@cached_property
def with_raw_response(self) -> WatchResourceWithRawResponse:
"""
@@ -167,6 +169,8 @@ def stop(
class AsyncWatchResource(AsyncAPIResource):
+ """Read, write, and manage files on the browser instance."""
+
@cached_property
def with_raw_response(self) -> AsyncWatchResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/browsers/logs.py b/src/kernel/resources/browsers/logs.py
index ab97a70d..01328551 100644
--- a/src/kernel/resources/browsers/logs.py
+++ b/src/kernel/resources/browsers/logs.py
@@ -25,6 +25,8 @@
class LogsResource(SyncAPIResource):
+ """Stream logs from the browser instance."""
+
@cached_property
def with_raw_response(self) -> LogsResourceWithRawResponse:
"""
@@ -102,6 +104,8 @@ def stream(
class AsyncLogsResource(AsyncAPIResource):
+ """Stream logs from the browser instance."""
+
@cached_property
def with_raw_response(self) -> AsyncLogsResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/browsers/playwright.py b/src/kernel/resources/browsers/playwright.py
index 5c47e3bf..6979a9de 100644
--- a/src/kernel/resources/browsers/playwright.py
+++ b/src/kernel/resources/browsers/playwright.py
@@ -22,6 +22,8 @@
class PlaywrightResource(SyncAPIResource):
+ """Execute Playwright code against the browser instance."""
+
@cached_property
def with_raw_response(self) -> PlaywrightResourceWithRawResponse:
"""
@@ -96,6 +98,8 @@ def execute(
class AsyncPlaywrightResource(AsyncAPIResource):
+ """Execute Playwright code against the browser instance."""
+
@cached_property
def with_raw_response(self) -> AsyncPlaywrightResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/browsers/process.py b/src/kernel/resources/browsers/process.py
index 9932f40c..86752a5e 100644
--- a/src/kernel/resources/browsers/process.py
+++ b/src/kernel/resources/browsers/process.py
@@ -38,6 +38,8 @@
class ProcessResource(SyncAPIResource):
+ """Execute and manage processes on the browser instance."""
+
@cached_property
def with_raw_response(self) -> ProcessResourceWithRawResponse:
"""
@@ -407,6 +409,8 @@ def stdout_stream(
class AsyncProcessResource(AsyncAPIResource):
+ """Execute and manage processes on the browser instance."""
+
@cached_property
def with_raw_response(self) -> AsyncProcessResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/browsers/replays.py b/src/kernel/resources/browsers/replays.py
index 8a1d1996..743a6668 100644
--- a/src/kernel/resources/browsers/replays.py
+++ b/src/kernel/resources/browsers/replays.py
@@ -31,6 +31,8 @@
class ReplaysResource(SyncAPIResource):
+ """Record and manage browser session video replays."""
+
@cached_property
def with_raw_response(self) -> ReplaysResourceWithRawResponse:
"""
@@ -205,6 +207,8 @@ def stop(
class AsyncReplaysResource(AsyncAPIResource):
+ """Record and manage browser session video replays."""
+
@cached_property
def with_raw_response(self) -> AsyncReplaysResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/credential_providers.py b/src/kernel/resources/credential_providers.py
index 8df7d55c..c7ad4b00 100644
--- a/src/kernel/resources/credential_providers.py
+++ b/src/kernel/resources/credential_providers.py
@@ -27,6 +27,8 @@
class CredentialProvidersResource(SyncAPIResource):
+ """Configure external credential providers like 1Password."""
+
@cached_property
def with_raw_response(self) -> CredentialProvidersResourceWithRawResponse:
"""
@@ -311,6 +313,8 @@ def test(
class AsyncCredentialProvidersResource(AsyncAPIResource):
+ """Configure external credential providers like 1Password."""
+
@cached_property
def with_raw_response(self) -> AsyncCredentialProvidersResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/credentials.py b/src/kernel/resources/credentials.py
index 30e72e84..000c7675 100644
--- a/src/kernel/resources/credentials.py
+++ b/src/kernel/resources/credentials.py
@@ -26,6 +26,8 @@
class CredentialsResource(SyncAPIResource):
+ """Create and manage credentials for authentication."""
+
@cached_property
def with_raw_response(self) -> CredentialsResourceWithRawResponse:
"""
@@ -321,6 +323,8 @@ def totp_code(
class AsyncCredentialsResource(AsyncAPIResource):
+ """Create and manage credentials for authentication."""
+
@cached_property
def with_raw_response(self) -> AsyncCredentialsResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/deployments.py b/src/kernel/resources/deployments.py
index 753eb8b1..b6a72d2d 100644
--- a/src/kernel/resources/deployments.py
+++ b/src/kernel/resources/deployments.py
@@ -30,6 +30,8 @@
class DeploymentsResource(SyncAPIResource):
+ """Create and manage app deployments and stream deployment events."""
+
@cached_property
def with_raw_response(self) -> DeploymentsResourceWithRawResponse:
"""
@@ -293,6 +295,8 @@ def follow(
class AsyncDeploymentsResource(AsyncAPIResource):
+ """Create and manage app deployments and stream deployment events."""
+
@cached_property
def with_raw_response(self) -> AsyncDeploymentsResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/extensions.py b/src/kernel/resources/extensions.py
index 69497b1f..ffdef29e 100644
--- a/src/kernel/resources/extensions.py
+++ b/src/kernel/resources/extensions.py
@@ -34,6 +34,8 @@
class ExtensionsResource(SyncAPIResource):
+ """Create, list, retrieve, and delete browser extensions."""
+
@cached_property
def with_raw_response(self) -> ExtensionsResourceWithRawResponse:
"""
@@ -241,6 +243,8 @@ def upload(
class AsyncExtensionsResource(AsyncAPIResource):
+ """Create, list, retrieve, and delete browser extensions."""
+
@cached_property
def with_raw_response(self) -> AsyncExtensionsResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/invocations.py b/src/kernel/resources/invocations.py
index 3194026d..25be409f 100644
--- a/src/kernel/resources/invocations.py
+++ b/src/kernel/resources/invocations.py
@@ -32,6 +32,8 @@
class InvocationsResource(SyncAPIResource):
+ """Invoke actions and stream or query invocation status and events."""
+
@cached_property
def with_raw_response(self) -> InvocationsResourceWithRawResponse:
"""
@@ -383,6 +385,8 @@ def list_browsers(
class AsyncInvocationsResource(AsyncAPIResource):
+ """Invoke actions and stream or query invocation status and events."""
+
@cached_property
def with_raw_response(self) -> AsyncInvocationsResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/profiles.py b/src/kernel/resources/profiles.py
index e9b124b5..f75569f2 100644
--- a/src/kernel/resources/profiles.py
+++ b/src/kernel/resources/profiles.py
@@ -31,6 +31,8 @@
class ProfilesResource(SyncAPIResource):
+ """Create, list, retrieve, and delete browser profiles."""
+
@cached_property
def with_raw_response(self) -> ProfilesResourceWithRawResponse:
"""
@@ -241,6 +243,8 @@ def download(
class AsyncProfilesResource(AsyncAPIResource):
+ """Create, list, retrieve, and delete browser profiles."""
+
@cached_property
def with_raw_response(self) -> AsyncProfilesResourceWithRawResponse:
"""
diff --git a/src/kernel/resources/proxies.py b/src/kernel/resources/proxies.py
index d42f7b04..0c2508c0 100644
--- a/src/kernel/resources/proxies.py
+++ b/src/kernel/resources/proxies.py
@@ -27,6 +27,8 @@
class ProxiesResource(SyncAPIResource):
+ """Create and manage proxy configurations for routing browser traffic."""
+
@cached_property
def with_raw_response(self) -> ProxiesResourceWithRawResponse:
"""
@@ -224,6 +226,8 @@ def check(
class AsyncProxiesResource(AsyncAPIResource):
+ """Create and manage proxy configurations for routing browser traffic."""
+
@cached_property
def with_raw_response(self) -> AsyncProxiesResourceWithRawResponse:
"""
From 077a61c3c3f287eaddd3f90cf4f5cf04dc7baf39 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 3 Mar 2026 18:32:31 +0000
Subject: [PATCH 2/5] feat: [kernel-1028] add api clipboard support
---
.stats.yml | 8 +-
api.md | 3 +
src/kernel/resources/browsers/computer.py | 170 +++++++++++++++++
src/kernel/types/browsers/__init__.py | 2 +
.../computer_read_clipboard_response.py | 10 +
.../computer_write_clipboard_params.py | 12 ++
tests/api_resources/browsers/test_computer.py | 177 ++++++++++++++++++
7 files changed, 378 insertions(+), 4 deletions(-)
create mode 100644 src/kernel/types/browsers/computer_read_clipboard_response.py
create mode 100644 src/kernel/types/browsers/computer_write_clipboard_params.py
diff --git a/.stats.yml b/.stats.yml
index d4eead98..a08c103b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 101
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-a935c8aae21f8ddb83ea5e289034df12cbde88d432fa2b287629814bb3f58bb6.yml
-openapi_spec_hash: df3189b9728372f01662a19c060bcbc5
-config_hash: 81f143f4bee47ae7b0b8357551babadf
+configured_endpoints: 103
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-f05b888046776a18dbffc1264a27c0256839d132066ef5f6e09ccf1bc505a8f7.yml
+openapi_spec_hash: 646fce3982d3efbdb38004b0e4ac4d17
+config_hash: cff4d43372b6fa66b64e2d4150f6aa76
diff --git a/api.md b/api.md
index 511ab51f..cce73021 100644
--- a/api.md
+++ b/api.md
@@ -192,6 +192,7 @@ Types:
```python
from kernel.types.browsers import (
ComputerGetMousePositionResponse,
+ ComputerReadClipboardResponse,
ComputerSetCursorVisibilityResponse,
)
```
@@ -205,9 +206,11 @@ Methods:
- client.browsers.computer.get_mouse_position(id) -> ComputerGetMousePositionResponse
- client.browsers.computer.move_mouse(id, \*\*params) -> None
- client.browsers.computer.press_key(id, \*\*params) -> None
+- client.browsers.computer.read_clipboard(id) -> ComputerReadClipboardResponse
- client.browsers.computer.scroll(id, \*\*params) -> None
- client.browsers.computer.set_cursor_visibility(id, \*\*params) -> ComputerSetCursorVisibilityResponse
- client.browsers.computer.type_text(id, \*\*params) -> None
+- client.browsers.computer.write_clipboard(id, \*\*params) -> None
## Playwright
diff --git a/src/kernel/resources/browsers/computer.py b/src/kernel/resources/browsers/computer.py
index 933767f0..cc61834b 100644
--- a/src/kernel/resources/browsers/computer.py
+++ b/src/kernel/resources/browsers/computer.py
@@ -34,9 +34,11 @@
computer_drag_mouse_params,
computer_move_mouse_params,
computer_click_mouse_params,
+ computer_write_clipboard_params,
computer_capture_screenshot_params,
computer_set_cursor_visibility_params,
)
+from ...types.browsers.computer_read_clipboard_response import ComputerReadClipboardResponse
from ...types.browsers.computer_get_mouse_position_response import ComputerGetMousePositionResponse
from ...types.browsers.computer_set_cursor_visibility_response import ComputerSetCursorVisibilityResponse
@@ -408,6 +410,39 @@ def press_key(
cast_to=NoneType,
)
+ def read_clipboard(
+ self,
+ id: str,
+ *,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ComputerReadClipboardResponse:
+ """
+ Read text from the clipboard on the browser instance
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ 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}")
+ return self._post(
+ f"/browsers/{id}/computer/clipboard/read",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ComputerReadClipboardResponse,
+ )
+
def scroll(
self,
id: str,
@@ -553,6 +588,44 @@ def type_text(
cast_to=NoneType,
)
+ def write_clipboard(
+ self,
+ id: str,
+ *,
+ text: str,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Write text to the clipboard on the browser instance
+
+ Args:
+ text: Text to write to the system clipboard
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ 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}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._post(
+ f"/browsers/{id}/computer/clipboard/write",
+ body=maybe_transform({"text": text}, computer_write_clipboard_params.ComputerWriteClipboardParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
class AsyncComputerResource(AsyncAPIResource):
@cached_property
@@ -919,6 +992,39 @@ async def press_key(
cast_to=NoneType,
)
+ async def read_clipboard(
+ self,
+ id: str,
+ *,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> ComputerReadClipboardResponse:
+ """
+ Read text from the clipboard on the browser instance
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ 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}")
+ return await self._post(
+ f"/browsers/{id}/computer/clipboard/read",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ComputerReadClipboardResponse,
+ )
+
async def scroll(
self,
id: str,
@@ -1064,6 +1170,46 @@ async def type_text(
cast_to=NoneType,
)
+ async def write_clipboard(
+ self,
+ id: str,
+ *,
+ text: str,
+ # 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> None:
+ """
+ Write text to the clipboard on the browser instance
+
+ Args:
+ text: Text to write to the system clipboard
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ 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}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._post(
+ f"/browsers/{id}/computer/clipboard/write",
+ body=await async_maybe_transform(
+ {"text": text}, computer_write_clipboard_params.ComputerWriteClipboardParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
class ComputerResourceWithRawResponse:
def __init__(self, computer: ComputerResource) -> None:
@@ -1091,6 +1237,9 @@ def __init__(self, computer: ComputerResource) -> None:
self.press_key = to_raw_response_wrapper(
computer.press_key,
)
+ self.read_clipboard = to_raw_response_wrapper(
+ computer.read_clipboard,
+ )
self.scroll = to_raw_response_wrapper(
computer.scroll,
)
@@ -1100,6 +1249,9 @@ def __init__(self, computer: ComputerResource) -> None:
self.type_text = to_raw_response_wrapper(
computer.type_text,
)
+ self.write_clipboard = to_raw_response_wrapper(
+ computer.write_clipboard,
+ )
class AsyncComputerResourceWithRawResponse:
@@ -1128,6 +1280,9 @@ def __init__(self, computer: AsyncComputerResource) -> None:
self.press_key = async_to_raw_response_wrapper(
computer.press_key,
)
+ self.read_clipboard = async_to_raw_response_wrapper(
+ computer.read_clipboard,
+ )
self.scroll = async_to_raw_response_wrapper(
computer.scroll,
)
@@ -1137,6 +1292,9 @@ def __init__(self, computer: AsyncComputerResource) -> None:
self.type_text = async_to_raw_response_wrapper(
computer.type_text,
)
+ self.write_clipboard = async_to_raw_response_wrapper(
+ computer.write_clipboard,
+ )
class ComputerResourceWithStreamingResponse:
@@ -1165,6 +1323,9 @@ def __init__(self, computer: ComputerResource) -> None:
self.press_key = to_streamed_response_wrapper(
computer.press_key,
)
+ self.read_clipboard = to_streamed_response_wrapper(
+ computer.read_clipboard,
+ )
self.scroll = to_streamed_response_wrapper(
computer.scroll,
)
@@ -1174,6 +1335,9 @@ def __init__(self, computer: ComputerResource) -> None:
self.type_text = to_streamed_response_wrapper(
computer.type_text,
)
+ self.write_clipboard = to_streamed_response_wrapper(
+ computer.write_clipboard,
+ )
class AsyncComputerResourceWithStreamingResponse:
@@ -1202,6 +1366,9 @@ def __init__(self, computer: AsyncComputerResource) -> None:
self.press_key = async_to_streamed_response_wrapper(
computer.press_key,
)
+ self.read_clipboard = async_to_streamed_response_wrapper(
+ computer.read_clipboard,
+ )
self.scroll = async_to_streamed_response_wrapper(
computer.scroll,
)
@@ -1211,3 +1378,6 @@ def __init__(self, computer: AsyncComputerResource) -> None:
self.type_text = async_to_streamed_response_wrapper(
computer.type_text,
)
+ self.write_clipboard = async_to_streamed_response_wrapper(
+ computer.write_clipboard,
+ )
diff --git a/src/kernel/types/browsers/__init__.py b/src/kernel/types/browsers/__init__.py
index 3daee051..1e47205d 100644
--- a/src/kernel/types/browsers/__init__.py
+++ b/src/kernel/types/browsers/__init__.py
@@ -41,6 +41,8 @@
from .playwright_execute_response import PlaywrightExecuteResponse as PlaywrightExecuteResponse
from .f_set_file_permissions_params import FSetFilePermissionsParams as FSetFilePermissionsParams
from .process_stdout_stream_response import ProcessStdoutStreamResponse as ProcessStdoutStreamResponse
+from .computer_write_clipboard_params import ComputerWriteClipboardParams as ComputerWriteClipboardParams
+from .computer_read_clipboard_response import ComputerReadClipboardResponse as ComputerReadClipboardResponse
from .computer_capture_screenshot_params import ComputerCaptureScreenshotParams as ComputerCaptureScreenshotParams
from .computer_get_mouse_position_response import ComputerGetMousePositionResponse as ComputerGetMousePositionResponse
from .computer_set_cursor_visibility_params import (
diff --git a/src/kernel/types/browsers/computer_read_clipboard_response.py b/src/kernel/types/browsers/computer_read_clipboard_response.py
new file mode 100644
index 00000000..e5210090
--- /dev/null
+++ b/src/kernel/types/browsers/computer_read_clipboard_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ..._models import BaseModel
+
+__all__ = ["ComputerReadClipboardResponse"]
+
+
+class ComputerReadClipboardResponse(BaseModel):
+ text: str
+ """Current clipboard text content"""
diff --git a/src/kernel/types/browsers/computer_write_clipboard_params.py b/src/kernel/types/browsers/computer_write_clipboard_params.py
new file mode 100644
index 00000000..81f7b095
--- /dev/null
+++ b/src/kernel/types/browsers/computer_write_clipboard_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 Required, TypedDict
+
+__all__ = ["ComputerWriteClipboardParams"]
+
+
+class ComputerWriteClipboardParams(TypedDict, total=False):
+ text: Required[str]
+ """Text to write to the system clipboard"""
diff --git a/tests/api_resources/browsers/test_computer.py b/tests/api_resources/browsers/test_computer.py
index 091fc91d..32a4ca9c 100644
--- a/tests/api_resources/browsers/test_computer.py
+++ b/tests/api_resources/browsers/test_computer.py
@@ -18,6 +18,7 @@
AsyncStreamedBinaryAPIResponse,
)
from kernel.types.browsers import (
+ ComputerReadClipboardResponse,
ComputerGetMousePositionResponse,
ComputerSetCursorVisibilityResponse,
)
@@ -426,6 +427,48 @@ def test_path_params_press_key(self, client: Kernel) -> None:
keys=["string"],
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_read_clipboard(self, client: Kernel) -> None:
+ computer = client.browsers.computer.read_clipboard(
+ "id",
+ )
+ assert_matches_type(ComputerReadClipboardResponse, computer, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_read_clipboard(self, client: Kernel) -> None:
+ response = client.browsers.computer.with_raw_response.read_clipboard(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ computer = response.parse()
+ assert_matches_type(ComputerReadClipboardResponse, computer, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_read_clipboard(self, client: Kernel) -> None:
+ with client.browsers.computer.with_streaming_response.read_clipboard(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ computer = response.parse()
+ assert_matches_type(ComputerReadClipboardResponse, computer, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_read_clipboard(self, client: Kernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.browsers.computer.with_raw_response.read_clipboard(
+ "",
+ )
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_scroll(self, client: Kernel) -> None:
@@ -591,6 +634,52 @@ def test_path_params_type_text(self, client: Kernel) -> None:
text="text",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_write_clipboard(self, client: Kernel) -> None:
+ computer = client.browsers.computer.write_clipboard(
+ id="id",
+ text="text",
+ )
+ assert computer is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_write_clipboard(self, client: Kernel) -> None:
+ response = client.browsers.computer.with_raw_response.write_clipboard(
+ id="id",
+ text="text",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ computer = response.parse()
+ assert computer is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_write_clipboard(self, client: Kernel) -> None:
+ with client.browsers.computer.with_streaming_response.write_clipboard(
+ id="id",
+ text="text",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ computer = response.parse()
+ assert computer is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_write_clipboard(self, client: Kernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.browsers.computer.with_raw_response.write_clipboard(
+ id="",
+ text="text",
+ )
+
class TestAsyncComputer:
parametrize = pytest.mark.parametrize(
@@ -999,6 +1088,48 @@ async def test_path_params_press_key(self, async_client: AsyncKernel) -> None:
keys=["string"],
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_read_clipboard(self, async_client: AsyncKernel) -> None:
+ computer = await async_client.browsers.computer.read_clipboard(
+ "id",
+ )
+ assert_matches_type(ComputerReadClipboardResponse, computer, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_read_clipboard(self, async_client: AsyncKernel) -> None:
+ response = await async_client.browsers.computer.with_raw_response.read_clipboard(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ computer = await response.parse()
+ assert_matches_type(ComputerReadClipboardResponse, computer, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_read_clipboard(self, async_client: AsyncKernel) -> None:
+ async with async_client.browsers.computer.with_streaming_response.read_clipboard(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ computer = await response.parse()
+ assert_matches_type(ComputerReadClipboardResponse, computer, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_read_clipboard(self, async_client: AsyncKernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.browsers.computer.with_raw_response.read_clipboard(
+ "",
+ )
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_scroll(self, async_client: AsyncKernel) -> None:
@@ -1163,3 +1294,49 @@ async def test_path_params_type_text(self, async_client: AsyncKernel) -> None:
id="",
text="text",
)
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_write_clipboard(self, async_client: AsyncKernel) -> None:
+ computer = await async_client.browsers.computer.write_clipboard(
+ id="id",
+ text="text",
+ )
+ assert computer is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_write_clipboard(self, async_client: AsyncKernel) -> None:
+ response = await async_client.browsers.computer.with_raw_response.write_clipboard(
+ id="id",
+ text="text",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ computer = await response.parse()
+ assert computer is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_write_clipboard(self, async_client: AsyncKernel) -> None:
+ async with async_client.browsers.computer.with_streaming_response.write_clipboard(
+ id="id",
+ text="text",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ computer = await response.parse()
+ assert computer is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_write_clipboard(self, async_client: AsyncKernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.browsers.computer.with_raw_response.write_clipboard(
+ id="",
+ text="text",
+ )
From 8b3db281a64cafba5dac7effdc264f30a94c38ea Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 3 Mar 2026 22:37:29 +0000
Subject: [PATCH 3/5] feat: expose smooth mouse movement via public API
---
.stats.yml | 4 ++--
src/kernel/resources/browsers/computer.py | 18 ++++++++++++++++++
.../types/browsers/computer_batch_params.py | 9 +++++++++
.../browsers/computer_move_mouse_params.py | 9 +++++++++
tests/api_resources/browsers/test_computer.py | 4 ++++
5 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index a08c103b..d2f972b9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 103
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-f05b888046776a18dbffc1264a27c0256839d132066ef5f6e09ccf1bc505a8f7.yml
-openapi_spec_hash: 646fce3982d3efbdb38004b0e4ac4d17
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-2ba004ce5444b5f8abe3bcf66fd7c6da394bc964e8b2bf197576841135a48046.yml
+openapi_spec_hash: f156ea2ae35e4d148704c6e4ce051239
config_hash: cff4d43372b6fa66b64e2d4150f6aa76
diff --git a/src/kernel/resources/browsers/computer.py b/src/kernel/resources/browsers/computer.py
index cc61834b..1357c1e8 100644
--- a/src/kernel/resources/browsers/computer.py
+++ b/src/kernel/resources/browsers/computer.py
@@ -310,7 +310,9 @@ def move_mouse(
*,
x: int,
y: int,
+ duration_ms: int | Omit = omit,
hold_keys: SequenceNotStr[str] | Omit = omit,
+ smooth: 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,
@@ -326,8 +328,13 @@ def move_mouse(
y: Y coordinate to move the cursor to
+ duration_ms: Target total duration in milliseconds for the mouse movement when smooth=true.
+ Omit for automatic timing based on distance.
+
hold_keys: Modifier keys to hold during the move
+ smooth: Use human-like Bezier curve path instead of instant mouse movement.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -345,7 +352,9 @@ def move_mouse(
{
"x": x,
"y": y,
+ "duration_ms": duration_ms,
"hold_keys": hold_keys,
+ "smooth": smooth,
},
computer_move_mouse_params.ComputerMoveMouseParams,
),
@@ -892,7 +901,9 @@ async def move_mouse(
*,
x: int,
y: int,
+ duration_ms: int | Omit = omit,
hold_keys: SequenceNotStr[str] | Omit = omit,
+ smooth: 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,
@@ -908,8 +919,13 @@ async def move_mouse(
y: Y coordinate to move the cursor to
+ duration_ms: Target total duration in milliseconds for the mouse movement when smooth=true.
+ Omit for automatic timing based on distance.
+
hold_keys: Modifier keys to hold during the move
+ smooth: Use human-like Bezier curve path instead of instant mouse movement.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -927,7 +943,9 @@ async def move_mouse(
{
"x": x,
"y": y,
+ "duration_ms": duration_ms,
"hold_keys": hold_keys,
+ "smooth": smooth,
},
computer_move_mouse_params.ComputerMoveMouseParams,
),
diff --git a/src/kernel/types/browsers/computer_batch_params.py b/src/kernel/types/browsers/computer_batch_params.py
index 601cd2b9..9aca7244 100644
--- a/src/kernel/types/browsers/computer_batch_params.py
+++ b/src/kernel/types/browsers/computer_batch_params.py
@@ -79,9 +79,18 @@ class ActionMoveMouse(TypedDict, total=False):
y: Required[int]
"""Y coordinate to move the cursor to"""
+ duration_ms: int
+ """Target total duration in milliseconds for the mouse movement when smooth=true.
+
+ Omit for automatic timing based on distance.
+ """
+
hold_keys: SequenceNotStr[str]
"""Modifier keys to hold during the move"""
+ smooth: bool
+ """Use human-like Bezier curve path instead of instant mouse movement."""
+
class ActionPressKey(TypedDict, total=False):
keys: Required[SequenceNotStr[str]]
diff --git a/src/kernel/types/browsers/computer_move_mouse_params.py b/src/kernel/types/browsers/computer_move_mouse_params.py
index 1769e074..3a4f99e5 100644
--- a/src/kernel/types/browsers/computer_move_mouse_params.py
+++ b/src/kernel/types/browsers/computer_move_mouse_params.py
@@ -16,5 +16,14 @@ class ComputerMoveMouseParams(TypedDict, total=False):
y: Required[int]
"""Y coordinate to move the cursor to"""
+ duration_ms: int
+ """Target total duration in milliseconds for the mouse movement when smooth=true.
+
+ Omit for automatic timing based on distance.
+ """
+
hold_keys: SequenceNotStr[str]
"""Modifier keys to hold during the move"""
+
+ smooth: bool
+ """Use human-like Bezier curve path instead of instant mouse movement."""
diff --git a/tests/api_resources/browsers/test_computer.py b/tests/api_resources/browsers/test_computer.py
index 32a4ca9c..09960bfc 100644
--- a/tests/api_resources/browsers/test_computer.py
+++ b/tests/api_resources/browsers/test_computer.py
@@ -326,7 +326,9 @@ def test_method_move_mouse_with_all_params(self, client: Kernel) -> None:
id="id",
x=0,
y=0,
+ duration_ms=50,
hold_keys=["string"],
+ smooth=True,
)
assert computer is None
@@ -987,7 +989,9 @@ async def test_method_move_mouse_with_all_params(self, async_client: AsyncKernel
id="id",
x=0,
y=0,
+ duration_ms=50,
hold_keys=["string"],
+ smooth=True,
)
assert computer is None
From c4b8c62622354859847c13234ee9f54611f4175f Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 5 Mar 2026 15:43:01 +0000
Subject: [PATCH 4/5] feat: add force flag to viewport resize to bypass live
view/recording check
---
.stats.yml | 4 ++--
src/kernel/resources/browsers/browsers.py | 4 ++--
src/kernel/types/browser_update_params.py | 16 ++++++++++++++--
tests/api_resources/test_browsers.py | 2 ++
4 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index d2f972b9..e1ce185b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 103
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-2ba004ce5444b5f8abe3bcf66fd7c6da394bc964e8b2bf197576841135a48046.yml
-openapi_spec_hash: f156ea2ae35e4d148704c6e4ce051239
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-ef24d4bf172555bcbe8e3b432c644a25a1c6afd99c958a2eda8c3b1ea9568113.yml
+openapi_spec_hash: b603c5a983e837928fa7d1100ed64fc9
config_hash: cff4d43372b6fa66b64e2d4150f6aa76
diff --git a/src/kernel/resources/browsers/browsers.py b/src/kernel/resources/browsers/browsers.py
index 32855ee8..235da236 100644
--- a/src/kernel/resources/browsers/browsers.py
+++ b/src/kernel/resources/browsers/browsers.py
@@ -284,7 +284,7 @@ def update(
*,
profile: BrowserProfile | Omit = omit,
proxy_id: Optional[str] | Omit = omit,
- viewport: BrowserViewport | Omit = omit,
+ viewport: browser_update_params.Viewport | 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,
@@ -711,7 +711,7 @@ async def update(
*,
profile: BrowserProfile | Omit = omit,
proxy_id: Optional[str] | Omit = omit,
- viewport: BrowserViewport | Omit = omit,
+ viewport: browser_update_params.Viewport | 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,
diff --git a/src/kernel/types/browser_update_params.py b/src/kernel/types/browser_update_params.py
index 917cd7da..5c211948 100644
--- a/src/kernel/types/browser_update_params.py
+++ b/src/kernel/types/browser_update_params.py
@@ -8,7 +8,7 @@
from .shared_params.browser_profile import BrowserProfile
from .shared_params.browser_viewport import BrowserViewport
-__all__ = ["BrowserUpdateParams"]
+__all__ = ["BrowserUpdateParams", "Viewport"]
class BrowserUpdateParams(TypedDict, total=False):
@@ -24,5 +24,17 @@ class BrowserUpdateParams(TypedDict, total=False):
Omit to leave unchanged, set to empty string to remove proxy.
"""
- viewport: BrowserViewport
+ viewport: Viewport
"""Viewport configuration to apply to the browser session."""
+
+
+class Viewport(BrowserViewport, total=False):
+ """Viewport configuration to apply to the browser session."""
+
+ force: bool
+ """
+ If true, allow the viewport change even when a live view or recording/replay is
+ active. Active recordings will be gracefully stopped and restarted at the new
+ resolution as separate segments. If false (default), the resize is refused when
+ a live view or recording is active.
+ """
diff --git a/tests/api_resources/test_browsers.py b/tests/api_resources/test_browsers.py
index 2addbb87..1e612ff2 100644
--- a/tests/api_resources/test_browsers.py
+++ b/tests/api_resources/test_browsers.py
@@ -158,6 +158,7 @@ def test_method_update_with_all_params(self, client: Kernel) -> None:
"height": 800,
"width": 1280,
"refresh_rate": 60,
+ "force": True,
},
)
assert_matches_type(BrowserUpdateResponse, browser, path=["response"])
@@ -521,6 +522,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) ->
"height": 800,
"width": 1280,
"refresh_rate": 60,
+ "force": True,
},
)
assert_matches_type(BrowserUpdateResponse, browser, path=["response"])
From 474dcda4ebe5a117ec930a4b92d258d4487c42fa Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 5 Mar 2026 15:47:13 +0000
Subject: [PATCH 5/5] release: 0.42.1
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 15 +++++++++++++++
pyproject.toml | 2 +-
src/kernel/_version.py | 2 +-
4 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 52afe059..dc28bb87 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.42.0"
+ ".": "0.42.1"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5c4d947..338a74af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
# Changelog
+## 0.42.1 (2026-03-05)
+
+Full Changelog: [v0.42.0...v0.42.1](https://github.com/kernel/kernel-python-sdk/compare/v0.42.0...v0.42.1)
+
+### Features
+
+* [kernel-1028] add api clipboard support ([077a61c](https://github.com/kernel/kernel-python-sdk/commit/077a61c3c3f287eaddd3f90cf4f5cf04dc7baf39))
+* add force flag to viewport resize to bypass live view/recording check ([c4b8c62](https://github.com/kernel/kernel-python-sdk/commit/c4b8c62622354859847c13234ee9f54611f4175f))
+* expose smooth mouse movement via public API ([8b3db28](https://github.com/kernel/kernel-python-sdk/commit/8b3db281a64cafba5dac7effdc264f30a94c38ea))
+
+
+### Chores
+
+* **internal:** codegen related update ([e9265c4](https://github.com/kernel/kernel-python-sdk/commit/e9265c4ffba59e8cfd8a02e12653b83a471aced3))
+
## 0.42.0 (2026-03-02)
Full Changelog: [v0.41.0...v0.42.0](https://github.com/kernel/kernel-python-sdk/compare/v0.41.0...v0.42.0)
diff --git a/pyproject.toml b/pyproject.toml
index 968ba8d8..225ad6fb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "kernel"
-version = "0.42.0"
+version = "0.42.1"
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 7a26ebd7..e6149c73 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.42.0" # x-release-please-version
+__version__ = "0.42.1" # x-release-please-version