Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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.100.0"
".": "0.101.0"
}
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## [0.101.0](https://github.com/kernel/kernel-python-sdk/compare/v0.100.0...v0.101.0) (2026-09-10)


### Features

* Add config analysis lifecycle guarantees ([e0d9d71](https://github.com/kernel/kernel-python-sdk/commit/e0d9d715689585224cde848845ebaed90c404f64))
* Brand origin TLS timeouts and classify provider failures ([b00a694](https://github.com/kernel/kernel-python-sdk/commit/b00a6942ff9c831f624e87c12923ee109f2d6cf7))
* Clarify proxy country defaults ([bb00cda](https://github.com/kernel/kernel-python-sdk/commit/bb00cdaabdeb569ed1bf46b538d15de8768b9686))
* Expose vault access in organization entitlements ([1c3b388](https://github.com/kernel/kernel-python-sdk/commit/1c3b388f1a4597f65ed3926a8ec2646f5e0fc994))
* Limit free organizations to three vaults ([b0d5628](https://github.com/kernel/kernel-python-sdk/commit/b0d5628acbe0a9d9d006a3349ba1338fdc3d4402))
* Populate safe failure reasons on invocation responses ([7162cbb](https://github.com/kernel/kernel-python-sdk/commit/7162cbbed49eb4d0a8d431bbb84680e48bdce8a2))
* Return vendor guidance with config registry recommendations ([938e40b](https://github.com/kernel/kernel-python-sdk/commit/938e40b2a9f4e37ef8221787debbb948e019eeeb))
* Support international ISP proxy countries ([78adb8a](https://github.com/kernel/kernel-python-sdk/commit/78adb8a4ae929028497e30b0a5988050eee7c1f4))

## [0.100.0](https://github.com/kernel/kernel-python-sdk/compare/v0.99.0...v0.100.0) (2026-09-04)


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.100.0"
version = "0.101.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.100.0" # x-release-please-version
__version__ = "0.101.0" # x-release-please-version
4 changes: 2 additions & 2 deletions src/kernel/resources/organization/limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> OrgLimits:
"""Get the organization's effective limits and managed auth usage."""
"""Get the organization's effective limits and managed auth and vault usage."""
return self._get(
"/org/limits",
options=make_request_options(
Expand Down Expand Up @@ -138,7 +138,7 @@ async def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> OrgLimits:
"""Get the organization's effective limits and managed auth usage."""
"""Get the organization's effective limits and managed auth and vault usage."""
return await self._get(
"/org/limits",
options=make_request_options(
Expand Down
8 changes: 6 additions & 2 deletions src/kernel/resources/vaults/vaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ def upsert(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> Vault:
"""
Create or retrieve a vault by immutable name
Free organizations can store up to 3 non-deleted vaults across all projects.
Paid plans and active trials have no vault cap. Retrieving an existing vault by
name succeeds even at the limit.

Args:
name: Immutable name used to create or retrieve the vault.
Expand Down Expand Up @@ -345,7 +347,9 @@ async def upsert(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> Vault:
"""
Create or retrieve a vault by immutable name
Free organizations can store up to 3 non-deleted vaults across all projects.
Paid plans and active trials have no vault cap. Retrieving an existing vault by
name succeeds even at the limit.

Args:
name: Immutable name used to create or retrieve the vault.
Expand Down
7 changes: 5 additions & 2 deletions src/kernel/types/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ class Analysis(BaseModel):
created_at: datetime
"""Time the analysis was created."""

expires_at: datetime
"""Deadline after which a still-running analysis becomes expired."""

failure: Optional[ErrorModel] = None
"""Present for failed or canceled analyses.
"""Present for failed, canceled, or expired analyses.

Messages contain safe retry guidance rather than internal workflow errors.
"""

finished_at: Optional[datetime] = None
"""Time the analysis reached a terminal status. Null while it is running."""

status: Literal["running", "completed", "failed", "canceled"]
status: Literal["running", "completed", "failed", "canceled", "expired"]
"""Lifecycle status of a background analysis."""
7 changes: 5 additions & 2 deletions src/kernel/types/browsers/browser_proxy_error_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Data(BrowserEventContext):
"destination_blocked",
"provider_blacklisted",
"provider_unreachable",
"provider_rejected",
"origin_tls_timeout",
"proxy_unavailable",
"upstream_timeout",
"upstream_dns_failure",
Expand All @@ -29,8 +31,9 @@ class Data(BrowserEventContext):
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.
provider_unreachable, provider_rejected, origin_tls_timeout, proxy_unavailable,
upstream_timeout, upstream_dns_failure, upstream_connect_failed. Unknown header
values are dropped.
"""

request_id: str
Expand Down
8 changes: 8 additions & 0 deletions src/kernel/types/config_registry_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@ class ConfigRegistryResponse(BaseModel):
"""A recommendation or a structured no-recommendation result."""

target: Target

guidance: Optional[str] = None
"""Short advisory markdown to facilitate navigating this target.

Returned even when no configuration reached the target, since knowing what
prevented success is useful without a configuration. Not verified against this
target. Null when nothing applicable was observed or no notes exist.
"""
14 changes: 11 additions & 3 deletions src/kernel/types/invocation_create_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@ class InvocationCreateResponse(BaseModel):
"""Status of the invocation"""

output: Optional[str] = None
"""The return value of the action that was invoked, rendered as a JSON string.
"""The action result or detailed failure output.

This could be: string, number, boolean, array, object, or null.
Often a JSON-encoded value, but failures may contain plain text. May contain
sensitive application data.
"""

status_reason: Optional[str] = None
"""Status reason"""
"""
A nonempty, customer-safe summary of the recorded failure output, always present
when status is failed and omitted otherwise. Recognized messages receive a
specific summary; other failures receive a generic summary. Message matching
does not establish whether the failure originated in the platform or action
code. Does not include raw action output or internal error details.
Human-readable text, not a stable identifier for retry logic.
"""
15 changes: 12 additions & 3 deletions src/kernel/types/invocation_list_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ class InvocationListResponse(BaseModel):
"""

output: Optional[str] = None
"""Output produced by the action, rendered as a JSON string.
"""The action result or detailed failure output.

This could be: string, number, boolean, array, object, or null.
Often a JSON-encoded value, but failures may contain plain text. May contain
sensitive application data.
"""

payload: Optional[str] = None
Expand All @@ -47,4 +48,12 @@ class InvocationListResponse(BaseModel):
"""

status_reason: Optional[str] = None
"""Status reason"""
"""
A nonempty, customer-safe summary of the recorded failure output, always present
when status is failed and omitted otherwise, including in the first failed
invocation_state event. Recognized messages receive a specific summary; other
failures receive a generic summary. Message matching does not establish whether
the failure originated in the platform or action code. Does not include raw
action output or internal error details. Available for historical invocations as
well. Human-readable text, not a stable identifier for retry logic.
"""
15 changes: 12 additions & 3 deletions src/kernel/types/invocation_retrieve_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ class InvocationRetrieveResponse(BaseModel):
"""

output: Optional[str] = None
"""Output produced by the action, rendered as a JSON string.
"""The action result or detailed failure output.

This could be: string, number, boolean, array, object, or null.
Often a JSON-encoded value, but failures may contain plain text. May contain
sensitive application data.
"""

payload: Optional[str] = None
Expand All @@ -47,4 +48,12 @@ class InvocationRetrieveResponse(BaseModel):
"""

status_reason: Optional[str] = None
"""Status reason"""
"""
A nonempty, customer-safe summary of the recorded failure output, always present
when status is failed and omitted otherwise, including in the first failed
invocation_state event. Recognized messages receive a specific summary; other
failures receive a generic summary. Message matching does not establish whether
the failure originated in the platform or action code. Does not include raw
action output or internal error details. Available for historical invocations as
well. Human-readable text, not a stable identifier for retry logic.
"""
15 changes: 12 additions & 3 deletions src/kernel/types/invocation_state_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ class Invocation(BaseModel):
"""

output: Optional[str] = None
"""Output produced by the action, rendered as a JSON string.
"""The action result or detailed failure output.

This could be: string, number, boolean, array, object, or null.
Often a JSON-encoded value, but failures may contain plain text. May contain
sensitive application data.
"""

payload: Optional[str] = None
Expand All @@ -47,7 +48,15 @@ class Invocation(BaseModel):
"""

status_reason: Optional[str] = None
"""Status reason"""
"""
A nonempty, customer-safe summary of the recorded failure output, always present
when status is failed and omitted otherwise, including in the first failed
invocation_state event. Recognized messages receive a specific summary; other
failures receive a generic summary. Message matching does not establish whether
the failure originated in the platform or action code. Does not include raw
action output or internal error details. Available for historical invocations as
well. Human-readable text, not a stable identifier for retry logic.
"""


class InvocationStateEvent(BaseModel):
Expand Down
15 changes: 12 additions & 3 deletions src/kernel/types/invocation_update_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ class InvocationUpdateResponse(BaseModel):
"""

output: Optional[str] = None
"""Output produced by the action, rendered as a JSON string.
"""The action result or detailed failure output.

This could be: string, number, boolean, array, object, or null.
Often a JSON-encoded value, but failures may contain plain text. May contain
sensitive application data.
"""

payload: Optional[str] = None
Expand All @@ -47,4 +48,12 @@ class InvocationUpdateResponse(BaseModel):
"""

status_reason: Optional[str] = None
"""Status reason"""
"""
A nonempty, customer-safe summary of the recorded failure output, always present
when status is failed and omitted otherwise, including in the first failed
invocation_state event. Recognized messages receive a specific summary; other
failures receive a generic summary. Message matching does not establish whether
the failure originated in the platform or action code. Does not include raw
action output or internal error details. Available for historical invocations as
well. Human-readable text, not a stable identifier for retry logic.
"""
8 changes: 8 additions & 0 deletions src/kernel/types/lookup_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,11 @@ class LookupResponse(BaseModel):
recommendation: Optional[Recommendation] = None

target: Target

guidance: Optional[str] = None
"""Short advisory markdown to facilitate navigating this target.

Returned even when no configuration reached the target, since knowing what
prevented success is useful without a configuration. Not verified against this
target. Null when nothing applicable was observed or no notes exist.
"""
22 changes: 22 additions & 0 deletions src/kernel/types/organization/org_entitlements.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"FeaturesManagedProxies",
"FeaturesProfiles",
"FeaturesProxyBypassHosts",
"FeaturesVaults",
"Limits",
"Plan",
]
Expand Down Expand Up @@ -114,6 +115,15 @@ class FeaturesProxyBypassHosts(BaseModel):
"""Whether the organization is entitled to use this feature."""


class FeaturesVaults(BaseModel):
"""
Whether the organization can access vaults, using the same access check as vault API routes.
"""

enabled: bool
"""Whether the organization is entitled to use this feature."""


class Features(BaseModel):
browser_extensions: FeaturesBrowserExtensions

Expand All @@ -139,6 +149,12 @@ class Features(BaseModel):

proxy_bypass_hosts: FeaturesProxyBypassHosts

vaults: FeaturesVaults
"""
Whether the organization can access vaults, using the same access check as vault
API routes.
"""


class Limits(BaseModel):
default_max_concurrent_invocations_per_app: int
Expand All @@ -156,6 +172,12 @@ class Limits(BaseModel):
max_concurrent_invocations: int
"""Effective organization-wide concurrent app invocation ceiling."""

max_vaults: Optional[int] = None
"""Maximum non-deleted vaults allowed org-wide across all projects.

Null means unlimited. The vaults feature flag still controls access.
"""


class Plan(BaseModel):
id: Literal["FREE", "HOBBYIST", "START_UP", "ENTERPRISE"]
Expand Down
9 changes: 9 additions & 0 deletions src/kernel/types/organization/org_limits.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,22 @@ class OrgLimits(BaseModel):
projects.
"""

max_vaults: Optional[int] = None
"""Maximum non-deleted vaults allowed org-wide across all projects.

Null means unlimited.
"""

min_health_check_interval_seconds: int
"""
Smallest health_check_interval the organization's plan accepts on a managed auth
connection. Requests below this are rejected with 400. Existing connections
stored below the floor are grandfathered until edited.
"""

vaults_used: int
"""Current non-deleted vault count across all projects in the organization."""

default_project_max_concurrent_sessions: Optional[int] = None
"""
Default maximum concurrent browsers applied to every project that has no
Expand Down
15 changes: 12 additions & 3 deletions src/kernel/types/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ class ConfigRegistryManagedProxyCreateConfigIspProxyConfig(BaseModel):
"""Configuration for an ISP proxy."""

country: Optional[str] = None
"""ISO 3166 country code. Defaults to US if not provided."""
"""ISO 3166 country code.

Supported countries are US, GB, FR, DE, and SG. Defaults to US if not provided.
"""


class ConfigRegistryManagedProxyCreateConfigResidentialProxyConfig(BaseModel):
Expand All @@ -53,7 +56,10 @@ class ConfigRegistryManagedProxyCreateConfigResidentialProxyConfig(BaseModel):
"""

country: Optional[str] = None
"""ISO 3166 country code."""
"""ISO 3166 country code.

If omitted, the proxy uses the global pool without country targeting.
"""

os: Optional[Literal["windows", "macos", "android"]] = None
"""Operating system of the residential device."""
Expand All @@ -72,7 +78,10 @@ class ConfigRegistryManagedProxyCreateConfigMobileProxyConfig(BaseModel):
"""Provider city alias. Mobile carrier routing can make observed geo vary."""

country: Optional[str] = None
"""ISO 3166 country code"""
"""ISO 3166 country code.

If omitted, the proxy uses the global pool without country targeting.
"""

state: Optional[str] = None
"""US-only state code. Mobile carrier routing can make observed geo vary."""
Expand Down
Loading
Loading