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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
lint:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/kernel-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -44,7 +44,7 @@ jobs:
permissions:
contents: read
id-token: write
runs-on: ${{ github.repository == 'stainless-sdks/kernel-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

Expand Down Expand Up @@ -84,7 +84,7 @@ jobs:
test:
timeout-minutes: 10
name: test
runs-on: ${{ github.repository == 'stainless-sdks/kernel-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down
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-1dffe057847b596dd311ce4b6e0e8036126dce3e97d390636c9c8e6d2f4823e1.yml
openapi_spec_hash: c06336c199ee64c222ba3122deae9463
config_hash: 77ee715aa17061166f9a02b264a21b8d
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## 0.80.0 (2026-07-19)

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))
* Expose browser sessions on auth timeline events ([687b401](https://github.com/kernel/kernel-python-sdk/commit/687b401117d37d6db8e818cd08ee3983671a23f6))
* **managed-auth:** add TS CUA worker contract (KERNEL-1456) ([de2fc59](https://github.com/kernel/kernel-python-sdk/commit/de2fc590e00152328ac6a4f5165da0fb727644bb))
* **stlc:** configurable CI runner and private-production-repo support in workflow templates ([79f96e4](https://github.com/kernel/kernel-python-sdk/commit/79f96e4e8d8f0e04e21c37010e1faa765f17afb6))

## 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
3 changes: 3 additions & 0 deletions src/kernel/types/auth/managed_auth_timeline_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class ManagedAuthTimelineEvent(BaseModel):
session-validity check.
"""

browser_session_id: Optional[str] = None
"""Browser session that produced the event, if one was created."""

error_code: Optional[str] = None
"""Machine-readable error code. Present when a login/reauth event failed."""

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
Loading
Loading