Skip to content
Open
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.79.0"
".": "0.80.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 127
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-e04362b2c82b88f4f7fb43209c764fa9fdf37fe98932e142547be43a1e99c50b.yml
openapi_spec_hash: b16e79bfd6cac36090c815a8184b9e09
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-5b9eb5cdadbc7a5f404f5c2cec40f726e5fece54bf8e2dd29ab5c7700eb44f0e.yml
openapi_spec_hash: 63dd0798a4c0ed6477af50fff397f5dc
config_hash: 77ee715aa17061166f9a02b264a21b8d
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 0.80.0 (2026-07-17)

Full Changelog: [v0.79.0...v0.80.0](https://github.com/kernel/kernel-python-sdk/compare/v0.79.0...v0.80.0)

### Features

* Add example to ProxyCheckRequest.url so API reference sample shows it ([2a288ca](https://github.com/kernel/kernel-python-sdk/commit/2a288ca546da7760cdc16e566260fd440ae36fb7))
* **managed-auth:** add TS CUA worker contract (KERNEL-1456) ([de2fc59](https://github.com/kernel/kernel-python-sdk/commit/de2fc590e00152328ac6a4f5165da0fb727644bb))

## 0.79.0 (2026-07-15)

Full Changelog: [v0.78.1...v0.79.0](https://github.com/kernel/kernel-python-sdk/compare/v0.78.1...v0.79.0)
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.79.0"
version = "0.80.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.79.0" # x-release-please-version
__version__ = "0.80.0" # x-release-please-version
16 changes: 16 additions & 0 deletions src/kernel/resources/auth/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,10 @@ def submit(
self,
id: str,
*,
field_values: Dict[str, str] | Omit = omit,
fields: Dict[str, str] | Omit = omit,
mfa_option_id: str | Omit = omit,
selected_choice_id: str | Omit = omit,
sign_in_option_id: str | Omit = omit,
sso_button_selector: str | Omit = omit,
sso_provider: str | Omit = omit,
Expand All @@ -523,10 +525,14 @@ def submit(
progress and get results.

Args:
field_values: Canonical map of field ID to submitted value.

fields: Map of field name to value

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

selected_choice_id: Canonical choice ID selected by the user.

sign_in_option_id: The sign-in option ID to select (when sign_in_options were returned)

sso_button_selector: XPath selector for the SSO button to click (ODA). Use sso_provider instead for
Expand All @@ -549,8 +555,10 @@ def submit(
path_template("/auth/connections/{id}/submit", id=id),
body=maybe_transform(
{
"field_values": field_values,
"fields": fields,
"mfa_option_id": mfa_option_id,
"selected_choice_id": selected_choice_id,
"sign_in_option_id": sign_in_option_id,
"sso_button_selector": sso_button_selector,
"sso_provider": sso_provider,
Expand Down Expand Up @@ -1088,8 +1096,10 @@ async def submit(
self,
id: str,
*,
field_values: Dict[str, str] | Omit = omit,
fields: Dict[str, str] | Omit = omit,
mfa_option_id: str | Omit = omit,
selected_choice_id: str | Omit = omit,
sign_in_option_id: str | Omit = omit,
sso_button_selector: str | Omit = omit,
sso_provider: str | Omit = omit,
Expand All @@ -1106,10 +1116,14 @@ async def submit(
progress and get results.

Args:
field_values: Canonical map of field ID to submitted value.

fields: Map of field name to value

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

selected_choice_id: Canonical choice ID selected by the user.

sign_in_option_id: The sign-in option ID to select (when sign_in_options were returned)

sso_button_selector: XPath selector for the SSO button to click (ODA). Use sso_provider instead for
Expand All @@ -1132,8 +1146,10 @@ async def submit(
path_template("/auth/connections/{id}/submit", id=id),
body=await async_maybe_transform(
{
"field_values": field_values,
"fields": fields,
"mfa_option_id": mfa_option_id,
"selected_choice_id": selected_choice_id,
"sign_in_option_id": sign_in_option_id,
"sso_button_selector": sso_button_selector,
"sso_provider": sso_provider,
Expand Down
58 changes: 58 additions & 0 deletions src/kernel/types/auth/connection_follow_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,36 @@
__all__ = [
"ConnectionFollowResponse",
"ManagedAuthStateEvent",
"ManagedAuthStateEventChoice",
"ManagedAuthStateEventDiscoveredField",
"ManagedAuthStateEventField",
"ManagedAuthStateEventMfaOption",
"ManagedAuthStateEventPendingSSOButton",
"ManagedAuthStateEventSignInOption",
]


class ManagedAuthStateEventChoice(BaseModel):
"""Canonical auth-flow choice awaiting user selection."""

id: str
"""Stable choice identifier for canonical submit."""

label: str
"""Human-readable choice label."""

type: Literal[
"mfa_method", "sso_provider", "sign_in_method", "auth_method", "identifier_method", "account", "other"
]
"""Choice type."""

description: Optional[str] = None
"""Additional context for the choice."""

observed_selector: Optional[str] = None
"""Selector for the visible choice, when available."""


class ManagedAuthStateEventDiscoveredField(BaseModel):
"""A discovered form field"""

Expand Down Expand Up @@ -53,6 +76,28 @@ class ManagedAuthStateEventDiscoveredField(BaseModel):
"""Whether field is required"""


class ManagedAuthStateEventField(BaseModel):
"""Canonical field awaiting user input."""

id: str
"""Stable field identifier for canonical submit."""

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

type: Literal["identifier", "password", "code", "totp_code", "totp_secret", "text"]
"""Managed-auth field type."""

label: Optional[str] = None
"""Human-readable label shown to the user."""

observed_selector: Optional[str] = None
"""Selector for the visible field, when available."""

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


class ManagedAuthStateEventMfaOption(BaseModel):
"""An MFA method option for verification"""

Expand Down Expand Up @@ -118,6 +163,13 @@ class ManagedAuthStateEvent(BaseModel):
timestamp: datetime
"""Time the state was reported."""

choices: Optional[List[ManagedAuthStateEventChoice]] = None
"""Canonical choices awaiting selection.

Prefer this over pending_sso_buttons, mfa_options, and sign_in_options when
present.
"""

discovered_fields: Optional[List[ManagedAuthStateEventDiscoveredField]] = None
"""
Fields awaiting input (present when flow_step=AWAITING_INPUT; may also be
Expand All @@ -136,6 +188,12 @@ class ManagedAuthStateEvent(BaseModel):
flow_step=AWAITING_EXTERNAL_ACTION).
"""

fields: Optional[List[ManagedAuthStateEventField]] = None
"""Canonical fields awaiting input.

Prefer this over discovered_fields when present.
"""

flow_type: Optional[Literal["LOGIN", "REAUTH"]] = None
"""Type of the current flow."""

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 @@ -9,12 +9,18 @@


class ConnectionSubmitParams(TypedDict, total=False):
field_values: Dict[str, str]
"""Canonical map of field ID to submitted value."""

fields: Dict[str, str]
"""Map of field name to value"""

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

selected_choice_id: str
"""Canonical choice ID selected by the user."""

sign_in_option_id: str
"""The sign-in option ID to select (when sign_in_options were returned)"""

Expand Down
67 changes: 66 additions & 1 deletion src/kernel/types/auth/managed_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,37 @@

from ..._models import BaseModel

__all__ = ["ManagedAuth", "Credential", "DiscoveredField", "MfaOption", "PendingSSOButton", "SignInOption"]
__all__ = [
"ManagedAuth",
"Choice",
"Credential",
"DiscoveredField",
"Field",
"MfaOption",
"PendingSSOButton",
"SignInOption",
]


class Choice(BaseModel):
"""Canonical auth-flow choice awaiting user selection."""

id: str
"""Stable choice identifier for canonical submit."""

label: str
"""Human-readable choice label."""

type: Literal[
"mfa_method", "sso_provider", "sign_in_method", "auth_method", "identifier_method", "account", "other"
]
"""Choice type."""

description: Optional[str] = None
"""Additional context for the choice."""

observed_selector: Optional[str] = None
"""Selector for the visible choice, when available."""


class Credential(BaseModel):
Expand Down Expand Up @@ -65,6 +95,28 @@ class DiscoveredField(BaseModel):
"""Whether field is required"""


class Field(BaseModel):
"""Canonical field awaiting user input."""

id: str
"""Stable field identifier for canonical submit."""

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

type: Literal["identifier", "password", "code", "totp_code", "totp_secret", "text"]
"""Managed-auth field type."""

label: Optional[str] = None
"""Human-readable label shown to the user."""

observed_selector: Optional[str] = None
"""Selector for the visible field, when available."""

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


class MfaOption(BaseModel):
"""An MFA method option for verification"""

Expand Down Expand Up @@ -243,6 +295,13 @@ class ManagedAuth(BaseModel):
automatically
"""

choices: Optional[List[Choice]] = None
"""Canonical choices awaiting selection.

Prefer this over pending_sso_buttons, mfa_options, and sign_in_options when
present.
"""

credential: Optional[Credential] = None
"""Reference to credentials for the auth connection. Use one of:

Expand All @@ -269,6 +328,12 @@ class ManagedAuth(BaseModel):
flow_step=awaiting_external_action)
"""

fields: Optional[List[Field]] = None
"""Canonical fields awaiting input.

Prefer this over discovered_fields when present.
"""

flow_expires_at: Optional[datetime] = None
"""When the current flow expires (null when no flow in progress).

Expand Down
10 changes: 10 additions & 0 deletions tests/api_resources/auth/test_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,16 @@ def test_method_submit(self, client: Kernel) -> None:
def test_method_submit_with_all_params(self, client: Kernel) -> None:
connection = client.auth.connections.submit(
id="id",
field_values={
"field_email": "user@example.com",
"field_password": "secret",
},
fields={
"email": "user@example.com",
"password": "secret",
},
mfa_option_id="sms",
selected_choice_id="google",
sign_in_option_id="work-account",
sso_button_selector="xpath=//button[contains(text(), 'Continue with Google')]",
sso_provider="google",
Expand Down Expand Up @@ -853,11 +858,16 @@ async def test_method_submit(self, async_client: AsyncKernel) -> None:
async def test_method_submit_with_all_params(self, async_client: AsyncKernel) -> None:
connection = await async_client.auth.connections.submit(
id="id",
field_values={
"field_email": "user@example.com",
"field_password": "secret",
},
fields={
"email": "user@example.com",
"password": "secret",
},
mfa_option_id="sms",
selected_choice_id="google",
sign_in_option_id="work-account",
sso_button_selector="xpath=//button[contains(text(), 'Continue with Google')]",
sso_provider="google",
Expand Down
4 changes: 2 additions & 2 deletions tests/api_resources/test_proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def test_method_check(self, client: Kernel) -> None:
def test_method_check_with_all_params(self, client: Kernel) -> None:
proxy = client.proxies.check(
id="id",
url="url",
url="https://example.com",
)
assert_matches_type(ProxyCheckResponse, proxy, path=["response"])

Expand Down Expand Up @@ -524,7 +524,7 @@ async def test_method_check(self, async_client: AsyncKernel) -> None:
async def test_method_check_with_all_params(self, async_client: AsyncKernel) -> None:
proxy = await async_client.proxies.check(
id="id",
url="url",
url="https://example.com",
)
assert_matches_type(ProxyCheckResponse, proxy, path=["response"])

Expand Down
Loading