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.92.0"
".": "0.93.0"
}
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## [0.93.0](https://github.com/kernel/kernel-python-sdk/compare/v0.92.0...v0.93.0) (2026-08-19)


### Features

* Add proxy_error to browser telemetry event schema ([5973ab6](https://github.com/kernel/kernel-python-sdk/commit/5973ab6c766ee31929a523e3ea21fb000bc6879a))
* Bind managed auth submissions to interactions ([63fb060](https://github.com/kernel/kernel-python-sdk/commit/63fb0606910b17a99f7a584e425fbd77e2d562e5))
* Harden canonical managed auth interactions ([3522fcb](https://github.com/kernel/kernel-python-sdk/commit/3522fcb9e70854ad2900585f5b37222e7f0e1b26))

## [0.92.0](https://github.com/kernel/kernel-python-sdk/compare/v0.91.0...v0.92.0) (2026-08-17)


Expand Down
1 change: 1 addition & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ from kernel.types.browsers import (
BrowserPageNavigationEvent,
BrowserPageNavigationSettledEvent,
BrowserPageTabOpenedEvent,
BrowserProxyErrorEvent,
BrowserServiceCrashedEvent,
BrowserSystemOomKillEvent,
BrowserTelemetryCategoriesConfig,
Expand Down
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.92.0"
version = "0.93.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.92.0" # x-release-please-version
__version__ = "0.93.0" # x-release-please-version
10 changes: 10 additions & 0 deletions src/kernel/resources/auth/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ def submit(
*,
field_values: Dict[str, str] | Omit = omit,
fields: Dict[str, str] | Omit = omit,
interaction_id: str | Omit = omit,
mfa_option_id: str | Omit = omit,
selected_choice_id: str | Omit = omit,
sign_in_option_id: str | Omit = omit,
Expand All @@ -552,6 +553,9 @@ def submit(

fields: Map of field name to value

interaction_id: Opaque interaction ID returned with canonical fields and choices. Required for
canonical submissions.

mfa_option_id: The MFA method type to select (when mfa_options were returned)

selected_choice_id: Canonical choice ID selected by the user.
Expand Down Expand Up @@ -580,6 +584,7 @@ def submit(
{
"field_values": field_values,
"fields": fields,
"interaction_id": interaction_id,
"mfa_option_id": mfa_option_id,
"selected_choice_id": selected_choice_id,
"sign_in_option_id": sign_in_option_id,
Expand Down Expand Up @@ -1143,6 +1148,7 @@ async def submit(
*,
field_values: Dict[str, str] | Omit = omit,
fields: Dict[str, str] | Omit = omit,
interaction_id: str | Omit = omit,
mfa_option_id: str | Omit = omit,
selected_choice_id: str | Omit = omit,
sign_in_option_id: str | Omit = omit,
Expand All @@ -1165,6 +1171,9 @@ async def submit(

fields: Map of field name to value

interaction_id: Opaque interaction ID returned with canonical fields and choices. Required for
canonical submissions.

mfa_option_id: The MFA method type to select (when mfa_options were returned)

selected_choice_id: Canonical choice ID selected by the user.
Expand Down Expand Up @@ -1193,6 +1202,7 @@ async def submit(
{
"field_values": field_values,
"fields": fields,
"interaction_id": interaction_id,
"mfa_option_id": mfa_option_id,
"selected_choice_id": selected_choice_id,
"sign_in_option_id": sign_in_option_id,
Expand Down
16 changes: 10 additions & 6 deletions src/kernel/types/auth/connection_follow_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ class ManagedAuthStateEventField(BaseModel):
id: str
"""Stable field identifier for canonical submit."""

reason: Literal["missing", "rejected"]
"""Why the field requires user input."""

ref: str
"""Credential reference name to store the submitted value under."""

Expand All @@ -112,12 +115,6 @@ class ManagedAuthStateEventField(BaseModel):
observed_selector: Optional[str] = None
"""Selector for the visible field, when available."""

replace_existing: Optional[bool] = None
"""
Whether the submitted value must replace an existing credential after explicit
rejection.
"""

required: Optional[bool] = None
"""Whether this field is required."""

Expand Down Expand Up @@ -224,6 +221,13 @@ class ManagedAuthStateEvent(BaseModel):
hosted_url: Optional[str] = None
"""URL to redirect user to for hosted login."""

interaction_id: Optional[str] = None
"""Opaque identifier for the current canonical interaction.

Required when submitting fields or choices and changes for each new actionable
pause.
"""

live_view_url: Optional[str] = None
"""Browser live view URL for debugging."""

Expand Down
6 changes: 6 additions & 0 deletions src/kernel/types/auth/connection_submit_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ class ConnectionSubmitParams(TypedDict, total=False):
fields: Dict[str, str]
"""Map of field name to value"""

interaction_id: str
"""Opaque interaction ID returned with canonical fields and choices.

Required for canonical submissions.
"""

mfa_option_id: str
"""The MFA method type to select (when mfa_options were returned)"""

Expand Down
16 changes: 10 additions & 6 deletions src/kernel/types/auth/managed_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ class Field(BaseModel):
id: str
"""Stable field identifier for canonical submit."""

reason: Literal["missing", "rejected"]
"""Why the field requires user input."""

ref: str
"""Credential reference name to store the submitted value under."""

Expand All @@ -221,12 +224,6 @@ class Field(BaseModel):
observed_selector: Optional[str] = None
"""Selector for the visible field, when available."""

replace_existing: Optional[bool] = None
"""
Whether the submitted value must replace an existing credential after explicit
rejection.
"""

required: Optional[bool] = None
"""Whether this field is required."""

Expand Down Expand Up @@ -504,6 +501,13 @@ class ManagedAuth(BaseModel):
hosted_url: Optional[str] = None
"""URL to redirect user to for hosted login (present when flow in progress)"""

interaction_id: Optional[str] = None
"""Opaque identifier for the current canonical interaction.

Required when submitting fields or choices and changes for each new actionable
pause.
"""

last_auth_at: Optional[datetime] = None
"""Deprecated alias for `last_auth_check_at`.

Expand Down
1 change: 1 addition & 0 deletions src/kernel/types/browsers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from .browser_telemetry_config import BrowserTelemetryConfig as BrowserTelemetryConfig
from .browser_cdp_connect_event import BrowserCdpConnectEvent as BrowserCdpConnectEvent
from .browser_console_log_event import BrowserConsoleLogEvent as BrowserConsoleLogEvent
from .browser_proxy_error_event import BrowserProxyErrorEvent as BrowserProxyErrorEvent
from .computer_press_key_params import ComputerPressKeyParams as ComputerPressKeyParams
from .computer_type_text_params import ComputerTypeTextParams as ComputerTypeTextParams
from .f_create_directory_params import FCreateDirectoryParams as FCreateDirectoryParams
Expand Down
73 changes: 73 additions & 0 deletions src/kernel/types/browsers/browser_proxy_error_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

from typing import Optional
from typing_extensions import Literal

from ..._models import BaseModel
from .browser_event_source import BrowserEventSource
from .browser_event_context import BrowserEventContext

__all__ = ["BrowserProxyErrorEvent", "Data"]


class Data(BrowserEventContext):
"""Browser event context stamped by the browser monitor onto all CDP-sourced events.

Identifies the target, frame, and navigation epoch in which the event occurred.
"""

code: Literal[
"destination_blocked",
"provider_blacklisted",
"provider_unreachable",
"proxy_unavailable",
"upstream_timeout",
"upstream_dns_failure",
"upstream_connect_failed",
]
"""
Proxy-layer error code: the X-Kernel-Proxy-Error response header value from a
branded 5xx error page served by the metro egress host-proxy. Values mirror what
the proxy emits: destination_blocked, provider_blacklisted,
provider_unreachable, proxy_unavailable, upstream_timeout, upstream_dns_failure,
upstream_connect_failed. Unknown header values are dropped.
"""

request_id: str
"""CDP request identifier matching the originating request."""

status: int
"""HTTP response status of the branded error page (502)."""

method: Optional[str] = None
"""HTTP method of the failed request, when known."""

resource_type: Optional[str] = None
"""CDP Network.ResourceType for the request, when known."""


class BrowserProxyErrorEvent(BaseModel):
"""A branded proxy-layer failure observed by the browser.

Emitted when the metro egress host-proxy serves a branded 5xx error page whose response carries the X-Kernel-Proxy-Error header. Low-volume and carries a typed code. Its value is per-session and per-URL attribution for sessions that already capture the network stream: proxy failures are only observable while the CDP network collector is running, so this is an opt-in refinement of the raw network events rather than a default-on alerting signal.
"""

category: Literal["network"]

source: BrowserEventSource
"""Provenance metadata identifying which producer emitted the event."""

ts: int
"""Event timestamp in Unix microseconds."""

type: Literal["proxy_error"]

data: Optional[Data] = None
"""Browser event context stamped by the browser monitor onto all CDP-sourced
events.

Identifies the target, frame, and navigation epoch in which the event occurred.
"""

truncated: Optional[bool] = None
"""True if the data field was truncated due to size limits."""
2 changes: 2 additions & 0 deletions src/kernel/types/browsers/browser_telemetry_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .browser_page_load_event import BrowserPageLoadEvent
from .browser_cdp_connect_event import BrowserCdpConnectEvent
from .browser_console_log_event import BrowserConsoleLogEvent
from .browser_proxy_error_event import BrowserProxyErrorEvent
from .browser_network_idle_event import BrowserNetworkIdleEvent
from .browser_console_error_event import BrowserConsoleErrorEvent
from .browser_cdp_disconnect_event import BrowserCdpDisconnectEvent
Expand Down Expand Up @@ -47,6 +48,7 @@
BrowserNetworkResponseEvent,
BrowserNetworkLoadingFailedEvent,
BrowserNetworkIdleEvent,
BrowserProxyErrorEvent,
BrowserPageNavigationEvent,
BrowserPageDomContentLoadedEvent,
BrowserPageLoadEvent,
Expand Down
2 changes: 2 additions & 0 deletions tests/api_resources/auth/test_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ def test_method_submit_with_all_params(self, client: Kernel) -> None:
"email": "user@example.com",
"password": "secret",
},
interaction_id="mai_abc123xyz",
mfa_option_id="sms",
selected_choice_id="google",
sign_in_option_id="work-account",
Expand Down Expand Up @@ -1190,6 +1191,7 @@ async def test_method_submit_with_all_params(self, async_client: AsyncKernel) ->
"email": "user@example.com",
"password": "secret",
},
interaction_id="mai_abc123xyz",
mfa_option_id="sms",
selected_choice_id="google",
sign_in_option_id="work-account",
Expand Down
Loading