diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index aebbc8bc..f70d9978 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.101.0"
+ ".": "0.102.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 77497eb7..80c45f21 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog
+## [0.102.0](https://github.com/kernel/kernel-python-sdk/compare/v0.101.0...v0.102.0) (2026-09-14)
+
+
+### Features
+
+* Accept a workload intent and use it to widen vendor coverage ([39ffff8](https://github.com/kernel/kernel-python-sdk/commit/39ffff82be3987e2220d8d5057d8d2505991a3eb))
+* Add guarded vault card fill operations ([3927c96](https://github.com/kernel/kernel-python-sdk/commit/3927c961789b4427a72c979ee5bb3dbcae1b8c74))
+* Add single-use AgentCard prepare_checkout for Square ([c439359](https://github.com/kernel/kernel-python-sdk/commit/c43935913b8a471421ef8d96c9066c442ec95171))
+* Allow replacing AgentCard cards after unknown creates ([22a8731](https://github.com/kernel/kernel-python-sdk/commit/22a87318e6ac2f1318a295b9d22de5b2306e66b2))
+* Document punctuation key sequences ([e7850fd](https://github.com/kernel/kernel-python-sdk/commit/e7850fd5757934c731373c5cb09b4444a29d7e84))
+* Honor managed auth browser regions ([0fa2fa3](https://github.com/kernel/kernel-python-sdk/commit/0fa2fa34cd72d04a12c6f9afd61d87098d43799b))
+* Reapply vendor guidance recommendations ([dfcc7ec](https://github.com/kernel/kernel-python-sdk/commit/dfcc7ecbaa087a07d11a5b0eb4738b41b8fadd8b))
+* Report proxy-restricted targets from config registry lookup ([c276ebc](https://github.com/kernel/kernel-python-sdk/commit/c276ebc6fd266924894b300b13ff02f30d0c8527))
+
## [0.101.0](https://github.com/kernel/kernel-python-sdk/compare/v0.100.0...v0.101.0) (2026-09-11)
diff --git a/api.md b/api.md
index 63957ab1..1c9b02a3 100644
--- a/api.md
+++ b/api.md
@@ -525,12 +525,21 @@ Types:
```python
from kernel.types.vaults import (
AgentcardCheckoutAuthorization,
+ AgentcardCheckoutPreparation,
+ AuthorizeVaultItemOperationRequest,
CardVaultItemSpec,
CardVaultItemState,
+ FillVaultItemOperationRequest,
+ FillVaultItemOperationResult,
+ PrepareCheckoutVaultItemOperationRequest,
VaultCardAliases,
+ VaultCardFillField,
+ VaultCheckoutContext,
+ VaultFillFieldResult,
VaultItem,
VaultItemAction,
VaultItemEvent,
+ VaultItemOperationResponse,
VaultPaymentMethod,
WalletVaultItemSpec,
WalletVaultItemState,
@@ -546,7 +555,7 @@ Methods:
- client.vaults.items.list(id_or_name) -> ItemListResponse
- client.vaults.items.delete(key, \*, id_or_name) -> None
- client.vaults.items.events(key, \*, id_or_name, \*\*params) -> ItemEventsResponse
-- client.vaults.items.perform_operation(key, \*, id_or_name, \*\*params) -> VaultItem
+- client.vaults.items.perform_operation(key, \*, id_or_name, \*\*params) -> VaultItemOperationResponse
- client.vaults.items.upsert(key, \*, id_or_name, \*\*params) -> VaultItem
# Credentials
diff --git a/pyproject.toml b/pyproject.toml
index ce24d358..473c0ec0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "kernel"
-version = "0.101.0"
+version = "0.102.0"
description = "The official Python library for the kernel API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/kernel/_version.py b/src/kernel/_version.py
index 058933d0..b5daff26 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.101.0" # x-release-please-version
+__version__ = "0.102.0" # x-release-please-version
diff --git a/src/kernel/resources/browsers/computer.py b/src/kernel/resources/browsers/computer.py
index dcb242c6..b40ac897 100644
--- a/src/kernel/resources/browsers/computer.py
+++ b/src/kernel/resources/browsers/computer.py
@@ -397,7 +397,9 @@ def press_key(
keys: List of key symbols to press. Each item should be a key symbol supported by
xdotool (see X11 keysym definitions). Examples include "Return", "Shift",
"Ctrl", "Alt", "F5". Items in this list could also be combinations, e.g.
- "Ctrl+t" or "Ctrl+Shift+Tab".
+ "Ctrl+t" or "Ctrl+Shift+Tab". Use X11 names for punctuation in combinations,
+ such as "Ctrl+minus" or "Ctrl+plus". A literal hyphen is also accepted as an
+ alias, so "Ctrl+-" is normalized to "Ctrl+minus".
duration: Duration to hold the keys down in milliseconds. If omitted or 0, keys are
tapped.
@@ -1002,7 +1004,9 @@ async def press_key(
keys: List of key symbols to press. Each item should be a key symbol supported by
xdotool (see X11 keysym definitions). Examples include "Return", "Shift",
"Ctrl", "Alt", "F5". Items in this list could also be combinations, e.g.
- "Ctrl+t" or "Ctrl+Shift+Tab".
+ "Ctrl+t" or "Ctrl+Shift+Tab". Use X11 names for punctuation in combinations,
+ such as "Ctrl+minus" or "Ctrl+plus". A literal hyphen is also accepted as an
+ alias, so "Ctrl+-" is normalized to "Ctrl+minus".
duration: Duration to hold the keys down in milliseconds. If omitted or 0, keys are
tapped.
diff --git a/src/kernel/resources/config_registry/config_registry.py b/src/kernel/resources/config_registry/config_registry.py
index 0b9d1824..27a8766c 100644
--- a/src/kernel/resources/config_registry/config_registry.py
+++ b/src/kernel/resources/config_registry/config_registry.py
@@ -165,6 +165,7 @@ def resolve(
*,
url: str,
allowed_proxy_countries: SequenceNotStr[str] | Omit = omit,
+ intent: 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,
@@ -184,6 +185,14 @@ def resolve(
configuration. Kernel may test a subset of allowed countries. When omitted,
Kernel uses its default country selection.
+ intent: Plain-language description of the workload you intend to run against this
+ target, in a sentence or two. Requires an https target, because the pass treats
+ any non-HTTPS destination as off-site and will not drive an http one. Kernel
+ uses it to drive the browser further into the site, where it can observe
+ protections that only appear once a session interacts. When this target already
+ has a verified configuration, the run confirms that one instead of re-deriving
+ the whole matrix, so supplying an intent narrows what can be recommended.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -198,6 +207,7 @@ def resolve(
{
"url": url,
"allowed_proxy_countries": allowed_proxy_countries,
+ "intent": intent,
},
config_registry_resolve_params.ConfigRegistryResolveParams,
),
@@ -339,6 +349,7 @@ async def resolve(
*,
url: str,
allowed_proxy_countries: SequenceNotStr[str] | Omit = omit,
+ intent: 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,
@@ -358,6 +369,14 @@ async def resolve(
configuration. Kernel may test a subset of allowed countries. When omitted,
Kernel uses its default country selection.
+ intent: Plain-language description of the workload you intend to run against this
+ target, in a sentence or two. Requires an https target, because the pass treats
+ any non-HTTPS destination as off-site and will not drive an http one. Kernel
+ uses it to drive the browser further into the site, where it can observe
+ protections that only appear once a session interacts. When this target already
+ has a verified configuration, the run confirms that one instead of re-deriving
+ the whole matrix, so supplying an intent narrows what can be recommended.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -372,6 +391,7 @@ async def resolve(
{
"url": url,
"allowed_proxy_countries": allowed_proxy_countries,
+ "intent": intent,
},
config_registry_resolve_params.ConfigRegistryResolveParams,
),
diff --git a/src/kernel/resources/vaults/items.py b/src/kernel/resources/vaults/items.py
index dd790910..02315e2b 100644
--- a/src/kernel/resources/vaults/items.py
+++ b/src/kernel/resources/vaults/items.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Any, List, cast
+from typing import Any, List, Iterable, cast
from typing_extensions import Literal, overload
import httpx
@@ -29,6 +29,9 @@
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.vault_card_fill_field_param import VaultCardFillFieldParam
+from ...types.vaults.vault_checkout_context_param import VaultCheckoutContextParam
+from ...types.vaults.vault_item_operation_response import VaultItemOperationResponse
__all__ = ["ItemsResource", "AsyncItemsResource"]
@@ -209,9 +212,11 @@ def delete(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
- 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.
+ Unresolved payment operations normally block deletion, including operations on
+ child cards of a wallet. An AgentCard card in recovery_required whose checkout
+ create response returned no authorization ID may be explicitly abandoned by
+ deleting that card directly; deleting its wallet or vault remains blocked.
+ Deleting or recreating an item is not proof that a payment did not occur.
Args:
extra_headers: Send extra headers
@@ -287,6 +292,7 @@ def events(
cast_to=ItemEventsResponse,
)
+ @overload
def perform_operation(
self,
key: str,
@@ -299,17 +305,80 @@ def perform_operation(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> VaultItem:
+ ) -> VaultItemOperationResponse:
+ """
+ Retrieve the item first and invoke only an operation listed in
+ `available_operations`, following its natural-language description. Availability
+ is rechecked at execution time; unavailable operations return 409. Authorization
+ and preparation may call an external provider and return updated state. Link
+ cards advertise authorize without checkout context. Eligible unused AgentCard
+ cards advertise prepare_checkout, which requires checkout context and obtains
+ device approval before native Square Pay. Keep the returned approval page open,
+ poll until ready_to_submit, then submit before preparation.expires_at. Unused
+ preparations expire automatically and cannot be reused. If spend-request
+ creation is rate limited, returns HTTP 429 with code
+ `spend_request_rate_limited`; stop and back off before retrying.
+
+ Fill returns a value-free execution result. Validation failures before writing
+ return 400 (invalid request or targets), 403 (access or destination denied), 404
+ (resource not found), or 409 (item or browser not ready). Once writing starts,
+ known partial failures and indeterminate field outcomes return 200 with status
+ `failed` or `unknown`, not an automatic-retry signal. A transport error may
+ leave the outcome unknown; do not automatically retry.
+
+ 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
+ """
+ ...
+
+ @overload
+ def perform_operation(
+ self,
+ key: str,
+ *,
+ id_or_name: str,
+ checkout: VaultCheckoutContextParam,
+ type: Literal["prepare_checkout"],
+ # 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,
+ ) -> VaultItemOperationResponse:
"""
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 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
+ `available_operations`, following its natural-language description. Availability
+ is rechecked at execution time; unavailable operations return 409. Authorization
+ and preparation may call an external provider and return updated state. Link
+ cards advertise authorize without checkout context. Eligible unused AgentCard
+ cards advertise prepare_checkout, which requires checkout context and obtains
+ device approval before native Square Pay. Keep the returned approval page open,
+ poll until ready_to_submit, then submit before preparation.expires_at. Unused
+ preparations expire automatically and cannot be reused. If spend-request
+ creation is rate limited, returns HTTP 429 with code
`spend_request_rate_limited`; stop and back off before retrying.
+ Fill returns a value-free execution result. Validation failures before writing
+ return 400 (invalid request or targets), 403 (access or destination denied), 404
+ (resource not found), or 409 (item or browser not ready). Once writing starts,
+ known partial failures and indeterminate field outcomes return 200 with status
+ `failed` or `unknown`, not an automatic-retry signal. A transport error may
+ leave the outcome unknown; do not automatically retry.
+
Args:
+ checkout: Required when preparing an unused AgentCard card for Square. Consent is bound to
+ this browser and declared merchant origin, not a tab. Wait for the item's
+ ready_to_submit status before native Pay and submit within its readiness
+ deadline. Unused preparations expire automatically; every preparation is
+ single-use, including after failure or expiry.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -318,19 +387,115 @@ def perform_operation(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ ...
+
+ @overload
+ def perform_operation(
+ self,
+ key: str,
+ *,
+ id_or_name: str,
+ browser_id: str,
+ fields: Iterable[VaultCardFillFieldParam],
+ page_url: str,
+ type: Literal["fill"],
+ timeout_ms: 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,
+ ) -> VaultItemOperationResponse:
+ """
+ Retrieve the item first and invoke only an operation listed in
+ `available_operations`, following its natural-language description. Availability
+ is rechecked at execution time; unavailable operations return 409. Authorization
+ and preparation may call an external provider and return updated state. Link
+ cards advertise authorize without checkout context. Eligible unused AgentCard
+ cards advertise prepare_checkout, which requires checkout context and obtains
+ device approval before native Square Pay. Keep the returned approval page open,
+ poll until ready_to_submit, then submit before preparation.expires_at. Unused
+ preparations expire automatically and cannot be reused. If spend-request
+ creation is rate limited, returns HTTP 429 with code
+ `spend_request_rate_limited`; stop and back off before retrying.
+
+ Fill returns a value-free execution result. Validation failures before writing
+ return 400 (invalid request or targets), 403 (access or destination denied), 404
+ (resource not found), or 409 (item or browser not ready). Once writing starts,
+ known partial failures and indeterminate field outcomes return 200 with status
+ `failed` or `unknown`, not an automatic-retry signal. A transport error may
+ leave the outcome unknown; do not automatically retry.
+
+ Args:
+ browser_id: Browser session ID, not a reusable browser name.
+
+ fields: Field bindings for this step. No two bindings may resolve to the same element.
+
+ page_url: Exact current top-level page URL, including path, query, and fragment. Must
+ match exactly one open page in the browser; zero or multiple matches fail. No
+ prefix or glob matching. Must use HTTPS without embedded credentials.
+
+ timeout_ms: Total operation deadline in milliseconds, not a per-field timeout.
+
+ 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(
+ ["id_or_name", "type"],
+ ["id_or_name", "checkout", "type"],
+ ["id_or_name", "browser_id", "fields", "page_url", "type"],
+ )
+ def perform_operation(
+ self,
+ key: str,
+ *,
+ id_or_name: str,
+ type: Literal["authorize"] | Literal["prepare_checkout"] | Literal["fill"],
+ checkout: VaultCheckoutContextParam | Omit = omit,
+ browser_id: str | Omit = omit,
+ fields: Iterable[VaultCardFillFieldParam] | Omit = omit,
+ page_url: str | Omit = omit,
+ timeout_ms: 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,
+ ) -> VaultItemOperationResponse:
if not id_or_name:
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
if not key:
raise ValueError(f"Expected a non-empty value for `key` but received {key!r}")
return cast(
- VaultItem,
+ VaultItemOperationResponse,
self._post(
path_template("/vaults/{id_or_name}/items/{key}/operations", id_or_name=id_or_name, key=key),
- body=maybe_transform({"type": type}, item_perform_operation_params.ItemPerformOperationParams),
+ body=maybe_transform(
+ {
+ "type": type,
+ "checkout": checkout,
+ "browser_id": browser_id,
+ "fields": fields,
+ "page_url": page_url,
+ "timeout_ms": timeout_ms,
+ },
+ item_perform_operation_params.ItemPerformOperationParams,
+ ),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=cast(Any, VaultItem), # Union types cannot be passed in as arguments in the type system
+ cast_to=cast(
+ Any, VaultItemOperationResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
)
@@ -625,9 +790,11 @@ async def delete(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
- 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.
+ Unresolved payment operations normally block deletion, including operations on
+ child cards of a wallet. An AgentCard card in recovery_required whose checkout
+ create response returned no authorization ID may be explicitly abandoned by
+ deleting that card directly; deleting its wallet or vault remains blocked.
+ Deleting or recreating an item is not proof that a payment did not occur.
Args:
extra_headers: Send extra headers
@@ -703,6 +870,7 @@ async def events(
cast_to=ItemEventsResponse,
)
+ @overload
async def perform_operation(
self,
key: str,
@@ -715,17 +883,80 @@ async def perform_operation(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> VaultItem:
+ ) -> VaultItemOperationResponse:
+ """
+ Retrieve the item first and invoke only an operation listed in
+ `available_operations`, following its natural-language description. Availability
+ is rechecked at execution time; unavailable operations return 409. Authorization
+ and preparation may call an external provider and return updated state. Link
+ cards advertise authorize without checkout context. Eligible unused AgentCard
+ cards advertise prepare_checkout, which requires checkout context and obtains
+ device approval before native Square Pay. Keep the returned approval page open,
+ poll until ready_to_submit, then submit before preparation.expires_at. Unused
+ preparations expire automatically and cannot be reused. If spend-request
+ creation is rate limited, returns HTTP 429 with code
+ `spend_request_rate_limited`; stop and back off before retrying.
+
+ Fill returns a value-free execution result. Validation failures before writing
+ return 400 (invalid request or targets), 403 (access or destination denied), 404
+ (resource not found), or 409 (item or browser not ready). Once writing starts,
+ known partial failures and indeterminate field outcomes return 200 with status
+ `failed` or `unknown`, not an automatic-retry signal. A transport error may
+ leave the outcome unknown; do not automatically retry.
+
+ 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
+ """
+ ...
+
+ @overload
+ async def perform_operation(
+ self,
+ key: str,
+ *,
+ id_or_name: str,
+ checkout: VaultCheckoutContextParam,
+ type: Literal["prepare_checkout"],
+ # 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,
+ ) -> VaultItemOperationResponse:
"""
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 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
+ `available_operations`, following its natural-language description. Availability
+ is rechecked at execution time; unavailable operations return 409. Authorization
+ and preparation may call an external provider and return updated state. Link
+ cards advertise authorize without checkout context. Eligible unused AgentCard
+ cards advertise prepare_checkout, which requires checkout context and obtains
+ device approval before native Square Pay. Keep the returned approval page open,
+ poll until ready_to_submit, then submit before preparation.expires_at. Unused
+ preparations expire automatically and cannot be reused. If spend-request
+ creation is rate limited, returns HTTP 429 with code
`spend_request_rate_limited`; stop and back off before retrying.
+ Fill returns a value-free execution result. Validation failures before writing
+ return 400 (invalid request or targets), 403 (access or destination denied), 404
+ (resource not found), or 409 (item or browser not ready). Once writing starts,
+ known partial failures and indeterminate field outcomes return 200 with status
+ `failed` or `unknown`, not an automatic-retry signal. A transport error may
+ leave the outcome unknown; do not automatically retry.
+
Args:
+ checkout: Required when preparing an unused AgentCard card for Square. Consent is bound to
+ this browser and declared merchant origin, not a tab. Wait for the item's
+ ready_to_submit status before native Pay and submit within its readiness
+ deadline. Unused preparations expire automatically; every preparation is
+ single-use, including after failure or expiry.
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -734,21 +965,115 @@ async def perform_operation(
timeout: Override the client-level default timeout for this request, in seconds
"""
+ ...
+
+ @overload
+ async def perform_operation(
+ self,
+ key: str,
+ *,
+ id_or_name: str,
+ browser_id: str,
+ fields: Iterable[VaultCardFillFieldParam],
+ page_url: str,
+ type: Literal["fill"],
+ timeout_ms: 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,
+ ) -> VaultItemOperationResponse:
+ """
+ Retrieve the item first and invoke only an operation listed in
+ `available_operations`, following its natural-language description. Availability
+ is rechecked at execution time; unavailable operations return 409. Authorization
+ and preparation may call an external provider and return updated state. Link
+ cards advertise authorize without checkout context. Eligible unused AgentCard
+ cards advertise prepare_checkout, which requires checkout context and obtains
+ device approval before native Square Pay. Keep the returned approval page open,
+ poll until ready_to_submit, then submit before preparation.expires_at. Unused
+ preparations expire automatically and cannot be reused. If spend-request
+ creation is rate limited, returns HTTP 429 with code
+ `spend_request_rate_limited`; stop and back off before retrying.
+
+ Fill returns a value-free execution result. Validation failures before writing
+ return 400 (invalid request or targets), 403 (access or destination denied), 404
+ (resource not found), or 409 (item or browser not ready). Once writing starts,
+ known partial failures and indeterminate field outcomes return 200 with status
+ `failed` or `unknown`, not an automatic-retry signal. A transport error may
+ leave the outcome unknown; do not automatically retry.
+
+ Args:
+ browser_id: Browser session ID, not a reusable browser name.
+
+ fields: Field bindings for this step. No two bindings may resolve to the same element.
+
+ page_url: Exact current top-level page URL, including path, query, and fragment. Must
+ match exactly one open page in the browser; zero or multiple matches fail. No
+ prefix or glob matching. Must use HTTPS without embedded credentials.
+
+ timeout_ms: Total operation deadline in milliseconds, not a per-field timeout.
+
+ 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(
+ ["id_or_name", "type"],
+ ["id_or_name", "checkout", "type"],
+ ["id_or_name", "browser_id", "fields", "page_url", "type"],
+ )
+ async def perform_operation(
+ self,
+ key: str,
+ *,
+ id_or_name: str,
+ type: Literal["authorize"] | Literal["prepare_checkout"] | Literal["fill"],
+ checkout: VaultCheckoutContextParam | Omit = omit,
+ browser_id: str | Omit = omit,
+ fields: Iterable[VaultCardFillFieldParam] | Omit = omit,
+ page_url: str | Omit = omit,
+ timeout_ms: 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,
+ ) -> VaultItemOperationResponse:
if not id_or_name:
raise ValueError(f"Expected a non-empty value for `id_or_name` but received {id_or_name!r}")
if not key:
raise ValueError(f"Expected a non-empty value for `key` but received {key!r}")
return cast(
- VaultItem,
+ VaultItemOperationResponse,
await self._post(
path_template("/vaults/{id_or_name}/items/{key}/operations", id_or_name=id_or_name, key=key),
body=await async_maybe_transform(
- {"type": type}, item_perform_operation_params.ItemPerformOperationParams
+ {
+ "type": type,
+ "checkout": checkout,
+ "browser_id": browser_id,
+ "fields": fields,
+ "page_url": page_url,
+ "timeout_ms": timeout_ms,
+ },
+ item_perform_operation_params.ItemPerformOperationParams,
),
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=cast(Any, VaultItem), # Union types cannot be passed in as arguments in the type system
+ cast_to=cast(
+ Any, VaultItemOperationResponse
+ ), # Union types cannot be passed in as arguments in the type system
),
)
diff --git a/src/kernel/types/auth/managed_auth_browser_config.py b/src/kernel/types/auth/managed_auth_browser_config.py
index c7e565d1..3309904e 100644
--- a/src/kernel/types/auth/managed_auth_browser_config.py
+++ b/src/kernel/types/auth/managed_auth_browser_config.py
@@ -1,6 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from typing_extensions import Literal
from ..._models import BaseModel
from ..browser_proxy_config import BrowserProxyConfig
@@ -108,6 +109,14 @@ class ManagedAuthBrowserConfig(BaseModel):
preserve or inherit the connection default.
"""
+ region: Optional[Literal["us-east", "eu-west", "ap-southeast"]] = None
+ """Browser region.
+
+ Omit on create to use us-east, on update to keep the current region, or on login
+ to inherit it. Login overrides apply only to that login. Non-default regions
+ require an eligible plan and organization access.
+ """
+
stealth: Optional[bool] = None
"""Whether managed auth browser sessions use stealth mode.
diff --git a/src/kernel/types/auth/managed_auth_browser_config_param.py b/src/kernel/types/auth/managed_auth_browser_config_param.py
index bfd09f95..6f8eab6d 100644
--- a/src/kernel/types/auth/managed_auth_browser_config_param.py
+++ b/src/kernel/types/auth/managed_auth_browser_config_param.py
@@ -3,7 +3,7 @@
from __future__ import annotations
from typing import Optional
-from typing_extensions import TypedDict
+from typing_extensions import Literal, TypedDict
from ..browser_proxy_config_param import BrowserProxyConfigParam
from ..browsers.browser_telemetry_categories_config_param import BrowserTelemetryCategoriesConfigParam
@@ -110,6 +110,14 @@ class ManagedAuthBrowserConfigParam(TypedDict, total=False):
preserve or inherit the connection default.
"""
+ region: Literal["us-east", "eu-west", "ap-southeast"]
+ """Browser region.
+
+ Omit on create to use us-east, on update to keep the current region, or on login
+ to inherit it. Login overrides apply only to that login. Non-default regions
+ require an eligible plan and organization access.
+ """
+
stealth: bool
"""Whether managed auth browser sessions use stealth mode.
diff --git a/src/kernel/types/browsers/computer_batch_params.py b/src/kernel/types/browsers/computer_batch_params.py
index 7fc6abb5..dbd91756 100644
--- a/src/kernel/types/browsers/computer_batch_params.py
+++ b/src/kernel/types/browsers/computer_batch_params.py
@@ -110,7 +110,10 @@ class ActionPressKey(TypedDict, total=False):
Each item should be a key symbol supported by xdotool (see X11 keysym
definitions). Examples include "Return", "Shift", "Ctrl", "Alt", "F5". Items in
- this list could also be combinations, e.g. "Ctrl+t" or "Ctrl+Shift+Tab".
+ this list could also be combinations, e.g. "Ctrl+t" or "Ctrl+Shift+Tab". Use X11
+ names for punctuation in combinations, such as "Ctrl+minus" or "Ctrl+plus". A
+ literal hyphen is also accepted as an alias, so "Ctrl+-" is normalized to
+ "Ctrl+minus".
"""
duration: int
diff --git a/src/kernel/types/browsers/computer_press_key_params.py b/src/kernel/types/browsers/computer_press_key_params.py
index ea2c9b45..8722e1b3 100644
--- a/src/kernel/types/browsers/computer_press_key_params.py
+++ b/src/kernel/types/browsers/computer_press_key_params.py
@@ -15,7 +15,10 @@ class ComputerPressKeyParams(TypedDict, total=False):
Each item should be a key symbol supported by xdotool (see X11 keysym
definitions). Examples include "Return", "Shift", "Ctrl", "Alt", "F5". Items in
- this list could also be combinations, e.g. "Ctrl+t" or "Ctrl+Shift+Tab".
+ this list could also be combinations, e.g. "Ctrl+t" or "Ctrl+Shift+Tab". Use X11
+ names for punctuation in combinations, such as "Ctrl+minus" or "Ctrl+plus". A
+ literal hyphen is also accepted as an alias, so "Ctrl+-" is normalized to
+ "Ctrl+minus".
"""
duration: int
diff --git a/src/kernel/types/config_registry_resolve_params.py b/src/kernel/types/config_registry_resolve_params.py
index 644c4b7a..2c0ecc00 100644
--- a/src/kernel/types/config_registry_resolve_params.py
+++ b/src/kernel/types/config_registry_resolve_params.py
@@ -19,3 +19,14 @@ class ConfigRegistryResolveParams(TypedDict, total=False):
configuration. Kernel may test a subset of allowed countries. When omitted,
Kernel uses its default country selection.
"""
+
+ intent: str
+ """
+ Plain-language description of the workload you intend to run against this
+ target, in a sentence or two. Requires an https target, because the pass treats
+ any non-HTTPS destination as off-site and will not drive an http one. Kernel
+ uses it to drive the browser further into the site, where it can observe
+ protections that only appear once a session interacts. When this target already
+ has a verified configuration, the run confirms that one instead of re-deriving
+ the whole matrix, so supplying an intent narrows what can be recommended.
+ """
diff --git a/src/kernel/types/config_registry_response.py b/src/kernel/types/config_registry_response.py
index 9995173f..dba10b9e 100644
--- a/src/kernel/types/config_registry_response.py
+++ b/src/kernel/types/config_registry_response.py
@@ -1,6 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from typing_extensions import Literal
from .target import Target
from .._models import BaseModel
@@ -21,3 +22,20 @@ class ConfigRegistryResponse(BaseModel):
"""A recommendation or a structured no-recommendation result."""
target: Target
+
+ guidance: Optional[str] = None
+ """Short advisory markdown to facilitate navigating this target.
+
+ Returned even when no configuration reached the target, since knowing what
+ prevented success is useful without a configuration. Not verified against this
+ target. Null when nothing applicable was observed or no notes exist.
+ """
+
+ workload_outcome: Optional[
+ Literal["completed", "turn_limit", "auth_required", "payment_required", "blocked", "error"]
+ ] = None
+ """How far the workload pass got, when an intent was supplied and a pass ran.
+
+ A run outcome rather than advice, so it is reported whether or not any guidance
+ could be assembled. Null when no intent was supplied or no pass ran.
+ """
diff --git a/src/kernel/types/lookup_response.py b/src/kernel/types/lookup_response.py
index cf0f5c16..d717b8cf 100644
--- a/src/kernel/types/lookup_response.py
+++ b/src/kernel/types/lookup_response.py
@@ -4,12 +4,21 @@
from .target import Target
from .._models import BaseModel
-from .recommendation import Recommendation
+from .recommendation_result import RecommendationResult
__all__ = ["LookupResponse"]
class LookupResponse(BaseModel):
- recommendation: Optional[Recommendation] = None
+ recommendation: Optional[RecommendationResult] = None
+ """A recommendation or a structured no-recommendation result."""
target: Target
+
+ guidance: Optional[str] = None
+ """Short advisory markdown to facilitate navigating this target.
+
+ Returned even when no configuration reached the target, since knowing what
+ prevented success is useful without a configuration. Not verified against this
+ target. Null when nothing applicable was observed or no notes exist.
+ """
diff --git a/src/kernel/types/vaults/__init__.py b/src/kernel/types/vaults/__init__.py
index 623e45d4..b48fd00d 100644
--- a/src/kernel/types/vaults/__init__.py
+++ b/src/kernel/types/vaults/__init__.py
@@ -16,7 +16,22 @@
from .vault_payment_method import VaultPaymentMethod as VaultPaymentMethod
from .card_vault_item_state import CardVaultItemState as CardVaultItemState
from .wallet_vault_item_spec import WalletVaultItemSpec as WalletVaultItemSpec
+from .vault_fill_field_result import VaultFillFieldResult as VaultFillFieldResult
from .wallet_vault_item_state import WalletVaultItemState as WalletVaultItemState
from .card_vault_item_spec_param import CardVaultItemSpecParam as CardVaultItemSpecParam
+from .vault_card_fill_field_param import VaultCardFillFieldParam as VaultCardFillFieldParam
+from .vault_checkout_context_param import VaultCheckoutContextParam as VaultCheckoutContextParam
from .item_perform_operation_params import ItemPerformOperationParams as ItemPerformOperationParams
+from .vault_item_operation_response import VaultItemOperationResponse as VaultItemOperationResponse
+from .agentcard_checkout_preparation import AgentcardCheckoutPreparation as AgentcardCheckoutPreparation
from .agentcard_checkout_authorization import AgentcardCheckoutAuthorization as AgentcardCheckoutAuthorization
+from .fill_vault_item_operation_result import FillVaultItemOperationResult as FillVaultItemOperationResult
+from .fill_vault_item_operation_request_param import (
+ FillVaultItemOperationRequestParam as FillVaultItemOperationRequestParam,
+)
+from .authorize_vault_item_operation_request_param import (
+ AuthorizeVaultItemOperationRequestParam as AuthorizeVaultItemOperationRequestParam,
+)
+from .prepare_checkout_vault_item_operation_request_param import (
+ PrepareCheckoutVaultItemOperationRequestParam as PrepareCheckoutVaultItemOperationRequestParam,
+)
diff --git a/src/kernel/types/vaults/agentcard_checkout_preparation.py b/src/kernel/types/vaults/agentcard_checkout_preparation.py
new file mode 100644
index 00000000..8296b2fd
--- /dev/null
+++ b/src/kernel/types/vaults/agentcard_checkout_preparation.py
@@ -0,0 +1,43 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["AgentcardCheckoutPreparation"]
+
+
+class AgentcardCheckoutPreparation(BaseModel):
+ """One-use Square checkout preparation.
+
+ Keep the approval page open through token handoff. The amount is display-only and does not constrain the merchant's eventual charge.
+ """
+
+ browser_id: str
+
+ created_at: datetime
+
+ environment: Literal["production", "sandbox"]
+
+ merchant_origin: str
+
+ status: Literal["creating", "awaiting_approval", "ready", "consumed", "cancelled", "expired", "unknown"]
+ """
+ Preparation consumed means egress claimed the preparation and it cannot be
+ reused. It does not mean the attempt settled. Use the enclosing item's status as
+ the lifecycle indicator; item consumed means the attempt settled, not that an
+ order or charge succeeded.
+ """
+
+ id: Optional[str] = None
+
+ approval_url: Optional[str] = None
+
+ expires_at: Optional[datetime] = None
+ """
+ When ready, the absolute deadline to submit the first native request; no later
+ than provider readiness expiry or 30 seconds after Kernel first observes
+ readiness. Polling never extends this deadline.
+ """
diff --git a/src/kernel/types/vaults/authorize_vault_item_operation_request_param.py b/src/kernel/types/vaults/authorize_vault_item_operation_request_param.py
new file mode 100644
index 00000000..10ba11bc
--- /dev/null
+++ b/src/kernel/types/vaults/authorize_vault_item_operation_request_param.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["AuthorizeVaultItemOperationRequestParam"]
+
+
+class AuthorizeVaultItemOperationRequestParam(TypedDict, total=False):
+ """Authorize a Link card using its existing purchase specification.
+
+ Use only after explicit user approval and when the item advertises authorize. Do not automatically retry provider failures or indeterminate outcomes. Checkout context is not accepted.
+ """
+
+ type: Required[Literal["authorize"]]
diff --git a/src/kernel/types/vaults/card_vault_item_state.py b/src/kernel/types/vaults/card_vault_item_state.py
index 7bb7e274..98459762 100644
--- a/src/kernel/types/vaults/card_vault_item_state.py
+++ b/src/kernel/types/vaults/card_vault_item_state.py
@@ -8,6 +8,7 @@
from ..._utils import PropertyInfo
from ..._models import BaseModel
from .vault_card_aliases import VaultCardAliases
+from .agentcard_checkout_preparation import AgentcardCheckoutPreparation
from .agentcard_checkout_authorization import AgentcardCheckoutAuthorization
__all__ = ["CardVaultItemState", "LinkCardState", "LinkCardStateMasks", "AgentCardCardState", "AgentCardCardStateMasks"]
@@ -76,12 +77,28 @@ def __getattr__(self, attr: str) -> str: ...
class AgentCardCardState(BaseModel):
provider: Literal["agentcard"]
- 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.
+ status: Literal[
+ "requested",
+ "ready",
+ "preparing",
+ "ready_to_submit",
+ "pending_approval",
+ "consumed",
+ "stopped",
+ "outcome_unknown",
+ "degraded",
+ "recovery_required",
+ ]
+ """ready_to_submit is device readiness for at most 30 seconds.
+
+ consumed means the prepared attempt has settled, not that an order succeeded.
+ stopped cannot be reused. outcome_unknown requires merchant reconciliation and
+ blocks new requests. recovery_required means the original checkout outcome is
+ unresolved. Automatic reuse is blocked. Known authorization IDs must be
+ reconciled through provider observations or support. When no authorization ID
+ was returned, an explicitly confirmed item deletion may abandon the unresolved
+ attempt so the caller can create a replacement; deletion does not prove that the
+ original attempt failed. It does not mean declined or expired.
"""
aliases: Optional[VaultCardAliases] = None
@@ -94,6 +111,13 @@ class AgentCardCardState(BaseModel):
masks: Optional[AgentCardCardStateMasks] = None
+ preparation: Optional[AgentcardCheckoutPreparation] = None
+ """One-use Square checkout preparation.
+
+ Keep the approval page open through token handoff. The amount is display-only
+ and does not constrain the merchant's eventual charge.
+ """
+
status_reason: Optional[str] = None
diff --git a/src/kernel/types/vaults/fill_vault_item_operation_request_param.py b/src/kernel/types/vaults/fill_vault_item_operation_request_param.py
new file mode 100644
index 00000000..a4613cd6
--- /dev/null
+++ b/src/kernel/types/vaults/fill_vault_item_operation_request_param.py
@@ -0,0 +1,61 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Literal, Required, TypedDict
+
+from .vault_card_fill_field_param import VaultCardFillFieldParam
+
+__all__ = ["FillVaultItemOperationRequestParam"]
+
+
+class FillVaultItemOperationRequestParam(TypedDict, total=False):
+ """
+ Fill selected fields from one ready, unexpired card into a browser linked
+ to its vault. Only supported for card items created from Link wallets.
+ Only invoke when the item advertises `fill`. Browser and vault must belong
+ to the same project. Kernel checks access and allowed destinations before
+ filling; providing a page URL does not authorize a destination.
+
+ Find exactly one open page matching `page_url`. For each selector, search
+ the main frame and all descendant frames for editable inputs or selects
+ matched directly or contained within matching elements. Each selector must
+ resolve to one unique editable element across all frames; zero or multiple
+ candidates fail. Count each element once, even if multiple matching
+ containers contain it. Validate all bindings before filling.
+ Select elements match an option by its value, not its label.
+ If the page navigates or a target disappears during filling, stop rather
+ than selecting a different page or element.
+
+ Fill in request order and stop on the first failure. This operation is
+ not atomic: previously filled fields are not rolled back. Never submit
+ the form or click buttons, though input/change events may trigger site
+ behavior. Fill is the preferred browser-checkout path. Aliases remain an
+ alternative for explicitly chosen egress-substitution integrations. Do not
+ automatically retry or fall back to aliases after a failed or indeterminate
+ operation.
+
+ Secret values are never returned or included in operation logs, traces,
+ audit events, or error details. This does not prevent an agent with
+ unrestricted browser access from reading values from the page or other
+ browser observation surfaces.
+ """
+
+ browser_id: Required[str]
+ """Browser session ID, not a reusable browser name."""
+
+ fields: Required[Iterable[VaultCardFillFieldParam]]
+ """Field bindings for this step. No two bindings may resolve to the same element."""
+
+ page_url: Required[str]
+ """Exact current top-level page URL, including path, query, and fragment.
+
+ Must match exactly one open page in the browser; zero or multiple matches fail.
+ No prefix or glob matching. Must use HTTPS without embedded credentials.
+ """
+
+ type: Required[Literal["fill"]]
+
+ timeout_ms: int
+ """Total operation deadline in milliseconds, not a per-field timeout."""
diff --git a/src/kernel/types/vaults/fill_vault_item_operation_result.py b/src/kernel/types/vaults/fill_vault_item_operation_result.py
new file mode 100644
index 00000000..0f3f1855
--- /dev/null
+++ b/src/kernel/types/vaults/fill_vault_item_operation_result.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+from .vault_fill_field_result import VaultFillFieldResult
+
+__all__ = ["FillVaultItemOperationResult"]
+
+
+class FillVaultItemOperationResult(BaseModel):
+ fields: List[VaultFillFieldResult]
+ """Exactly one result per request binding, in request order.
+
+ After the first failed or unknown field, all remaining fields are not_attempted.
+ """
+
+ status: Literal["completed", "failed", "unknown"]
+ """Completed only when all fields were filled.
+
+ Failed when execution stopped with known outcomes. Unknown when any field's
+ outcome cannot be determined. None of these statuses confirms payment or
+ merchant acceptance.
+ """
+
+ type: Literal["fill"]
diff --git a/src/kernel/types/vaults/item_perform_operation_params.py b/src/kernel/types/vaults/item_perform_operation_params.py
index 9d62f380..c583f53b 100644
--- a/src/kernel/types/vaults/item_perform_operation_params.py
+++ b/src/kernel/types/vaults/item_perform_operation_params.py
@@ -2,12 +2,63 @@
from __future__ import annotations
-from typing_extensions import Literal, Required, TypedDict
+from typing import Union, Iterable
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
-__all__ = ["ItemPerformOperationParams"]
+from .vault_card_fill_field_param import VaultCardFillFieldParam
+from .vault_checkout_context_param import VaultCheckoutContextParam
+__all__ = [
+ "ItemPerformOperationParams",
+ "AuthorizeVaultItemOperationRequest",
+ "PrepareCheckoutVaultItemOperationRequest",
+ "FillVaultItemOperationRequest",
+]
-class ItemPerformOperationParams(TypedDict, total=False):
+
+class AuthorizeVaultItemOperationRequest(TypedDict, total=False):
id_or_name: Required[str]
type: Required[Literal["authorize"]]
+
+
+class PrepareCheckoutVaultItemOperationRequest(TypedDict, total=False):
+ id_or_name: Required[str]
+
+ checkout: Required[VaultCheckoutContextParam]
+ """Required when preparing an unused AgentCard card for Square.
+
+ Consent is bound to this browser and declared merchant origin, not a tab. Wait
+ for the item's ready_to_submit status before native Pay and submit within its
+ readiness deadline. Unused preparations expire automatically; every preparation
+ is single-use, including after failure or expiry.
+ """
+
+ type: Required[Literal["prepare_checkout"]]
+
+
+class FillVaultItemOperationRequest(TypedDict, total=False):
+ id_or_name: Required[str]
+
+ browser_id: Required[str]
+ """Browser session ID, not a reusable browser name."""
+
+ fields: Required[Iterable[VaultCardFillFieldParam]]
+ """Field bindings for this step. No two bindings may resolve to the same element."""
+
+ page_url: Required[str]
+ """Exact current top-level page URL, including path, query, and fragment.
+
+ Must match exactly one open page in the browser; zero or multiple matches fail.
+ No prefix or glob matching. Must use HTTPS without embedded credentials.
+ """
+
+ type: Required[Literal["fill"]]
+
+ timeout_ms: int
+ """Total operation deadline in milliseconds, not a per-field timeout."""
+
+
+ItemPerformOperationParams: TypeAlias = Union[
+ AuthorizeVaultItemOperationRequest, PrepareCheckoutVaultItemOperationRequest, FillVaultItemOperationRequest
+]
diff --git a/src/kernel/types/vaults/prepare_checkout_vault_item_operation_request_param.py b/src/kernel/types/vaults/prepare_checkout_vault_item_operation_request_param.py
new file mode 100644
index 00000000..9900c513
--- /dev/null
+++ b/src/kernel/types/vaults/prepare_checkout_vault_item_operation_request_param.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+from .vault_checkout_context_param import VaultCheckoutContextParam
+
+__all__ = ["PrepareCheckoutVaultItemOperationRequestParam"]
+
+
+class PrepareCheckoutVaultItemOperationRequestParam(TypedDict, total=False):
+ """Prepare an unused AgentCard card for Square checkout.
+
+ Deliver the returned approval URL and keep the approval page open. Poll the item until ready_to_submit, then submit native Pay before preparation.expires_at. Readiness lasts at most 30 seconds. Unused preparations expire automatically. Preparations are single-use even after failure or expiry; do not automatically retry and reconcile uncertain outcomes with the merchant.
+ """
+
+ checkout: Required[VaultCheckoutContextParam]
+ """Required when preparing an unused AgentCard card for Square.
+
+ Consent is bound to this browser and declared merchant origin, not a tab. Wait
+ for the item's ready_to_submit status before native Pay and submit within its
+ readiness deadline. Unused preparations expire automatically; every preparation
+ is single-use, including after failure or expiry.
+ """
+
+ type: Required[Literal["prepare_checkout"]]
diff --git a/src/kernel/types/vaults/vault_card_fill_field_param.py b/src/kernel/types/vaults/vault_card_fill_field_param.py
new file mode 100644
index 00000000..e286291e
--- /dev/null
+++ b/src/kernel/types/vaults/vault_card_fill_field_param.py
@@ -0,0 +1,60 @@
+# 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__ = ["VaultCardFillFieldParam", "VaultCardStoredFillField", "VaultCardExpirationFillField"]
+
+
+class VaultCardStoredFillField(TypedDict, total=False):
+ field: Required[
+ Literal[
+ "number",
+ "exp_month",
+ "exp_year",
+ "cvc",
+ "billing_name",
+ "billing_line1",
+ "billing_line2",
+ "billing_city",
+ "billing_state",
+ "billing_postal_code",
+ "billing_country",
+ ]
+ ]
+ """Field in the decrypted card, not an alias.
+
+ Number and CVC preserve leading zeros; month uses two digits and year uses four
+ digits. Billing fields use the provider's stored billing address (name, line1,
+ line2, city, state, postal_code, country) without reformatting. Request only
+ needed billing fields. An absent or empty requested billing field returns 400
+ field_unavailable before any browser writes; it does not make other card fields
+ unavailable.
+ """
+
+ selector: Required[str]
+ """CSS selector for an editable input or select, or a containing element.
+
+ Must resolve to one unique editable element across all page frames.
+ """
+
+
+class VaultCardExpirationFillField(TypedDict, total=False):
+ """
+ Combined expiration derived from the stored month and year; not a separate stored secret.
+ """
+
+ field: Required[Literal["expiration"]]
+
+ format: Required[Literal["MM/YY", "MM/YYYY"]]
+
+ selector: Required[str]
+ """CSS selector for an editable input or select, or a containing element.
+
+ Must resolve to one unique editable element across all page frames.
+ """
+
+
+VaultCardFillFieldParam: TypeAlias = Union[VaultCardStoredFillField, VaultCardExpirationFillField]
diff --git a/src/kernel/types/vaults/vault_checkout_context_param.py b/src/kernel/types/vaults/vault_checkout_context_param.py
new file mode 100644
index 00000000..8b08c40c
--- /dev/null
+++ b/src/kernel/types/vaults/vault_checkout_context_param.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["VaultCheckoutContextParam"]
+
+
+class VaultCheckoutContextParam(TypedDict, total=False):
+ """Required when preparing an unused AgentCard card for Square.
+
+ Consent is bound to this browser and declared merchant origin, not a tab. Wait for the item's ready_to_submit status before native Pay and submit within its readiness deadline. Unused preparations expire automatically; every preparation is single-use, including after failure or expiry.
+ """
+
+ browser_id: Required[str]
+ """Active browser session with this vault bound to it."""
+
+ environment: Required[Literal["production", "sandbox"]]
+ """Square environment, independent of the AgentCard credential mode."""
+
+ merchant_origin: Required[str]
+ """Canonical HTTPS origin of the top-level merchant document, not the Square
+ iframe.
+
+ HTTP localhost is accepted for tests.
+ """
diff --git a/src/kernel/types/vaults/vault_fill_field_result.py b/src/kernel/types/vaults/vault_fill_field_result.py
new file mode 100644
index 00000000..757b4d43
--- /dev/null
+++ b/src/kernel/types/vaults/vault_fill_field_result.py
@@ -0,0 +1,35 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["VaultFillFieldResult"]
+
+
+class VaultFillFieldResult(BaseModel):
+ index: int
+ """Zero-based index into the request fields array."""
+
+ status: Literal["filled", "failed", "not_attempted", "unknown"]
+ """
+ Filled means the fill action completed, not that the website retained or
+ accepted the value.
+ """
+
+ error_code: Optional[
+ Literal[
+ "target_changed",
+ "element_not_found",
+ "ambiguous_selector",
+ "element_not_editable",
+ "option_not_found",
+ "timeout",
+ "execution_failed",
+ ]
+ ] = None
+ """Present only for failed or unknown fields.
+
+ Never includes secret values, DOM content, or raw browser errors.
+ """
diff --git a/src/kernel/types/vaults/vault_item.py b/src/kernel/types/vaults/vault_item.py
index 2cc7ab26..e33e12db 100644
--- a/src/kernel/types/vaults/vault_item.py
+++ b/src/kernel/types/vaults/vault_item.py
@@ -43,7 +43,7 @@ class WalletVaultItemAvailableOperation(BaseModel):
description: str
- type: Literal["authorize"]
+ type: Literal["authorize", "prepare_checkout", "fill"]
class WalletVaultItemExpanded(BaseModel):
@@ -107,7 +107,7 @@ class CardVaultItemAvailableOperation(BaseModel):
description: str
- type: Literal["authorize"]
+ type: Literal["authorize", "prepare_checkout", "fill"]
class CardVaultItem(BaseModel):
diff --git a/src/kernel/types/vaults/vault_item_operation_response.py b/src/kernel/types/vaults/vault_item_operation_response.py
new file mode 100644
index 00000000..a464a6b8
--- /dev/null
+++ b/src/kernel/types/vaults/vault_item_operation_response.py
@@ -0,0 +1,139 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from ..._models import BaseModel
+from .vault_item_action import VaultItemAction
+from .card_vault_item_spec import CardVaultItemSpec
+from .vault_payment_method import VaultPaymentMethod
+from .card_vault_item_state import CardVaultItemState
+from .wallet_vault_item_spec import WalletVaultItemSpec
+from .wallet_vault_item_state import WalletVaultItemState
+from .fill_vault_item_operation_result import FillVaultItemOperationResult
+
+__all__ = [
+ "VaultItemOperationResponse",
+ "WalletVaultItem",
+ "WalletVaultItemAvailableExpansion",
+ "WalletVaultItemAvailableOperation",
+ "WalletVaultItemExpanded",
+ "CardVaultItem",
+ "CardVaultItemAvailableExpansion",
+ "CardVaultItemAvailableOperation",
+]
+
+
+class WalletVaultItemAvailableExpansion(BaseModel):
+ """
+ Live data that can currently be requested by passing its type to the item GET expand parameter.
+ """
+
+ description: str
+
+ type: Literal["payment_methods"]
+
+
+class WalletVaultItemAvailableOperation(BaseModel):
+ """An operation that is currently valid for this item.
+
+ Read the description before invoking it through the item operations endpoint.
+ """
+
+ description: str
+
+ type: Literal["authorize", "prepare_checkout", "fill"]
+
+
+class WalletVaultItemExpanded(BaseModel):
+ """Live, non-persisted data requested through the item GET expand parameter."""
+
+ payment_methods: Optional[List[VaultPaymentMethod]] = None
+
+
+class WalletVaultItem(BaseModel):
+ id: str
+
+ available_expansions: List[WalletVaultItemAvailableExpansion]
+
+ available_operations: List[WalletVaultItemAvailableOperation]
+
+ created_at: datetime
+
+ key: str
+ """Immutable item key assigned when the item is created."""
+
+ spec: WalletVaultItemSpec
+ """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.
+ """
+
+ state: WalletVaultItemState
+
+ type: Literal["wallet"]
+
+ updated_at: datetime
+
+ action: Optional[VaultItemAction] = None
+
+ expanded: Optional[WalletVaultItemExpanded] = None
+ """Live, non-persisted data requested through the item GET expand parameter."""
+
+ expires_at: Optional[datetime] = None
+
+
+class CardVaultItemAvailableExpansion(BaseModel):
+ """
+ Live data that can currently be requested by passing its type to the item GET expand parameter.
+ """
+
+ description: str
+
+ type: Literal["payment_methods"]
+
+
+class CardVaultItemAvailableOperation(BaseModel):
+ """An operation that is currently valid for this item.
+
+ Read the description before invoking it through the item operations endpoint.
+ """
+
+ description: str
+
+ type: Literal["authorize", "prepare_checkout", "fill"]
+
+
+class CardVaultItem(BaseModel):
+ id: str
+
+ available_expansions: List[CardVaultItemAvailableExpansion]
+
+ available_operations: List[CardVaultItemAvailableOperation]
+
+ created_at: datetime
+
+ key: str
+ """Immutable item key assigned when the item is created."""
+
+ spec: CardVaultItemSpec
+ """Live payment card. Test-mode card creation is not supported."""
+
+ state: CardVaultItemState
+
+ type: Literal["card"]
+
+ updated_at: datetime
+
+ action: Optional[VaultItemAction] = None
+
+ expires_at: Optional[datetime] = None
+
+
+VaultItemOperationResponse: TypeAlias = Union[WalletVaultItem, CardVaultItem, FillVaultItemOperationResult]
diff --git a/tests/api_resources/auth/test_connections.py b/tests/api_resources/auth/test_connections.py
index 4dff13ee..53a55fa7 100644
--- a/tests/api_resources/auth/test_connections.py
+++ b/tests/api_resources/auth/test_connections.py
@@ -46,6 +46,7 @@ def test_method_create_with_all_params(self, client: Kernel) -> None:
"mode": "direct",
"name": "x",
},
+ "region": "us-east",
"stealth": False,
"telemetry": {
"browser": {
@@ -211,6 +212,7 @@ def test_method_update_with_all_params(self, client: Kernel) -> None:
"mode": "direct",
"name": "x",
},
+ "region": "us-east",
"stealth": False,
"telemetry": {
"browser": {
@@ -461,6 +463,7 @@ def test_method_login_with_all_params(self, client: Kernel) -> None:
"mode": "direct",
"name": "x",
},
+ "region": "us-east",
"stealth": False,
"telemetry": {
"browser": {
@@ -705,6 +708,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncKernel) ->
"mode": "direct",
"name": "x",
},
+ "region": "us-east",
"stealth": False,
"telemetry": {
"browser": {
@@ -870,6 +874,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) ->
"mode": "direct",
"name": "x",
},
+ "region": "us-east",
"stealth": False,
"telemetry": {
"browser": {
@@ -1120,6 +1125,7 @@ async def test_method_login_with_all_params(self, async_client: AsyncKernel) ->
"mode": "direct",
"name": "x",
},
+ "region": "us-east",
"stealth": False,
"telemetry": {
"browser": {
diff --git a/tests/api_resources/test_config_registry.py b/tests/api_resources/test_config_registry.py
index 710d3088..18a3d598 100644
--- a/tests/api_resources/test_config_registry.py
+++ b/tests/api_resources/test_config_registry.py
@@ -119,6 +119,7 @@ def test_method_resolve_with_all_params(self, client: Kernel) -> None:
config_registry = client.config_registry.resolve(
url="https://example.com",
allowed_proxy_countries=["US"],
+ intent="search for a black hoodie and add it to the cart",
)
assert_matches_type(ConfigRegistryResponse, config_registry, path=["response"])
@@ -251,6 +252,7 @@ async def test_method_resolve_with_all_params(self, async_client: AsyncKernel) -
config_registry = await async_client.config_registry.resolve(
url="https://example.com",
allowed_proxy_countries=["US"],
+ intent="search for a black hoodie and add it to the cart",
)
assert_matches_type(ConfigRegistryResponse, config_registry, path=["response"])
diff --git a/tests/api_resources/vaults/test_items.py b/tests/api_resources/vaults/test_items.py
index 9747f919..f9dde10b 100644
--- a/tests/api_resources/vaults/test_items.py
+++ b/tests/api_resources/vaults/test_items.py
@@ -13,6 +13,7 @@
VaultItem,
ItemListResponse,
ItemEventsResponse,
+ VaultItemOperationResponse,
)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -392,17 +393,17 @@ def test_path_params_events(self, client: Kernel) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_method_perform_operation(self, client: Kernel) -> None:
+ def test_method_perform_operation_overload_1(self, client: Kernel) -> None:
item = client.vaults.items.perform_operation(
key="key",
id_or_name="id_or_name",
type="authorize",
)
- assert_matches_type(VaultItem, item, path=["response"])
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_perform_operation(self, client: Kernel) -> None:
+ def test_raw_response_perform_operation_overload_1(self, client: Kernel) -> None:
response = client.vaults.items.with_raw_response.perform_operation(
key="key",
id_or_name="id_or_name",
@@ -412,11 +413,11 @@ def test_raw_response_perform_operation(self, client: Kernel) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
item = response.parse()
- assert_matches_type(VaultItem, item, path=["response"])
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_streaming_response_perform_operation(self, client: Kernel) -> None:
+ def test_streaming_response_perform_operation_overload_1(self, client: Kernel) -> None:
with client.vaults.items.with_streaming_response.perform_operation(
key="key",
id_or_name="id_or_name",
@@ -426,13 +427,13 @@ def test_streaming_response_perform_operation(self, client: Kernel) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
item = response.parse()
- assert_matches_type(VaultItem, item, path=["response"])
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
assert cast(Any, response.is_closed) is True
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_path_params_perform_operation(self, client: Kernel) -> None:
+ def test_path_params_perform_operation_overload_1(self, client: Kernel) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
client.vaults.items.with_raw_response.perform_operation(
key="key",
@@ -447,6 +448,276 @@ def test_path_params_perform_operation(self, client: Kernel) -> None:
type="authorize",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_perform_operation_overload_2(self, client: Kernel) -> None:
+ item = client.vaults.items.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ )
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_perform_operation_overload_2(self, client: Kernel) -> None:
+ response = client.vaults.items.with_raw_response.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ item = response.parse()
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_perform_operation_overload_2(self, client: Kernel) -> None:
+ with client.vaults.items.with_streaming_response.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ item = response.parse()
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_perform_operation_overload_2(self, client: Kernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
+ client.vaults.items.with_raw_response.perform_operation(
+ key="key",
+ id_or_name="",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"):
+ client.vaults.items.with_raw_response.perform_operation(
+ key="",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_perform_operation_overload_3(self, client: Kernel) -> None:
+ item = client.vaults.items.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ )
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_perform_operation_with_all_params_overload_3(self, client: Kernel) -> None:
+ item = client.vaults.items.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ timeout_ms=1,
+ )
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_perform_operation_overload_3(self, client: Kernel) -> None:
+ response = client.vaults.items.with_raw_response.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ item = response.parse()
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_perform_operation_overload_3(self, client: Kernel) -> None:
+ with client.vaults.items.with_streaming_response.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ item = response.parse()
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_perform_operation_overload_3(self, client: Kernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"):
+ client.vaults.items.with_raw_response.perform_operation(
+ key="key",
+ id_or_name="",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"):
+ client.vaults.items.with_raw_response.perform_operation(
+ key="",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ )
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_upsert_overload_1(self, client: Kernel) -> None:
@@ -1088,17 +1359,17 @@ async def test_path_params_events(self, async_client: AsyncKernel) -> None:
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_method_perform_operation(self, async_client: AsyncKernel) -> None:
+ async def test_method_perform_operation_overload_1(self, async_client: AsyncKernel) -> None:
item = await async_client.vaults.items.perform_operation(
key="key",
id_or_name="id_or_name",
type="authorize",
)
- assert_matches_type(VaultItem, item, path=["response"])
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_raw_response_perform_operation(self, async_client: AsyncKernel) -> None:
+ async def test_raw_response_perform_operation_overload_1(self, async_client: AsyncKernel) -> None:
response = await async_client.vaults.items.with_raw_response.perform_operation(
key="key",
id_or_name="id_or_name",
@@ -1108,11 +1379,11 @@ async def test_raw_response_perform_operation(self, async_client: AsyncKernel) -
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
item = await response.parse()
- assert_matches_type(VaultItem, item, path=["response"])
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- async def test_streaming_response_perform_operation(self, async_client: AsyncKernel) -> None:
+ async def test_streaming_response_perform_operation_overload_1(self, async_client: AsyncKernel) -> None:
async with async_client.vaults.items.with_streaming_response.perform_operation(
key="key",
id_or_name="id_or_name",
@@ -1122,13 +1393,13 @@ async def test_streaming_response_perform_operation(self, async_client: AsyncKer
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
item = await response.parse()
- assert_matches_type(VaultItem, item, path=["response"])
+ assert_matches_type(VaultItemOperationResponse, item, 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_perform_operation(self, async_client: AsyncKernel) -> None:
+ async def test_path_params_perform_operation_overload_1(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.vaults.items.with_raw_response.perform_operation(
key="key",
@@ -1143,6 +1414,276 @@ async def test_path_params_perform_operation(self, async_client: AsyncKernel) ->
type="authorize",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_perform_operation_overload_2(self, async_client: AsyncKernel) -> None:
+ item = await async_client.vaults.items.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ )
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_perform_operation_overload_2(self, async_client: AsyncKernel) -> None:
+ response = await async_client.vaults.items.with_raw_response.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ item = await response.parse()
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_perform_operation_overload_2(self, async_client: AsyncKernel) -> None:
+ async with async_client.vaults.items.with_streaming_response.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ item = await response.parse()
+ assert_matches_type(VaultItemOperationResponse, item, 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_perform_operation_overload_2(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.vaults.items.with_raw_response.perform_operation(
+ key="key",
+ id_or_name="",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"):
+ await async_client.vaults.items.with_raw_response.perform_operation(
+ key="",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ },
+ type="prepare_checkout",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_perform_operation_overload_3(self, async_client: AsyncKernel) -> None:
+ item = await async_client.vaults.items.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ )
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_perform_operation_with_all_params_overload_3(self, async_client: AsyncKernel) -> None:
+ item = await async_client.vaults.items.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ timeout_ms=1,
+ )
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_perform_operation_overload_3(self, async_client: AsyncKernel) -> None:
+ response = await async_client.vaults.items.with_raw_response.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ item = await response.parse()
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_perform_operation_overload_3(self, async_client: AsyncKernel) -> None:
+ async with async_client.vaults.items.with_streaming_response.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ item = await response.parse()
+ assert_matches_type(VaultItemOperationResponse, item, 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_perform_operation_overload_3(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.vaults.items.with_raw_response.perform_operation(
+ key="key",
+ id_or_name="",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"):
+ await async_client.vaults.items.with_raw_response.perform_operation(
+ key="",
+ id_or_name="id_or_name",
+ browser_id="browser-session-id",
+ fields=[
+ {
+ "field": "number",
+ "selector": "#card-number",
+ },
+ {
+ "field": "exp_month",
+ "selector": "#expiry-month",
+ },
+ {
+ "field": "exp_year",
+ "selector": "#expiry-year",
+ },
+ {
+ "field": "cvc",
+ "selector": "#security-code",
+ },
+ ],
+ page_url="https://shop.example/checkout",
+ type="fill",
+ )
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_upsert_overload_1(self, async_client: AsyncKernel) -> None: