diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 97d8dbba..aebbc8bc 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.100.0"
+ ".": "0.101.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 5fe5772a..a0ee50ed 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 158
+configured_endpoints: 163
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a14e35a..77497eb7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
# Changelog
+## [0.101.0](https://github.com/kernel/kernel-python-sdk/compare/v0.100.0...v0.101.0) (2026-09-11)
+
+
+### 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))
+* Integrate configurable vault providers across API and checkout ([478bc09](https://github.com/kernel/kernel-python-sdk/commit/478bc09cc5c8f6b2850628d02b88d699cc35328f))
+* 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))
+* Revert vendor guidance recommendations ([adacc13](https://github.com/kernel/kernel-python-sdk/commit/adacc1321a9c1cc1624e5adf6c2521b0f09851f4))
+* 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)
diff --git a/api.md b/api.md
index 797c5d9c..63957ab1 100644
--- a/api.md
+++ b/api.md
@@ -487,6 +487,22 @@ Methods:
- client.browser_pools.flush(id_or_name) -> None
- client.browser_pools.release(id_or_name, \*\*params) -> None
+# VaultProviderConfigs
+
+Types:
+
+```python
+from kernel.types import VaultProviderConfig
+```
+
+Methods:
+
+- client.vault_provider_configs.create(\*\*params) -> VaultProviderConfig
+- client.vault_provider_configs.retrieve(id_or_name) -> VaultProviderConfig
+- client.vault_provider_configs.update(id_or_name, \*\*params) -> VaultProviderConfig
+- client.vault_provider_configs.list(\*\*params) -> SyncOffsetPagination[VaultProviderConfig]
+- client.vault_provider_configs.delete(id_or_name) -> None
+
# Vaults
Types:
diff --git a/pyproject.toml b/pyproject.toml
index 84718a85..ce24d358 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -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"
diff --git a/src/kernel/_client.py b/src/kernel/_client.py
index aed72055..f4c9e48f 100644
--- a/src/kernel/_client.py
+++ b/src/kernel/_client.py
@@ -73,6 +73,7 @@
browser_pools,
config_registry,
credential_providers,
+ vault_provider_configs,
)
from .resources.apps import AppsResource, AsyncAppsResource
from .resources.proxies import ProxiesResource, AsyncProxiesResource
@@ -90,6 +91,7 @@
from .resources.telemetry.telemetry import TelemetryResource, AsyncTelemetryResource
from .resources.credential_providers import CredentialProvidersResource, AsyncCredentialProvidersResource
from .resources.audit_logs.audit_logs import AuditLogsResource, AsyncAuditLogsResource
+ from .resources.vault_provider_configs import VaultProviderConfigsResource, AsyncVaultProviderConfigsResource
from .resources.organization.organization import OrganizationResource, AsyncOrganizationResource
from .resources.config_registry.config_registry import ConfigRegistryResource, AsyncConfigRegistryResource
@@ -290,6 +292,12 @@ def browser_pools(self) -> BrowserPoolsResource:
return BrowserPoolsResource(self)
+ @cached_property
+ def vault_provider_configs(self) -> VaultProviderConfigsResource:
+ from .resources.vault_provider_configs import VaultProviderConfigsResource
+
+ return VaultProviderConfigsResource(self)
+
@cached_property
def vaults(self) -> VaultsResource:
from .resources.vaults import VaultsResource
@@ -689,6 +697,12 @@ def browser_pools(self) -> AsyncBrowserPoolsResource:
return AsyncBrowserPoolsResource(self)
+ @cached_property
+ def vault_provider_configs(self) -> AsyncVaultProviderConfigsResource:
+ from .resources.vault_provider_configs import AsyncVaultProviderConfigsResource
+
+ return AsyncVaultProviderConfigsResource(self)
+
@cached_property
def vaults(self) -> AsyncVaultsResource:
from .resources.vaults import AsyncVaultsResource
@@ -990,6 +1004,12 @@ def browser_pools(self) -> browser_pools.BrowserPoolsResourceWithRawResponse:
return BrowserPoolsResourceWithRawResponse(self._client.browser_pools)
+ @cached_property
+ def vault_provider_configs(self) -> vault_provider_configs.VaultProviderConfigsResourceWithRawResponse:
+ from .resources.vault_provider_configs import VaultProviderConfigsResourceWithRawResponse
+
+ return VaultProviderConfigsResourceWithRawResponse(self._client.vault_provider_configs)
+
@cached_property
def vaults(self) -> vaults.VaultsResourceWithRawResponse:
from .resources.vaults import VaultsResourceWithRawResponse
@@ -1123,6 +1143,12 @@ def browser_pools(self) -> browser_pools.AsyncBrowserPoolsResourceWithRawRespons
return AsyncBrowserPoolsResourceWithRawResponse(self._client.browser_pools)
+ @cached_property
+ def vault_provider_configs(self) -> vault_provider_configs.AsyncVaultProviderConfigsResourceWithRawResponse:
+ from .resources.vault_provider_configs import AsyncVaultProviderConfigsResourceWithRawResponse
+
+ return AsyncVaultProviderConfigsResourceWithRawResponse(self._client.vault_provider_configs)
+
@cached_property
def vaults(self) -> vaults.AsyncVaultsResourceWithRawResponse:
from .resources.vaults import AsyncVaultsResourceWithRawResponse
@@ -1256,6 +1282,12 @@ def browser_pools(self) -> browser_pools.BrowserPoolsResourceWithStreamingRespon
return BrowserPoolsResourceWithStreamingResponse(self._client.browser_pools)
+ @cached_property
+ def vault_provider_configs(self) -> vault_provider_configs.VaultProviderConfigsResourceWithStreamingResponse:
+ from .resources.vault_provider_configs import VaultProviderConfigsResourceWithStreamingResponse
+
+ return VaultProviderConfigsResourceWithStreamingResponse(self._client.vault_provider_configs)
+
@cached_property
def vaults(self) -> vaults.VaultsResourceWithStreamingResponse:
from .resources.vaults import VaultsResourceWithStreamingResponse
@@ -1389,6 +1421,12 @@ def browser_pools(self) -> browser_pools.AsyncBrowserPoolsResourceWithStreamingR
return AsyncBrowserPoolsResourceWithStreamingResponse(self._client.browser_pools)
+ @cached_property
+ def vault_provider_configs(self) -> vault_provider_configs.AsyncVaultProviderConfigsResourceWithStreamingResponse:
+ from .resources.vault_provider_configs import AsyncVaultProviderConfigsResourceWithStreamingResponse
+
+ return AsyncVaultProviderConfigsResourceWithStreamingResponse(self._client.vault_provider_configs)
+
@cached_property
def vaults(self) -> vaults.AsyncVaultsResourceWithStreamingResponse:
from .resources.vaults import AsyncVaultsResourceWithStreamingResponse
diff --git a/src/kernel/_version.py b/src/kernel/_version.py
index 2fba39cd..058933d0 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.100.0" # x-release-please-version
+__version__ = "0.101.0" # x-release-please-version
diff --git a/src/kernel/resources/__init__.py b/src/kernel/resources/__init__.py
index 5bc0849c..21426930 100644
--- a/src/kernel/resources/__init__.py
+++ b/src/kernel/resources/__init__.py
@@ -144,6 +144,14 @@
CredentialProvidersResourceWithStreamingResponse,
AsyncCredentialProvidersResourceWithStreamingResponse,
)
+from .vault_provider_configs import (
+ VaultProviderConfigsResource,
+ AsyncVaultProviderConfigsResource,
+ VaultProviderConfigsResourceWithRawResponse,
+ AsyncVaultProviderConfigsResourceWithRawResponse,
+ VaultProviderConfigsResourceWithStreamingResponse,
+ AsyncVaultProviderConfigsResourceWithStreamingResponse,
+)
__all__ = [
"DeploymentsResource",
@@ -212,6 +220,12 @@
"AsyncBrowserPoolsResourceWithRawResponse",
"BrowserPoolsResourceWithStreamingResponse",
"AsyncBrowserPoolsResourceWithStreamingResponse",
+ "VaultProviderConfigsResource",
+ "AsyncVaultProviderConfigsResource",
+ "VaultProviderConfigsResourceWithRawResponse",
+ "AsyncVaultProviderConfigsResourceWithRawResponse",
+ "VaultProviderConfigsResourceWithStreamingResponse",
+ "AsyncVaultProviderConfigsResourceWithStreamingResponse",
"VaultsResource",
"AsyncVaultsResource",
"VaultsResourceWithRawResponse",
diff --git a/src/kernel/resources/organization/limits.py b/src/kernel/resources/organization/limits.py
index d1bb6ecb..9dcd9dbb 100644
--- a/src/kernel/resources/organization/limits.py
+++ b/src/kernel/resources/organization/limits.py
@@ -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(
@@ -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(
diff --git a/src/kernel/resources/vault_provider_configs.py b/src/kernel/resources/vault_provider_configs.py
new file mode 100644
index 00000000..69f29d3d
--- /dev/null
+++ b/src/kernel/resources/vault_provider_configs.py
@@ -0,0 +1,721 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Any, cast
+from typing_extensions import Literal, overload
+
+import httpx
+
+from ..types import (
+ vault_provider_config_list_params,
+ vault_provider_config_create_params,
+ vault_provider_config_update_params,
+)
+from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
+from .._utils import path_template, required_args, maybe_transform, async_maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..pagination import SyncOffsetPagination, AsyncOffsetPagination
+from .._base_client import AsyncPaginator, make_request_options
+from ..types.vault_provider_config import VaultProviderConfig
+
+__all__ = ["VaultProviderConfigsResource", "AsyncVaultProviderConfigsResource"]
+
+
+class VaultProviderConfigsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> VaultProviderConfigsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return VaultProviderConfigsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> VaultProviderConfigsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#with_streaming_response
+ """
+ return VaultProviderConfigsResourceWithStreamingResponse(self)
+
+ @overload
+ def create(
+ self,
+ *,
+ credentials: vault_provider_config_create_params.VaultLinkProviderConfigRequestCredentials,
+ name: str,
+ provider: Literal["link"],
+ # 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,
+ ) -> VaultProviderConfig:
+ """Register a configuration shared across the organization's projects.
+
+ Names are
+ unique within the organization; duplicate names return 409 without replacing
+ credentials. A configuration serves many wallets. Secret credentials are never
+ returned. Requires an organization-scoped credential or dashboard
+ authentication; project-scoped credentials receive 403.
+
+ Args:
+ name: Unique within the organization.
+
+ 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
+ """
+ ...
+
+ @overload
+ def create(
+ self,
+ *,
+ credentials: vault_provider_config_create_params.VaultAgentCardProviderConfigRequestCredentials,
+ name: str,
+ provider: Literal["agentcard"],
+ # 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,
+ ) -> VaultProviderConfig:
+ """Register a configuration shared across the organization's projects.
+
+ Names are
+ unique within the organization; duplicate names return 409 without replacing
+ credentials. A configuration serves many wallets. Secret credentials are never
+ returned. Requires an organization-scoped credential or dashboard
+ authentication; project-scoped credentials receive 403.
+
+ Args:
+ name: Unique within the organization.
+
+ 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
+ """
+ ...
+
+ @required_args(["credentials", "name", "provider"])
+ def create(
+ self,
+ *,
+ credentials: vault_provider_config_create_params.VaultLinkProviderConfigRequestCredentials
+ | vault_provider_config_create_params.VaultAgentCardProviderConfigRequestCredentials,
+ name: str,
+ provider: Literal["link"] | Literal["agentcard"],
+ # 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,
+ ) -> VaultProviderConfig:
+ return cast(
+ VaultProviderConfig,
+ self._post(
+ "/vault-provider-configs",
+ body=maybe_transform(
+ {
+ "credentials": credentials,
+ "name": name,
+ "provider": provider,
+ },
+ vault_provider_config_create_params.VaultProviderConfigCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, VaultProviderConfig
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def retrieve(
+ self,
+ id_or_name: 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,
+ ) -> VaultProviderConfig:
+ """Look up a configuration by ID or name.
+
+ Returns 404 when it does not exist in the
+ organization.
+
+ 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_or_name:
+ raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
+ return cast(
+ VaultProviderConfig,
+ self._get(
+ path_template("/vault-provider-configs/{id_or_name}", id_or_name=id_or_name),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, VaultProviderConfig
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def update(
+ self,
+ id_or_name: str,
+ *,
+ credentials: vault_provider_config_update_params.Credentials | Omit = omit,
+ name: str | 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> VaultProviderConfig:
+ """Update the supplied fields; omitted fields remain unchanged.
+
+ Names must remain
+ unique within the organization. Requires an organization-scoped credential or
+ dashboard authentication; project-scoped credentials receive 403.
+
+ Args:
+ credentials: Fields to update. Omitted credentials are left unchanged. A rejected update
+ leaves existing credentials unchanged.
+
+ name: Unique within the organization.
+
+ 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_or_name:
+ raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
+ return cast(
+ VaultProviderConfig,
+ self._patch(
+ path_template("/vault-provider-configs/{id_or_name}", id_or_name=id_or_name),
+ body=maybe_transform(
+ {
+ "credentials": credentials,
+ "name": name,
+ },
+ vault_provider_config_update_params.VaultProviderConfigUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, VaultProviderConfig
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def list(
+ self,
+ *,
+ limit: int | Omit = omit,
+ offset: int | 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> SyncOffsetPagination[VaultProviderConfig]:
+ """
+ Secret credentials are never returned.
+
+ 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
+ """
+ return self._get_api_list(
+ "/vault-provider-configs",
+ page=SyncOffsetPagination[VaultProviderConfig],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "limit": limit,
+ "offset": offset,
+ },
+ vault_provider_config_list_params.VaultProviderConfigListParams,
+ ),
+ ),
+ model=cast(Any, VaultProviderConfig), # Union types cannot be passed in as arguments in the type system
+ )
+
+ def delete(
+ self,
+ id_or_name: 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:
+ """Delete a configuration in the organization.
+
+ Returns 409 while any non-deleted
+ vault item references the configuration, regardless of connection status. Does
+ not delete the external OAuth client or revoke unrelated grants. Requires an
+ organization-scoped credential or dashboard authentication; project-scoped
+ credentials receive 403.
+
+ 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_or_name:
+ raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ path_template("/vault-provider-configs/{id_or_name}", id_or_name=id_or_name),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class AsyncVaultProviderConfigsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncVaultProviderConfigsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return AsyncVaultProviderConfigsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncVaultProviderConfigsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#with_streaming_response
+ """
+ return AsyncVaultProviderConfigsResourceWithStreamingResponse(self)
+
+ @overload
+ async def create(
+ self,
+ *,
+ credentials: vault_provider_config_create_params.VaultLinkProviderConfigRequestCredentials,
+ name: str,
+ provider: Literal["link"],
+ # 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,
+ ) -> VaultProviderConfig:
+ """Register a configuration shared across the organization's projects.
+
+ Names are
+ unique within the organization; duplicate names return 409 without replacing
+ credentials. A configuration serves many wallets. Secret credentials are never
+ returned. Requires an organization-scoped credential or dashboard
+ authentication; project-scoped credentials receive 403.
+
+ Args:
+ name: Unique within the organization.
+
+ 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
+ """
+ ...
+
+ @overload
+ async def create(
+ self,
+ *,
+ credentials: vault_provider_config_create_params.VaultAgentCardProviderConfigRequestCredentials,
+ name: str,
+ provider: Literal["agentcard"],
+ # 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,
+ ) -> VaultProviderConfig:
+ """Register a configuration shared across the organization's projects.
+
+ Names are
+ unique within the organization; duplicate names return 409 without replacing
+ credentials. A configuration serves many wallets. Secret credentials are never
+ returned. Requires an organization-scoped credential or dashboard
+ authentication; project-scoped credentials receive 403.
+
+ Args:
+ name: Unique within the organization.
+
+ 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
+ """
+ ...
+
+ @required_args(["credentials", "name", "provider"])
+ async def create(
+ self,
+ *,
+ credentials: vault_provider_config_create_params.VaultLinkProviderConfigRequestCredentials
+ | vault_provider_config_create_params.VaultAgentCardProviderConfigRequestCredentials,
+ name: str,
+ provider: Literal["link"] | Literal["agentcard"],
+ # 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,
+ ) -> VaultProviderConfig:
+ return cast(
+ VaultProviderConfig,
+ await self._post(
+ "/vault-provider-configs",
+ body=await async_maybe_transform(
+ {
+ "credentials": credentials,
+ "name": name,
+ "provider": provider,
+ },
+ vault_provider_config_create_params.VaultProviderConfigCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, VaultProviderConfig
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ async def retrieve(
+ self,
+ id_or_name: 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,
+ ) -> VaultProviderConfig:
+ """Look up a configuration by ID or name.
+
+ Returns 404 when it does not exist in the
+ organization.
+
+ 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_or_name:
+ raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
+ return cast(
+ VaultProviderConfig,
+ await self._get(
+ path_template("/vault-provider-configs/{id_or_name}", id_or_name=id_or_name),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, VaultProviderConfig
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ async def update(
+ self,
+ id_or_name: str,
+ *,
+ credentials: vault_provider_config_update_params.Credentials | Omit = omit,
+ name: str | 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> VaultProviderConfig:
+ """Update the supplied fields; omitted fields remain unchanged.
+
+ Names must remain
+ unique within the organization. Requires an organization-scoped credential or
+ dashboard authentication; project-scoped credentials receive 403.
+
+ Args:
+ credentials: Fields to update. Omitted credentials are left unchanged. A rejected update
+ leaves existing credentials unchanged.
+
+ name: Unique within the organization.
+
+ 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_or_name:
+ raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
+ return cast(
+ VaultProviderConfig,
+ await self._patch(
+ path_template("/vault-provider-configs/{id_or_name}", id_or_name=id_or_name),
+ body=await async_maybe_transform(
+ {
+ "credentials": credentials,
+ "name": name,
+ },
+ vault_provider_config_update_params.VaultProviderConfigUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=cast(
+ Any, VaultProviderConfig
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def list(
+ self,
+ *,
+ limit: int | Omit = omit,
+ offset: int | 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,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> AsyncPaginator[VaultProviderConfig, AsyncOffsetPagination[VaultProviderConfig]]:
+ """
+ Secret credentials are never returned.
+
+ 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
+ """
+ return self._get_api_list(
+ "/vault-provider-configs",
+ page=AsyncOffsetPagination[VaultProviderConfig],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "limit": limit,
+ "offset": offset,
+ },
+ vault_provider_config_list_params.VaultProviderConfigListParams,
+ ),
+ ),
+ model=cast(Any, VaultProviderConfig), # Union types cannot be passed in as arguments in the type system
+ )
+
+ async def delete(
+ self,
+ id_or_name: 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:
+ """Delete a configuration in the organization.
+
+ Returns 409 while any non-deleted
+ vault item references the configuration, regardless of connection status. Does
+ not delete the external OAuth client or revoke unrelated grants. Requires an
+ organization-scoped credential or dashboard authentication; project-scoped
+ credentials receive 403.
+
+ 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_or_name:
+ raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ path_template("/vault-provider-configs/{id_or_name}", id_or_name=id_or_name),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+
+class VaultProviderConfigsResourceWithRawResponse:
+ def __init__(self, vault_provider_configs: VaultProviderConfigsResource) -> None:
+ self._vault_provider_configs = vault_provider_configs
+
+ self.create = to_raw_response_wrapper(
+ vault_provider_configs.create,
+ )
+ self.retrieve = to_raw_response_wrapper(
+ vault_provider_configs.retrieve,
+ )
+ self.update = to_raw_response_wrapper(
+ vault_provider_configs.update,
+ )
+ self.list = to_raw_response_wrapper(
+ vault_provider_configs.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ vault_provider_configs.delete,
+ )
+
+
+class AsyncVaultProviderConfigsResourceWithRawResponse:
+ def __init__(self, vault_provider_configs: AsyncVaultProviderConfigsResource) -> None:
+ self._vault_provider_configs = vault_provider_configs
+
+ self.create = async_to_raw_response_wrapper(
+ vault_provider_configs.create,
+ )
+ self.retrieve = async_to_raw_response_wrapper(
+ vault_provider_configs.retrieve,
+ )
+ self.update = async_to_raw_response_wrapper(
+ vault_provider_configs.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ vault_provider_configs.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ vault_provider_configs.delete,
+ )
+
+
+class VaultProviderConfigsResourceWithStreamingResponse:
+ def __init__(self, vault_provider_configs: VaultProviderConfigsResource) -> None:
+ self._vault_provider_configs = vault_provider_configs
+
+ self.create = to_streamed_response_wrapper(
+ vault_provider_configs.create,
+ )
+ self.retrieve = to_streamed_response_wrapper(
+ vault_provider_configs.retrieve,
+ )
+ self.update = to_streamed_response_wrapper(
+ vault_provider_configs.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ vault_provider_configs.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ vault_provider_configs.delete,
+ )
+
+
+class AsyncVaultProviderConfigsResourceWithStreamingResponse:
+ def __init__(self, vault_provider_configs: AsyncVaultProviderConfigsResource) -> None:
+ self._vault_provider_configs = vault_provider_configs
+
+ self.create = async_to_streamed_response_wrapper(
+ vault_provider_configs.create,
+ )
+ self.retrieve = async_to_streamed_response_wrapper(
+ vault_provider_configs.retrieve,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ vault_provider_configs.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ vault_provider_configs.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ vault_provider_configs.delete,
+ )
diff --git a/src/kernel/resources/vaults/items.py b/src/kernel/resources/vaults/items.py
index b87d67cb..dd790910 100644
--- a/src/kernel/resources/vaults/items.py
+++ b/src/kernel/resources/vaults/items.py
@@ -29,7 +29,6 @@
from ...types.vaults.item_list_response import ItemListResponse
from ...types.vaults.item_events_response import ItemEventsResponse
from ...types.vaults.card_vault_item_spec_param import CardVaultItemSpecParam
-from ...types.vaults.wallet_vault_item_spec_param import WalletVaultItemSpecParam
__all__ = ["ItemsResource", "AsyncItemsResource"]
@@ -127,8 +126,15 @@ def update(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> VaultItem:
- """
- Update a card specification before or between authorizations
+ """Requested cards accept a replacement specification.
+
+ Pending issuance requests
+ may update provider-supported fields on their existing request, subject to
+ atomic provider approval checks; omitted optional fields remain unchanged and
+ explicit empty lists clear them. Wallet/provider binding and unsupported fields
+ cannot change after authorization starts. An uncertain update enters
+ recovery_required and must not be retried. Checkout cards may be edited between
+ authorizations.
Args:
spec: Live payment card. Test-mode card creation is not supported.
@@ -203,7 +209,9 @@ def delete(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
- Delete a vault item and invalidate its secret value
+ Unresolved payment operations block deletion, including operations on child
+ cards of a wallet. Reconcile the original attempt with the provider or support
+ first; deleting or recreating an item is not proof that a payment did not occur.
Args:
extra_headers: Send extra headers
@@ -295,8 +303,10 @@ def perform_operation(
"""
Retrieve the item first and invoke only an operation listed in
`available_operations`, following its natural-language description. Operations
- may call an external provider and can return the item's updated state. If the
- provider rate limits spend-request creation, returns HTTP 429 with code
+ may call an external provider and return updated state. Link cards advertise
+ authorize. AgentCard cards are created with PUT and request approval when their
+ aliases are used at checkout; they do not expose this operation. If
+ spend-request creation is rate limited, returns HTTP 429 with code
`spend_request_rate_limited`; stop and back off before retrying.
Args:
@@ -330,7 +340,7 @@ def upsert(
key: str,
*,
id_or_name: str,
- spec: WalletVaultItemSpecParam,
+ spec: item_upsert_params.WalletVaultItemRequestSpec,
type: Literal["wallet"],
# 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.
@@ -340,12 +350,20 @@ def upsert(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> VaultItem:
"""
- Create or retrieve an identical vault item by immutable key
+ Create an item under a key unique within its vault, or retrieve the existing
+ item when its specification matches. An identical card PUT returns the existing
+ card in any lifecycle state without polling the provider, reauthorizing,
+ replacing aliases, or resetting recovery. Conflicting specifications return 409.
+ Provider-specific authorization requirements and retry behavior are described in
+ the item's request schema.
Args:
- spec: AgentCard wallet. Mode (sandbox vs live) is fixed by the deployment's AgentCard
- credential; there is no per-item test flag. user_id may only reference a user
- already enrolled by a wallet in this organization.
+ spec: AgentCard wallet. Omit provider_config to use Kernel-managed credentials, or
+ select a customer-owned configuration. Mode (sandbox vs live) is determined by
+ the selected credential; there is no per-item test flag. Without user_id,
+ creation returns a hosted enrollment action and Kernel polls until the user
+ connects. user_id may only reference a user already enrolled by a wallet in this
+ organization under the same configuration.
extra_headers: Send extra headers
@@ -373,7 +391,12 @@ def upsert(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> VaultItem:
"""
- Create or retrieve an identical vault item by immutable key
+ Create an item under a key unique within its vault, or retrieve the existing
+ item when its specification matches. An identical card PUT returns the existing
+ card in any lifecycle state without polling the provider, reauthorizing,
+ replacing aliases, or resetting recovery. Conflicting specifications return 409.
+ Provider-specific authorization requirements and retry behavior are described in
+ the item's request schema.
Args:
spec: Live payment card. Test-mode card creation is not supported.
@@ -394,7 +417,7 @@ def upsert(
key: str,
*,
id_or_name: str,
- spec: WalletVaultItemSpecParam | CardVaultItemSpecParam,
+ spec: item_upsert_params.WalletVaultItemRequestSpec | CardVaultItemSpecParam,
type: Literal["wallet"] | Literal["card"],
# 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.
@@ -519,8 +542,15 @@ async def update(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> VaultItem:
- """
- Update a card specification before or between authorizations
+ """Requested cards accept a replacement specification.
+
+ Pending issuance requests
+ may update provider-supported fields on their existing request, subject to
+ atomic provider approval checks; omitted optional fields remain unchanged and
+ explicit empty lists clear them. Wallet/provider binding and unsupported fields
+ cannot change after authorization starts. An uncertain update enters
+ recovery_required and must not be retried. Checkout cards may be edited between
+ authorizations.
Args:
spec: Live payment card. Test-mode card creation is not supported.
@@ -595,7 +625,9 @@ async def delete(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
- Delete a vault item and invalidate its secret value
+ Unresolved payment operations block deletion, including operations on child
+ cards of a wallet. Reconcile the original attempt with the provider or support
+ first; deleting or recreating an item is not proof that a payment did not occur.
Args:
extra_headers: Send extra headers
@@ -687,8 +719,10 @@ async def perform_operation(
"""
Retrieve the item first and invoke only an operation listed in
`available_operations`, following its natural-language description. Operations
- may call an external provider and can return the item's updated state. If the
- provider rate limits spend-request creation, returns HTTP 429 with code
+ may call an external provider and return updated state. Link cards advertise
+ authorize. AgentCard cards are created with PUT and request approval when their
+ aliases are used at checkout; they do not expose this operation. If
+ spend-request creation is rate limited, returns HTTP 429 with code
`spend_request_rate_limited`; stop and back off before retrying.
Args:
@@ -724,7 +758,7 @@ async def upsert(
key: str,
*,
id_or_name: str,
- spec: WalletVaultItemSpecParam,
+ spec: item_upsert_params.WalletVaultItemRequestSpec,
type: Literal["wallet"],
# 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.
@@ -734,12 +768,20 @@ async def upsert(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> VaultItem:
"""
- Create or retrieve an identical vault item by immutable key
+ Create an item under a key unique within its vault, or retrieve the existing
+ item when its specification matches. An identical card PUT returns the existing
+ card in any lifecycle state without polling the provider, reauthorizing,
+ replacing aliases, or resetting recovery. Conflicting specifications return 409.
+ Provider-specific authorization requirements and retry behavior are described in
+ the item's request schema.
Args:
- spec: AgentCard wallet. Mode (sandbox vs live) is fixed by the deployment's AgentCard
- credential; there is no per-item test flag. user_id may only reference a user
- already enrolled by a wallet in this organization.
+ spec: AgentCard wallet. Omit provider_config to use Kernel-managed credentials, or
+ select a customer-owned configuration. Mode (sandbox vs live) is determined by
+ the selected credential; there is no per-item test flag. Without user_id,
+ creation returns a hosted enrollment action and Kernel polls until the user
+ connects. user_id may only reference a user already enrolled by a wallet in this
+ organization under the same configuration.
extra_headers: Send extra headers
@@ -767,7 +809,12 @@ async def upsert(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> VaultItem:
"""
- Create or retrieve an identical vault item by immutable key
+ Create an item under a key unique within its vault, or retrieve the existing
+ item when its specification matches. An identical card PUT returns the existing
+ card in any lifecycle state without polling the provider, reauthorizing,
+ replacing aliases, or resetting recovery. Conflicting specifications return 409.
+ Provider-specific authorization requirements and retry behavior are described in
+ the item's request schema.
Args:
spec: Live payment card. Test-mode card creation is not supported.
@@ -788,7 +835,7 @@ async def upsert(
key: str,
*,
id_or_name: str,
- spec: WalletVaultItemSpecParam | CardVaultItemSpecParam,
+ spec: item_upsert_params.WalletVaultItemRequestSpec | CardVaultItemSpecParam,
type: Literal["wallet"] | Literal["card"],
# 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.
diff --git a/src/kernel/resources/vaults/vaults.py b/src/kernel/resources/vaults/vaults.py
index ec33277c..16619462 100644
--- a/src/kernel/resources/vaults/vaults.py
+++ b/src/kernel/resources/vaults/vaults.py
@@ -141,8 +141,11 @@ def delete(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """
- Delete a vault and invalidate its items
+ """Unresolved payment operations block deletion.
+
+ Reconcile the original attempt
+ with the provider or support first; deleting or recreating an item is not proof
+ that a payment did not occur.
Args:
extra_headers: Send extra headers
@@ -176,7 +179,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.
@@ -310,8 +315,11 @@ async def delete(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """
- Delete a vault and invalidate its items
+ """Unresolved payment operations block deletion.
+
+ Reconcile the original attempt
+ with the provider or support first; deleting or recreating an item is not proof
+ that a payment did not occur.
Args:
extra_headers: Send extra headers
@@ -345,7 +353,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.
diff --git a/src/kernel/types/__init__.py b/src/kernel/types/__init__.py
index 0310cfbe..70e9581a 100644
--- a/src/kernel/types/__init__.py
+++ b/src/kernel/types/__init__.py
@@ -73,6 +73,7 @@
from .proxy_create_response import ProxyCreateResponse as ProxyCreateResponse
from .proxy_update_response import ProxyUpdateResponse as ProxyUpdateResponse
from .recommendation_result import RecommendationResult as RecommendationResult
+from .vault_provider_config import VaultProviderConfig as VaultProviderConfig
from .vault_reference_param import VaultReferenceParam as VaultReferenceParam
from .browser_memory_request import BrowserMemoryRequest as BrowserMemoryRequest
from .browser_network_config import BrowserNetworkConfig as BrowserNetworkConfig
@@ -131,6 +132,9 @@
from .credential_provider_create_params import CredentialProviderCreateParams as CredentialProviderCreateParams
from .credential_provider_update_params import CredentialProviderUpdateParams as CredentialProviderUpdateParams
from .invocation_list_browsers_response import InvocationListBrowsersResponse as InvocationListBrowsersResponse
+from .vault_provider_config_list_params import VaultProviderConfigListParams as VaultProviderConfigListParams
+from .vault_provider_config_create_params import VaultProviderConfigCreateParams as VaultProviderConfigCreateParams
+from .vault_provider_config_update_params import VaultProviderConfigUpdateParams as VaultProviderConfigUpdateParams
from .credential_provider_list_items_response import (
CredentialProviderListItemsResponse as CredentialProviderListItemsResponse,
)
diff --git a/src/kernel/types/analysis.py b/src/kernel/types/analysis.py
index 9bce3019..34184ae4 100644
--- a/src/kernel/types/analysis.py
+++ b/src/kernel/types/analysis.py
@@ -17,8 +17,11 @@ 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.
"""
@@ -26,5 +29,5 @@ class Analysis(BaseModel):
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."""
diff --git a/src/kernel/types/browsers/browser_proxy_error_event.py b/src/kernel/types/browsers/browser_proxy_error_event.py
index 6f52d3bb..d8c9dd93 100644
--- a/src/kernel/types/browsers/browser_proxy_error_event.py
+++ b/src/kernel/types/browsers/browser_proxy_error_event.py
@@ -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",
@@ -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
diff --git a/src/kernel/types/invocation_create_response.py b/src/kernel/types/invocation_create_response.py
index 21fbcf33..3e775279 100644
--- a/src/kernel/types/invocation_create_response.py
+++ b/src/kernel/types/invocation_create_response.py
@@ -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.
+ """
diff --git a/src/kernel/types/invocation_list_response.py b/src/kernel/types/invocation_list_response.py
index e635b4d8..f55dff9c 100644
--- a/src/kernel/types/invocation_list_response.py
+++ b/src/kernel/types/invocation_list_response.py
@@ -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
@@ -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.
+ """
diff --git a/src/kernel/types/invocation_retrieve_response.py b/src/kernel/types/invocation_retrieve_response.py
index 580424eb..e16c02de 100644
--- a/src/kernel/types/invocation_retrieve_response.py
+++ b/src/kernel/types/invocation_retrieve_response.py
@@ -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
@@ -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.
+ """
diff --git a/src/kernel/types/invocation_state_event.py b/src/kernel/types/invocation_state_event.py
index f32bf8e9..00abae7d 100644
--- a/src/kernel/types/invocation_state_event.py
+++ b/src/kernel/types/invocation_state_event.py
@@ -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
@@ -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):
diff --git a/src/kernel/types/invocation_update_response.py b/src/kernel/types/invocation_update_response.py
index 3bcc8bc0..92dfe5ed 100644
--- a/src/kernel/types/invocation_update_response.py
+++ b/src/kernel/types/invocation_update_response.py
@@ -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
@@ -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.
+ """
diff --git a/src/kernel/types/organization/org_entitlements.py b/src/kernel/types/organization/org_entitlements.py
index c940cbef..614ce2fa 100644
--- a/src/kernel/types/organization/org_entitlements.py
+++ b/src/kernel/types/organization/org_entitlements.py
@@ -21,6 +21,7 @@
"FeaturesManagedProxies",
"FeaturesProfiles",
"FeaturesProxyBypassHosts",
+ "FeaturesVaults",
"Limits",
"Plan",
]
@@ -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
@@ -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
@@ -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"]
diff --git a/src/kernel/types/organization/org_limits.py b/src/kernel/types/organization/org_limits.py
index bdc3cb4a..4e24a5f0 100644
--- a/src/kernel/types/organization/org_limits.py
+++ b/src/kernel/types/organization/org_limits.py
@@ -22,6 +22,12 @@ 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
@@ -29,6 +35,9 @@ class OrgLimits(BaseModel):
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
diff --git a/src/kernel/types/proxy.py b/src/kernel/types/proxy.py
index d5238ad7..9c945ce6 100644
--- a/src/kernel/types/proxy.py
+++ b/src/kernel/types/proxy.py
@@ -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):
@@ -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."""
@@ -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."""
diff --git a/src/kernel/types/proxy_check_response.py b/src/kernel/types/proxy_check_response.py
index 49833d66..d2821093 100644
--- a/src/kernel/types/proxy_check_response.py
+++ b/src/kernel/types/proxy_check_response.py
@@ -28,7 +28,10 @@ class ConfigIspProxyConfig(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 ConfigResidentialProxyConfig(BaseModel):
@@ -44,7 +47,10 @@ class ConfigResidentialProxyConfig(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."""
@@ -63,7 +69,10 @@ class ConfigMobileProxyConfig(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."""
diff --git a/src/kernel/types/proxy_create_params.py b/src/kernel/types/proxy_create_params.py
index 7069d9b1..3e5a7935 100644
--- a/src/kernel/types/proxy_create_params.py
+++ b/src/kernel/types/proxy_create_params.py
@@ -50,7 +50,10 @@ class ConfigIspProxyConfig(TypedDict, total=False):
"""Configuration for an ISP proxy."""
country: str
- """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 ConfigResidentialProxyConfig(TypedDict, total=False):
@@ -66,7 +69,10 @@ class ConfigResidentialProxyConfig(TypedDict, total=False):
"""
country: str
- """ISO 3166 country code."""
+ """ISO 3166 country code.
+
+ If omitted, the proxy uses the global pool without country targeting.
+ """
os: Literal["windows", "macos", "android"]
"""Operating system of the residential device."""
@@ -85,7 +91,10 @@ class ConfigMobileProxyConfig(TypedDict, total=False):
"""Provider city alias. Mobile carrier routing can make observed geo vary."""
country: str
- """ISO 3166 country code"""
+ """ISO 3166 country code.
+
+ If omitted, the proxy uses the global pool without country targeting.
+ """
state: str
"""US-only state code. Mobile carrier routing can make observed geo vary."""
diff --git a/src/kernel/types/proxy_create_response.py b/src/kernel/types/proxy_create_response.py
index eeddcc3a..7f0b1d7c 100644
--- a/src/kernel/types/proxy_create_response.py
+++ b/src/kernel/types/proxy_create_response.py
@@ -28,7 +28,10 @@ class ConfigIspProxyConfig(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 ConfigResidentialProxyConfig(BaseModel):
@@ -44,7 +47,10 @@ class ConfigResidentialProxyConfig(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."""
@@ -63,7 +69,10 @@ class ConfigMobileProxyConfig(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."""
diff --git a/src/kernel/types/proxy_list_response.py b/src/kernel/types/proxy_list_response.py
index 878ad7f2..eea62ec8 100644
--- a/src/kernel/types/proxy_list_response.py
+++ b/src/kernel/types/proxy_list_response.py
@@ -28,7 +28,10 @@ class ConfigIspProxyConfig(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 ConfigResidentialProxyConfig(BaseModel):
@@ -44,7 +47,10 @@ class ConfigResidentialProxyConfig(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."""
@@ -63,7 +69,10 @@ class ConfigMobileProxyConfig(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."""
diff --git a/src/kernel/types/proxy_retrieve_response.py b/src/kernel/types/proxy_retrieve_response.py
index f2eb1487..26a72906 100644
--- a/src/kernel/types/proxy_retrieve_response.py
+++ b/src/kernel/types/proxy_retrieve_response.py
@@ -28,7 +28,10 @@ class ConfigIspProxyConfig(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 ConfigResidentialProxyConfig(BaseModel):
@@ -44,7 +47,10 @@ class ConfigResidentialProxyConfig(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."""
@@ -63,7 +69,10 @@ class ConfigMobileProxyConfig(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."""
diff --git a/src/kernel/types/proxy_update_response.py b/src/kernel/types/proxy_update_response.py
index bae95bba..85b8d5ab 100644
--- a/src/kernel/types/proxy_update_response.py
+++ b/src/kernel/types/proxy_update_response.py
@@ -28,7 +28,10 @@ class ConfigIspProxyConfig(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 ConfigResidentialProxyConfig(BaseModel):
@@ -44,7 +47,10 @@ class ConfigResidentialProxyConfig(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."""
@@ -63,7 +69,10 @@ class ConfigMobileProxyConfig(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."""
diff --git a/src/kernel/types/recommendation_summary.py b/src/kernel/types/recommendation_summary.py
index 278ba9ef..5716ae60 100644
--- a/src/kernel/types/recommendation_summary.py
+++ b/src/kernel/types/recommendation_summary.py
@@ -14,7 +14,7 @@ class RecommendationSummary(BaseModel):
analysis_id: str
"""ID of the most recently requested analysis for this exact target."""
- analysis_status: Literal["running", "completed", "failed", "canceled"]
+ analysis_status: Literal["running", "completed", "failed", "canceled", "expired"]
"""Lifecycle status of the most recently requested analysis for this exact target."""
last_requested_at: datetime
diff --git a/src/kernel/types/vault_provider_config.py b/src/kernel/types/vault_provider_config.py
new file mode 100644
index 00000000..7ab9a049
--- /dev/null
+++ b/src/kernel/types/vault_provider_config.py
@@ -0,0 +1,58 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Literal, Annotated, TypeAlias
+
+from .._utils import PropertyInfo
+from .._models import BaseModel
+
+__all__ = ["VaultProviderConfig", "VaultLinkProviderConfig", "VaultAgentCardProviderConfig"]
+
+
+class VaultLinkProviderConfig(BaseModel):
+ """Response schema for a Link configuration, without secret credentials.
+
+ Kernel generates the ID and timestamps. Configuration creation uses VaultLinkProviderConfigRequest.
+ """
+
+ id: str
+
+ client_id: str
+ """OAuth client identity; immutable. Secret credentials are never returned."""
+
+ created_at: datetime
+
+ name: str
+ """Unique within the organization."""
+
+ provider: Literal["link"]
+
+ updated_at: datetime
+
+
+class VaultAgentCardProviderConfig(BaseModel):
+ """Response schema for an AgentCard configuration, without secret credentials.
+
+ Kernel generates the ID and timestamps and introspects test_mode from the credentials. Configuration creation uses VaultAgentCardProviderConfigRequest.
+ """
+
+ id: str
+
+ client_id: str
+
+ created_at: datetime
+
+ name: str
+
+ provider: Literal["agentcard"]
+
+ test_mode: bool
+ """Introspected mode of the selected credential; true means sandbox objects."""
+
+ updated_at: datetime
+
+
+VaultProviderConfig: TypeAlias = Annotated[
+ Union[VaultLinkProviderConfig, VaultAgentCardProviderConfig], PropertyInfo(discriminator="provider")
+]
diff --git a/src/kernel/types/vault_provider_config_create_params.py b/src/kernel/types/vault_provider_config_create_params.py
new file mode 100644
index 00000000..185f06a6
--- /dev/null
+++ b/src/kernel/types/vault_provider_config_create_params.py
@@ -0,0 +1,47 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+__all__ = [
+ "VaultProviderConfigCreateParams",
+ "VaultLinkProviderConfigRequest",
+ "VaultLinkProviderConfigRequestCredentials",
+ "VaultAgentCardProviderConfigRequest",
+ "VaultAgentCardProviderConfigRequestCredentials",
+]
+
+
+class VaultLinkProviderConfigRequest(TypedDict, total=False):
+ credentials: Required[VaultLinkProviderConfigRequestCredentials]
+
+ name: Required[str]
+ """Unique within the organization."""
+
+ provider: Required[Literal["link"]]
+
+
+class VaultLinkProviderConfigRequestCredentials(TypedDict, total=False):
+ client_id: Required[str]
+
+ client_secret: Required[str]
+
+
+class VaultAgentCardProviderConfigRequest(TypedDict, total=False):
+ credentials: Required[VaultAgentCardProviderConfigRequestCredentials]
+
+ name: Required[str]
+ """Unique within the organization."""
+
+ provider: Required[Literal["agentcard"]]
+
+
+class VaultAgentCardProviderConfigRequestCredentials(TypedDict, total=False):
+ client_id: Required[str]
+
+ client_secret: Required[str]
+
+
+VaultProviderConfigCreateParams: TypeAlias = Union[VaultLinkProviderConfigRequest, VaultAgentCardProviderConfigRequest]
diff --git a/src/kernel/types/vault_provider_config_list_params.py b/src/kernel/types/vault_provider_config_list_params.py
new file mode 100644
index 00000000..27065f97
--- /dev/null
+++ b/src/kernel/types/vault_provider_config_list_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["VaultProviderConfigListParams"]
+
+
+class VaultProviderConfigListParams(TypedDict, total=False):
+ limit: int
+
+ offset: int
diff --git a/src/kernel/types/vault_provider_config_update_params.py b/src/kernel/types/vault_provider_config_update_params.py
new file mode 100644
index 00000000..49d1be8a
--- /dev/null
+++ b/src/kernel/types/vault_provider_config_update_params.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["VaultProviderConfigUpdateParams", "Credentials"]
+
+
+class VaultProviderConfigUpdateParams(TypedDict, total=False):
+ credentials: Credentials
+ """Fields to update.
+
+ Omitted credentials are left unchanged. A rejected update leaves existing
+ credentials unchanged.
+ """
+
+ name: str
+ """Unique within the organization."""
+
+
+class Credentials(TypedDict, total=False):
+ """Fields to update.
+
+ Omitted credentials are left unchanged. A rejected update leaves existing credentials unchanged.
+ """
+
+ client_secret: str
diff --git a/src/kernel/types/vaults/__init__.py b/src/kernel/types/vaults/__init__.py
index 7ee998eb..623e45d4 100644
--- a/src/kernel/types/vaults/__init__.py
+++ b/src/kernel/types/vaults/__init__.py
@@ -18,6 +18,5 @@
from .wallet_vault_item_spec import WalletVaultItemSpec as WalletVaultItemSpec
from .wallet_vault_item_state import WalletVaultItemState as WalletVaultItemState
from .card_vault_item_spec_param import CardVaultItemSpecParam as CardVaultItemSpecParam
-from .wallet_vault_item_spec_param import WalletVaultItemSpecParam as WalletVaultItemSpecParam
from .item_perform_operation_params import ItemPerformOperationParams as ItemPerformOperationParams
from .agentcard_checkout_authorization import AgentcardCheckoutAuthorization as AgentcardCheckoutAuthorization
diff --git a/src/kernel/types/vaults/card_vault_item_state.py b/src/kernel/types/vaults/card_vault_item_state.py
index 4808d1ff..7bb7e274 100644
--- a/src/kernel/types/vaults/card_vault_item_state.py
+++ b/src/kernel/types/vaults/card_vault_item_state.py
@@ -34,7 +34,17 @@ def __getattr__(self, attr: str) -> str: ...
class LinkCardState(BaseModel):
provider: Literal["link"]
- status: Literal["requested", "pending_authorization", "ready", "consumed", "expired", "declined"]
+ status: Literal[
+ "requested", "pending_authorization", "ready", "consumed", "expired", "declined", "recovery_required"
+ ]
+ """recovery_required means an original provider operation has an unresolved
+ outcome.
+
+ Do not retry, delete, or replace it. Known references may be observed safely,
+ but unknown creation without an ID and uncertain card-material retrieval require
+ manual reconciliation with the provider or support. There is no reset or
+ caller-asserted reconciliation operation.
+ """
aliases: Optional[VaultCardAliases] = None
@@ -66,7 +76,13 @@ def __getattr__(self, attr: str) -> str: ...
class AgentCardCardState(BaseModel):
provider: Literal["agentcard"]
- status: Literal["requested", "ready", "pending_approval", "degraded"]
+ status: Literal["requested", "ready", "pending_approval", "degraded", "recovery_required"]
+ """recovery_required means the original checkout outcome is unresolved.
+
+ Do not retry, delete, or replace it. Known authorization IDs may be reconciled
+ through provider observations; otherwise contact the provider or support for
+ manual reconciliation. It does not mean declined or expired.
+ """
aliases: Optional[VaultCardAliases] = None
diff --git a/src/kernel/types/vaults/item_upsert_params.py b/src/kernel/types/vaults/item_upsert_params.py
index c3fe00e8..2a62d726 100644
--- a/src/kernel/types/vaults/item_upsert_params.py
+++ b/src/kernel/types/vaults/item_upsert_params.py
@@ -6,25 +6,176 @@
from typing_extensions import Literal, Required, TypeAlias, TypedDict
from .card_vault_item_spec_param import CardVaultItemSpecParam
-from .wallet_vault_item_spec_param import WalletVaultItemSpecParam
-__all__ = ["ItemUpsertParams", "WalletVaultItemRequest", "CardVaultItemRequest"]
+__all__ = [
+ "ItemUpsertParams",
+ "WalletVaultItemRequest",
+ "WalletVaultItemRequestSpec",
+ "WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpec",
+ "WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorization",
+ "WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationKernelManagedLinkAuthorizationInput",
+ "WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationKernelManagedLinkAuthorizationInputClient",
+ "WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInput",
+ "WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputClient",
+ "WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputClientProviderConfig",
+ "WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputTokens",
+ "WalletVaultItemRequestSpecAgentCardWalletVaultItemSpec",
+ "WalletVaultItemRequestSpecAgentCardWalletVaultItemSpecProviderConfig",
+ "CardVaultItemRequest",
+]
class WalletVaultItemRequest(TypedDict, total=False):
id_or_name: Required[str]
- spec: Required[WalletVaultItemSpecParam]
+ spec: Required[WalletVaultItemRequestSpec]
"""AgentCard wallet.
- Mode (sandbox vs live) is fixed by the deployment's AgentCard credential; there
- is no per-item test flag. user_id may only reference a user already enrolled by
- a wallet in this organization.
+ Omit provider_config to use Kernel-managed credentials, or select a
+ customer-owned configuration. Mode (sandbox vs live) is determined by the
+ selected credential; there is no per-item test flag. Without user_id, creation
+ returns a hosted enrollment action and Kernel polls until the user connects.
+ user_id may only reference a user already enrolled by a wallet in this
+ organization under the same configuration.
"""
type: Required[Literal["wallet"]]
+class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationKernelManagedLinkAuthorizationInputClient(
+ TypedDict, total=False
+):
+ type: Required[Literal["kernel_managed"]]
+
+
+class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationKernelManagedLinkAuthorizationInput(
+ TypedDict, total=False
+):
+ """Kernel starts and completes the user's Link authorization flow."""
+
+ client: Required[
+ WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationKernelManagedLinkAuthorizationInputClient
+ ]
+
+ method: Required[Literal["oauth"]]
+
+
+class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputClientProviderConfig(
+ TypedDict, total=False
+):
+ """Select a provider config by ID or name.
+
+ Responses return the ID. Renaming a config does not change existing wallet bindings; a wallet cannot switch to a different config after creation.
+ """
+
+ id: str
+
+ name: str
+
+
+class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputClient(
+ TypedDict, total=False
+):
+ provider_config: Required[
+ WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputClientProviderConfig
+ ]
+ """Select a provider config by ID or name.
+
+ Responses return the ID. Renaming a config does not change existing wallet
+ bindings; a wallet cannot switch to a different config after creation.
+ """
+
+ type: Required[Literal["customer_managed"]]
+
+
+class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputTokens(
+ TypedDict, total=False
+):
+ """Send the token pair from your backend.
+
+ Both tokens must be from the same Link grant under the referenced client. Supply a currently valid access token. Kernel refreshes when needed after import and uses the expiry returned by Link for subsequent tokens. Tokens are never returned in wallet responses, events, or logs.
+ """
+
+ access_token: Required[str]
+
+ refresh_token: Required[str]
+
+
+class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInput(
+ TypedDict, total=False
+):
+ """The customer's backend completes Link OAuth and supplies the resulting tokens.
+
+ For a new wallet, Kernel verifies the access token can access Link payment methods without consuming or rotating the refresh token. Valid access creates a wallet with state.status=connected. An expired, invalid, revoked, or insufficiently scoped access token returns 400 and no wallet is created. Refresh expired tokens in your backend before importing them. A failed import does not modify existing wallets.
+ After successful import, Kernel owns subsequent refresh-token rotation; the customer must stop refreshing this grant. Import does not verify the refresh token: if it or the configured client credentials are rejected during a later refresh, the imported wallet becomes degraded. An unknown refresh outcome also leaves it degraded; Kernel does not retry a refresh token that may already have been consumed. There is no in-place reauthorization operation for an imported wallet.
+ If this imported wallet's credentials become unusable, obtain a fresh Link OAuth grant in your backend and create a wallet under a NEW wallet key. Use the new wallet for NEW cards and payments, not to retry an old payment whose outcome is uncertain. This does not replace the old grant, rebind existing cards, or resolve their payment outcomes. Retain the old wallet and its cards while reconciling any uncertain payments with the provider or support. Do not repeat an uncertain payment on the new wallet, and do not treat deletion as evidence that it did not execute. Deletion of the old wallet can remain blocked by unresolved child cards.
+ Repeating a create for the same item key and non-secret spec returns the existing wallet without replacing tokens, even if they have rotated or the wallet needs reconnection. ID and name references resolving to the same config are equivalent. A different config or non-secret spec returns 409. This create operation does not replace an existing grant.
+ """
+
+ client: Required[
+ WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputClient
+ ]
+
+ method: Required[Literal["oauth"]]
+
+ tokens: Required[
+ WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInputTokens
+ ]
+ """Send the token pair from your backend.
+
+ Both tokens must be from the same Link grant under the referenced client. Supply
+ a currently valid access token. Kernel refreshes when needed after import and
+ uses the expiry returned by Link for subsequent tokens. Tokens are never
+ returned in wallet responses, events, or logs.
+ """
+
+
+WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorization: TypeAlias = Union[
+ WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationKernelManagedLinkAuthorizationInput,
+ WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorizationImportedLinkAuthorizationInput,
+]
+
+
+class WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpec(TypedDict, total=False):
+ authorization: Required[WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpecAuthorization]
+ """Kernel starts and completes the user's Link authorization flow."""
+
+ provider: Required[Literal["link"]]
+
+
+class WalletVaultItemRequestSpecAgentCardWalletVaultItemSpecProviderConfig(TypedDict, total=False):
+ """Select an AgentCard configuration.
+
+ The wallet's configuration cannot be changed after creation.
+ """
+
+ id: str
+
+ name: str
+
+
+class WalletVaultItemRequestSpecAgentCardWalletVaultItemSpec(TypedDict, total=False):
+ """AgentCard wallet.
+
+ Omit provider_config to use Kernel-managed credentials, or select a customer-owned configuration. Mode (sandbox vs live) is determined by the selected credential; there is no per-item test flag. Without user_id, creation returns a hosted enrollment action and Kernel polls until the user connects. user_id may only reference a user already enrolled by a wallet in this organization under the same configuration.
+ """
+
+ provider: Required[Literal["agentcard"]]
+
+ provider_config: WalletVaultItemRequestSpecAgentCardWalletVaultItemSpecProviderConfig
+ """Select an AgentCard configuration.
+
+ The wallet's configuration cannot be changed after creation.
+ """
+
+ user_id: str
+
+
+WalletVaultItemRequestSpec: TypeAlias = Union[
+ WalletVaultItemRequestSpecLinkWalletVaultItemRequestSpec, WalletVaultItemRequestSpecAgentCardWalletVaultItemSpec
+]
+
+
class CardVaultItemRequest(TypedDict, total=False):
id_or_name: Required[str]
diff --git a/src/kernel/types/vaults/vault_item.py b/src/kernel/types/vaults/vault_item.py
index 7f4c9b81..2cc7ab26 100644
--- a/src/kernel/types/vaults/vault_item.py
+++ b/src/kernel/types/vaults/vault_item.py
@@ -67,9 +67,12 @@ class WalletVaultItem(BaseModel):
spec: WalletVaultItemSpec
"""AgentCard wallet.
- Mode (sandbox vs live) is fixed by the deployment's AgentCard credential; there
- is no per-item test flag. user_id may only reference a user already enrolled by
- a wallet in this organization.
+ Omit provider_config to use Kernel-managed credentials, or select a
+ customer-owned configuration. Mode (sandbox vs live) is determined by the
+ selected credential; there is no per-item test flag. Without user_id, creation
+ returns a hosted enrollment action and Kernel polls until the user connects.
+ user_id may only reference a user already enrolled by a wallet in this
+ organization under the same configuration.
"""
state: WalletVaultItemState
diff --git a/src/kernel/types/vaults/wallet_vault_item_spec.py b/src/kernel/types/vaults/wallet_vault_item_spec.py
index 03176670..2c17933d 100644
--- a/src/kernel/types/vaults/wallet_vault_item_spec.py
+++ b/src/kernel/types/vaults/wallet_vault_item_spec.py
@@ -11,14 +11,49 @@
"LinkWalletVaultItemSpec",
"LinkWalletVaultItemSpecAuthorization",
"LinkWalletVaultItemSpecAuthorizationClient",
+ "LinkWalletVaultItemSpecAuthorizationClientKernelManagedOAuthClient",
+ "LinkWalletVaultItemSpecAuthorizationClientCustomerManagedOAuthClient",
+ "LinkWalletVaultItemSpecAuthorizationClientCustomerManagedOAuthClientProviderConfig",
"AgentCardWalletVaultItemSpec",
+ "AgentCardWalletVaultItemSpecProviderConfig",
]
-class LinkWalletVaultItemSpecAuthorizationClient(BaseModel):
+class LinkWalletVaultItemSpecAuthorizationClientKernelManagedOAuthClient(BaseModel):
type: Literal["kernel_managed"]
+class LinkWalletVaultItemSpecAuthorizationClientCustomerManagedOAuthClientProviderConfig(BaseModel):
+ """Select a provider config by ID or name.
+
+ Responses return the ID. Renaming a config does not change existing wallet bindings; a wallet cannot switch to a different config after creation.
+ """
+
+ id: Optional[str] = None
+
+ name: Optional[str] = None
+
+
+class LinkWalletVaultItemSpecAuthorizationClientCustomerManagedOAuthClient(BaseModel):
+ provider_config: LinkWalletVaultItemSpecAuthorizationClientCustomerManagedOAuthClientProviderConfig
+ """Select a provider config by ID or name.
+
+ Responses return the ID. Renaming a config does not change existing wallet
+ bindings; a wallet cannot switch to a different config after creation.
+ """
+
+ type: Literal["customer_managed"]
+
+
+LinkWalletVaultItemSpecAuthorizationClient: TypeAlias = Annotated[
+ Union[
+ LinkWalletVaultItemSpecAuthorizationClientKernelManagedOAuthClient,
+ LinkWalletVaultItemSpecAuthorizationClientCustomerManagedOAuthClient,
+ ],
+ PropertyInfo(discriminator="type"),
+]
+
+
class LinkWalletVaultItemSpecAuthorization(BaseModel):
client: LinkWalletVaultItemSpecAuthorizationClient
@@ -31,14 +66,31 @@ class LinkWalletVaultItemSpec(BaseModel):
provider: Literal["link"]
+class AgentCardWalletVaultItemSpecProviderConfig(BaseModel):
+ """Select an AgentCard configuration.
+
+ The wallet's configuration cannot be changed after creation.
+ """
+
+ id: Optional[str] = None
+
+ name: Optional[str] = None
+
+
class AgentCardWalletVaultItemSpec(BaseModel):
"""AgentCard wallet.
- Mode (sandbox vs live) is fixed by the deployment's AgentCard credential; there is no per-item test flag. user_id may only reference a user already enrolled by a wallet in this organization.
+ Omit provider_config to use Kernel-managed credentials, or select a customer-owned configuration. Mode (sandbox vs live) is determined by the selected credential; there is no per-item test flag. Without user_id, creation returns a hosted enrollment action and Kernel polls until the user connects. user_id may only reference a user already enrolled by a wallet in this organization under the same configuration.
"""
provider: Literal["agentcard"]
+ provider_config: Optional[AgentCardWalletVaultItemSpecProviderConfig] = None
+ """Select an AgentCard configuration.
+
+ The wallet's configuration cannot be changed after creation.
+ """
+
user_id: Optional[str] = None
diff --git a/src/kernel/types/vaults/wallet_vault_item_spec_param.py b/src/kernel/types/vaults/wallet_vault_item_spec_param.py
deleted file mode 100644
index dc30e054..00000000
--- a/src/kernel/types/vaults/wallet_vault_item_spec_param.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Union
-from typing_extensions import Literal, Required, TypeAlias, TypedDict
-
-__all__ = [
- "WalletVaultItemSpecParam",
- "LinkWalletVaultItemSpec",
- "LinkWalletVaultItemSpecAuthorization",
- "LinkWalletVaultItemSpecAuthorizationClient",
- "AgentCardWalletVaultItemSpec",
-]
-
-
-class LinkWalletVaultItemSpecAuthorizationClient(TypedDict, total=False):
- type: Required[Literal["kernel_managed"]]
-
-
-class LinkWalletVaultItemSpecAuthorization(TypedDict, total=False):
- client: Required[LinkWalletVaultItemSpecAuthorizationClient]
-
- method: Required[Literal["oauth"]]
-
-
-class LinkWalletVaultItemSpec(TypedDict, total=False):
- authorization: Required[LinkWalletVaultItemSpecAuthorization]
-
- provider: Required[Literal["link"]]
-
-
-class AgentCardWalletVaultItemSpec(TypedDict, total=False):
- """AgentCard wallet.
-
- Mode (sandbox vs live) is fixed by the deployment's AgentCard credential; there is no per-item test flag. user_id may only reference a user already enrolled by a wallet in this organization.
- """
-
- provider: Required[Literal["agentcard"]]
-
- user_id: str
-
-
-WalletVaultItemSpecParam: TypeAlias = Union[LinkWalletVaultItemSpec, AgentCardWalletVaultItemSpec]
diff --git a/tests/api_resources/test_vault_provider_configs.py b/tests/api_resources/test_vault_provider_configs.py
new file mode 100644
index 00000000..7ab21cd5
--- /dev/null
+++ b/tests/api_resources/test_vault_provider_configs.py
@@ -0,0 +1,569 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from kernel import Kernel, AsyncKernel
+from tests.utils import assert_matches_type
+from kernel.types import (
+ VaultProviderConfig,
+)
+from kernel.pagination import SyncOffsetPagination, AsyncOffsetPagination
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestVaultProviderConfigs:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_overload_1(self, client: Kernel) -> None:
+ vault_provider_config = client.vault_provider_configs.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="link",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_create_overload_1(self, client: Kernel) -> None:
+ response = client.vault_provider_configs.with_raw_response.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="link",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_create_overload_1(self, client: Kernel) -> None:
+ with client.vault_provider_configs.with_streaming_response.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="link",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_overload_2(self, client: Kernel) -> None:
+ vault_provider_config = client.vault_provider_configs.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="agentcard",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_create_overload_2(self, client: Kernel) -> None:
+ response = client.vault_provider_configs.with_raw_response.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="agentcard",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_create_overload_2(self, client: Kernel) -> None:
+ with client.vault_provider_configs.with_streaming_response.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="agentcard",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve(self, client: Kernel) -> None:
+ vault_provider_config = client.vault_provider_configs.retrieve(
+ "id_or_name",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: Kernel) -> None:
+ response = client.vault_provider_configs.with_raw_response.retrieve(
+ "id_or_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Kernel) -> None:
+ with client.vault_provider_configs.with_streaming_response.retrieve(
+ "id_or_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve(self, client: Kernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
+ client.vault_provider_configs.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update(self, client: Kernel) -> None:
+ vault_provider_config = client.vault_provider_configs.update(
+ id_or_name="id_or_name",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update_with_all_params(self, client: Kernel) -> None:
+ vault_provider_config = client.vault_provider_configs.update(
+ id_or_name="id_or_name",
+ credentials={"client_secret": "x"},
+ name="renamed-link-client",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_update(self, client: Kernel) -> None:
+ response = client.vault_provider_configs.with_raw_response.update(
+ id_or_name="id_or_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_update(self, client: Kernel) -> None:
+ with client.vault_provider_configs.with_streaming_response.update(
+ id_or_name="id_or_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_update(self, client: Kernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
+ client.vault_provider_configs.with_raw_response.update(
+ id_or_name="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Kernel) -> None:
+ vault_provider_config = client.vault_provider_configs.list()
+ assert_matches_type(SyncOffsetPagination[VaultProviderConfig], vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Kernel) -> None:
+ vault_provider_config = client.vault_provider_configs.list(
+ limit=1,
+ offset=0,
+ )
+ assert_matches_type(SyncOffsetPagination[VaultProviderConfig], vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Kernel) -> None:
+ response = client.vault_provider_configs.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = response.parse()
+ assert_matches_type(SyncOffsetPagination[VaultProviderConfig], vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Kernel) -> None:
+ with client.vault_provider_configs.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = response.parse()
+ assert_matches_type(SyncOffsetPagination[VaultProviderConfig], vault_provider_config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_delete(self, client: Kernel) -> None:
+ vault_provider_config = client.vault_provider_configs.delete(
+ "id_or_name",
+ )
+ assert vault_provider_config is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_delete(self, client: Kernel) -> None:
+ response = client.vault_provider_configs.with_raw_response.delete(
+ "id_or_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = response.parse()
+ assert vault_provider_config is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_delete(self, client: Kernel) -> None:
+ with client.vault_provider_configs.with_streaming_response.delete(
+ "id_or_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = response.parse()
+ assert vault_provider_config is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_delete(self, client: Kernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
+ client.vault_provider_configs.with_raw_response.delete(
+ "",
+ )
+
+
+class TestAsyncVaultProviderConfigs:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_overload_1(self, async_client: AsyncKernel) -> None:
+ vault_provider_config = await async_client.vault_provider_configs.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="link",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_create_overload_1(self, async_client: AsyncKernel) -> None:
+ response = await async_client.vault_provider_configs.with_raw_response.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="link",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = await response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_create_overload_1(self, async_client: AsyncKernel) -> None:
+ async with async_client.vault_provider_configs.with_streaming_response.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="link",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = await response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_overload_2(self, async_client: AsyncKernel) -> None:
+ vault_provider_config = await async_client.vault_provider_configs.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="agentcard",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_create_overload_2(self, async_client: AsyncKernel) -> None:
+ response = await async_client.vault_provider_configs.with_raw_response.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="agentcard",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = await response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_create_overload_2(self, async_client: AsyncKernel) -> None:
+ async with async_client.vault_provider_configs.with_streaming_response.create(
+ credentials={
+ "client_id": "x",
+ "client_secret": "x",
+ },
+ name="name",
+ provider="agentcard",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = await response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncKernel) -> None:
+ vault_provider_config = await async_client.vault_provider_configs.retrieve(
+ "id_or_name",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncKernel) -> None:
+ response = await async_client.vault_provider_configs.with_raw_response.retrieve(
+ "id_or_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = await response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncKernel) -> None:
+ async with async_client.vault_provider_configs.with_streaming_response.retrieve(
+ "id_or_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = await response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, 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_retrieve(self, async_client: AsyncKernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
+ await async_client.vault_provider_configs.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update(self, async_client: AsyncKernel) -> None:
+ vault_provider_config = await async_client.vault_provider_configs.update(
+ id_or_name="id_or_name",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> None:
+ vault_provider_config = await async_client.vault_provider_configs.update(
+ id_or_name="id_or_name",
+ credentials={"client_secret": "x"},
+ name="renamed-link-client",
+ )
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncKernel) -> None:
+ response = await async_client.vault_provider_configs.with_raw_response.update(
+ id_or_name="id_or_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = await response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncKernel) -> None:
+ async with async_client.vault_provider_configs.with_streaming_response.update(
+ id_or_name="id_or_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = await response.parse()
+ assert_matches_type(VaultProviderConfig, vault_provider_config, 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_update(self, async_client: AsyncKernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
+ await async_client.vault_provider_configs.with_raw_response.update(
+ id_or_name="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncKernel) -> None:
+ vault_provider_config = await async_client.vault_provider_configs.list()
+ assert_matches_type(AsyncOffsetPagination[VaultProviderConfig], vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncKernel) -> None:
+ vault_provider_config = await async_client.vault_provider_configs.list(
+ limit=1,
+ offset=0,
+ )
+ assert_matches_type(AsyncOffsetPagination[VaultProviderConfig], vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncKernel) -> None:
+ response = await async_client.vault_provider_configs.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = await response.parse()
+ assert_matches_type(AsyncOffsetPagination[VaultProviderConfig], vault_provider_config, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncKernel) -> None:
+ async with async_client.vault_provider_configs.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = await response.parse()
+ assert_matches_type(AsyncOffsetPagination[VaultProviderConfig], vault_provider_config, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncKernel) -> None:
+ vault_provider_config = await async_client.vault_provider_configs.delete(
+ "id_or_name",
+ )
+ assert vault_provider_config is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncKernel) -> None:
+ response = await async_client.vault_provider_configs.with_raw_response.delete(
+ "id_or_name",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ vault_provider_config = await response.parse()
+ assert vault_provider_config is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncKernel) -> None:
+ async with async_client.vault_provider_configs.with_streaming_response.delete(
+ "id_or_name",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ vault_provider_config = await response.parse()
+ assert vault_provider_config 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_delete(self, async_client: AsyncKernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
+ await async_client.vault_provider_configs.with_raw_response.delete(
+ "",
+ )
diff --git a/tests/api_resources/test_vaults.py b/tests/api_resources/test_vaults.py
index 0836a7f8..f9b36c73 100644
--- a/tests/api_resources/test_vaults.py
+++ b/tests/api_resources/test_vaults.py
@@ -143,7 +143,7 @@ def test_path_params_delete(self, client: Kernel) -> None:
@parametrize
def test_method_upsert(self, client: Kernel) -> None:
vault = client.vaults.upsert(
- name="name",
+ name="checkout",
)
assert_matches_type(Vault, vault, path=["response"])
@@ -151,7 +151,7 @@ def test_method_upsert(self, client: Kernel) -> None:
@parametrize
def test_raw_response_upsert(self, client: Kernel) -> None:
response = client.vaults.with_raw_response.upsert(
- name="name",
+ name="checkout",
)
assert response.is_closed is True
@@ -163,7 +163,7 @@ def test_raw_response_upsert(self, client: Kernel) -> None:
@parametrize
def test_streaming_response_upsert(self, client: Kernel) -> None:
with client.vaults.with_streaming_response.upsert(
- name="name",
+ name="checkout",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -304,7 +304,7 @@ async def test_path_params_delete(self, async_client: AsyncKernel) -> None:
@parametrize
async def test_method_upsert(self, async_client: AsyncKernel) -> None:
vault = await async_client.vaults.upsert(
- name="name",
+ name="checkout",
)
assert_matches_type(Vault, vault, path=["response"])
@@ -312,7 +312,7 @@ async def test_method_upsert(self, async_client: AsyncKernel) -> None:
@parametrize
async def test_raw_response_upsert(self, async_client: AsyncKernel) -> None:
response = await async_client.vaults.with_raw_response.upsert(
- name="name",
+ name="checkout",
)
assert response.is_closed is True
@@ -324,7 +324,7 @@ async def test_raw_response_upsert(self, async_client: AsyncKernel) -> None:
@parametrize
async def test_streaming_response_upsert(self, async_client: AsyncKernel) -> None:
async with async_client.vaults.with_streaming_response.upsert(
- name="name",
+ name="checkout",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/api_resources/vaults/test_items.py b/tests/api_resources/vaults/test_items.py
index 51759529..9747f919 100644
--- a/tests/api_resources/vaults/test_items.py
+++ b/tests/api_resources/vaults/test_items.py
@@ -91,14 +91,14 @@ def test_method_update(self, client: Kernel) -> None:
key="x",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
)
assert_matches_type(VaultItem, item, path=["response"])
@@ -110,14 +110,14 @@ def test_method_update_with_all_params(self, client: Kernel) -> None:
key="x",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
"expires_at": 0,
"line_items": [
{
@@ -157,14 +157,14 @@ def test_raw_response_update(self, client: Kernel) -> None:
key="x",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
)
@@ -180,14 +180,14 @@ def test_streaming_response_update(self, client: Kernel) -> None:
key="x",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
) as response:
assert not response.is_closed
@@ -206,14 +206,14 @@ def test_path_params_update(self, client: Kernel) -> None:
key="x",
id_or_name="",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
)
@@ -222,14 +222,14 @@ def test_path_params_update(self, client: Kernel) -> None:
key="",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
)
@@ -787,14 +787,14 @@ async def test_method_update(self, async_client: AsyncKernel) -> None:
key="x",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
)
assert_matches_type(VaultItem, item, path=["response"])
@@ -806,14 +806,14 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) ->
key="x",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
"expires_at": 0,
"line_items": [
{
@@ -853,14 +853,14 @@ async def test_raw_response_update(self, async_client: AsyncKernel) -> None:
key="x",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
)
@@ -876,14 +876,14 @@ async def test_streaming_response_update(self, async_client: AsyncKernel) -> Non
key="x",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
) as response:
assert not response.is_closed
@@ -902,14 +902,14 @@ async def test_path_params_update(self, async_client: AsyncKernel) -> None:
key="x",
id_or_name="",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
)
@@ -918,14 +918,14 @@ async def test_path_params_update(self, async_client: AsyncKernel) -> None:
key="",
id_or_name="id_or_name",
spec={
- "amount": 1,
- "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
- "currency": "bFx",
- "merchant_name": "x",
- "merchant_url": "https://example.com",
- "payment_method_id": "x",
+ "amount": 3000,
+ "context": "The order total changed to USD 30.00 including shipping and taxes for one notebook. Update this unapproved request rather than creating a second payment.",
+ "currency": "usd",
+ "merchant_name": "Example Store",
+ "merchant_url": "https://store.example.com",
+ "payment_method_id": "pm_example",
"provider": "link",
- "wallet": "wallet",
+ "wallet": "link-wallet",
},
)