From 632b8ec501c1c68453300230849f1f4a05462477 Mon Sep 17 00:00:00 2001 From: Shuchang Zheng Date: Tue, 7 Jul 2026 15:18:31 -0700 Subject: [PATCH] Bump version to 1.0.45 (#7167) Co-authored-by: Claude Fable 5 --- fern/openapi/skyvern_openapi.json | 162 + packages/skyvern-ui/pyproject.toml | 2 +- pyproject.toml | 2 +- scripts/fern_build_python_sdk.sh | 3 + scripts/patch_generated_client.py | 132 + skyvern-ts/client/.npmrc | 5 - skyvern-ts/client/package-lock.json | 989 +++-- skyvern-ts/client/package.json | 12 +- skyvern-ts/client/pnpm-lock.yaml | 752 ++-- skyvern-ts/client/reference.md | 205 +- skyvern-ts/client/src/Client.ts | 2015 +++++++--- .../requests/BatchGetWorkflowTagsRequest.ts | 12 + .../requests/CreateBrowserProfileRequest.ts | 17 +- .../requests/CreateBrowserSessionRequest.ts | 2 + .../client/requests/GetCredentialsRequest.ts | 8 +- .../requests/GetWorkflowTagHistoryRequest.ts | 18 + .../client/requests/GetWorkflowsRequest.ts | 2 + .../api/client/requests/TagApplyRequest.ts | 14 + .../src/api/client/requests/TagKeyUpdate.ts | 10 + .../requests/UpdateBrowserProfileRequest.ts | 15 + .../requests/UpdateBrowserSessionRequest.ts | 12 + .../requests/WorkflowRunRequestInput.ts | 8 +- .../requests/WorkflowTagsBatchRequest.ts | 10 + .../client/src/api/client/requests/index.ts | 6 + .../{workflows => agents}/client/Client.ts | 20 +- .../{server => agents}/client/index.ts | 0 .../api/resources/{server => agents}/index.ts | 0 skyvern-ts/client/src/api/resources/index.ts | 3 +- .../api/resources/schedules/client/Client.ts | 28 +- .../src/api/resources/server/client/Client.ts | 84 - .../api/resources/workflows/client/index.ts | 1 - .../src/api/resources/workflows/index.ts | 1 - .../client/src/api/types/ActionBlock.ts | 2 + .../client/src/api/types/ActionBlockYaml.ts | 2 + skyvern-ts/client/src/api/types/ActionType.ts | 2 + .../client/src/api/types/AiFallbackMode.ts | 16 + .../client/src/api/types/ArtifactType.ts | 2 + .../client/src/api/types/BrowserProfile.ts | 11 + .../src/api/types/BrowserSessionResponse.ts | 2 + .../src/api/types/CreateCredentialRequest.ts | 10 + .../src/api/types/CredentialResponse.ts | 2 + .../client/src/api/types/FileStorageType.ts | 1 + .../client/src/api/types/FileUploadBlock.ts | 2 + .../src/api/types/FileUploadBlockYaml.ts | 2 + skyvern-ts/client/src/api/types/LoginBlock.ts | 1 + .../client/src/api/types/LoginBlockYaml.ts | 1 + .../client/src/api/types/TagDeleteInput.ts | 12 + .../client/src/api/types/TagHistoryItem.ts | 15 + .../src/api/types/TagHistoryResponse.ts | 8 + skyvern-ts/client/src/api/types/TagInput.ts | 12 + skyvern-ts/client/src/api/types/TagItem.ts | 10 + skyvern-ts/client/src/api/types/TagKey.ts | 10 + .../src/api/types/TagKeyDeleteResponse.ts | 9 + .../client/src/api/types/TagResponse.ts | 13 + .../client/src/api/types/TagsResponse.ts | 12 + skyvern-ts/client/src/api/types/Workflow.ts | 2 + .../src/api/types/WorkflowRunRequestOutput.ts | 4 +- .../api/types/WorkflowTagsBatchResponse.ts | 14 + skyvern-ts/client/src/api/types/index.ts | 11 + skyvern-ts/client/src/library/Skyvern.ts | 4 +- .../src/library/SkyvernBrowserPageAgent.ts | 48 +- skyvern-ts/client/src/version.ts | 2 +- .../{workflows.test.ts => agents.test.ts} | 18 +- skyvern-ts/client/tests/wire/main.test.ts | 2840 +++++++++----- .../client/tests/wire/schedules.test.ts | 28 +- skyvern-ts/client/tests/wire/server.test.ts | 19 - skyvern/client/__init__.py | 53 +- skyvern/client/{server => agents}/__init__.py | 0 .../client/{workflows => agents}/client.py | 22 +- .../{workflows => agents}/raw_client.py | 8 +- skyvern/client/client.py | 2450 ++++++++---- skyvern/client/core/client_wrapper.py | 4 +- skyvern/client/core/pydantic_utilities.py | 1 + skyvern/client/raw_client.py | 3277 ++++++++++++----- skyvern/client/schedules/raw_client.py | 28 +- skyvern/client/server/client.py | 99 - skyvern/client/server/raw_client.py | 92 - skyvern/client/types/__init__.py | 45 + skyvern/client/types/action_block.py | 3 + skyvern/client/types/action_block_yaml.py | 3 + skyvern/client/types/action_type.py | 2 + skyvern/client/types/ai_fallback_mode.py | 5 + skyvern/client/types/artifact_type.py | 2 + skyvern/client/types/browser_profile.py | 7 +- .../types/browser_profile_proxy_location.py | 8 + .../client/types/browser_session_response.py | 5 + ..._browser_profile_request_proxy_location.py | 10 + .../client/types/create_credential_request.py | 16 + ...reate_credential_request_proxy_location.py | 10 + skyvern/client/types/credential_parameter.py | 2 - .../client/types/credential_parameter_yaml.py | 2 - skyvern/client/types/credential_response.py | 16 +- skyvern/client/types/file_type.py | 2 +- skyvern/client/types/for_loop_block.py | 4 +- .../types/for_loop_block_loop_blocks_item.py | 87 +- skyvern/client/types/for_loop_block_yaml.py | 1 + .../for_loop_block_yaml_loop_blocks_item.py | 28 +- skyvern/client/types/login_block.py | 1 + skyvern/client/types/login_block_yaml.py | 1 + .../types/non_empty_credit_card_credential.py | 20 - skyvern/client/types/tag_delete_input.py | 32 + skyvern/client/types/tag_history_item.py | 31 + skyvern/client/types/tag_history_response.py | 21 + skyvern/client/types/tag_input.py | 32 + skyvern/client/types/tag_item.py | 25 + skyvern/client/types/tag_key.py | 25 + .../client/types/tag_key_delete_response.py | 24 + skyvern/client/types/tag_response.py | 29 + skyvern/client/types/tags_response.py | 26 + ..._browser_profile_request_proxy_location.py | 10 + .../while_loop_block_loop_blocks_item.py | 85 +- skyvern/client/types/while_loop_block_yaml.py | 1 + .../while_loop_block_yaml_loop_blocks_item.py | 28 +- skyvern/client/types/workflow.py | 5 +- .../types/workflow_create_yaml_request.py | 1 - .../types/workflow_definition_blocks_item.py | 4 + .../workflow_definition_parameters_item.py | 2 - .../workflow_definition_yaml_blocks_item.py | 4 + ...orkflow_definition_yaml_parameters_item.py | 2 - .../types/workflow_run_request_output.py | 2 +- .../types/workflow_tags_batch_response.py | 28 + skyvern/client/workflows/__init__.py | 4 - skyvern/library/skyvern.py | 2 +- tests/unit/test_sdk_run_metadata.py | 16 +- uv.lock | 2 +- 125 files changed, 9604 insertions(+), 4848 deletions(-) create mode 100644 scripts/patch_generated_client.py delete mode 100644 skyvern-ts/client/.npmrc create mode 100644 skyvern-ts/client/src/api/client/requests/BatchGetWorkflowTagsRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/GetWorkflowTagHistoryRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/TagApplyRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/TagKeyUpdate.ts create mode 100644 skyvern-ts/client/src/api/client/requests/UpdateBrowserSessionRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/WorkflowTagsBatchRequest.ts rename skyvern-ts/client/src/api/resources/{workflows => agents}/client/Client.ts (85%) rename skyvern-ts/client/src/api/resources/{server => agents}/client/index.ts (100%) rename skyvern-ts/client/src/api/resources/{server => agents}/index.ts (100%) delete mode 100644 skyvern-ts/client/src/api/resources/server/client/Client.ts delete mode 100644 skyvern-ts/client/src/api/resources/workflows/client/index.ts delete mode 100644 skyvern-ts/client/src/api/resources/workflows/index.ts create mode 100644 skyvern-ts/client/src/api/types/AiFallbackMode.ts create mode 100644 skyvern-ts/client/src/api/types/TagDeleteInput.ts create mode 100644 skyvern-ts/client/src/api/types/TagHistoryItem.ts create mode 100644 skyvern-ts/client/src/api/types/TagHistoryResponse.ts create mode 100644 skyvern-ts/client/src/api/types/TagInput.ts create mode 100644 skyvern-ts/client/src/api/types/TagItem.ts create mode 100644 skyvern-ts/client/src/api/types/TagKey.ts create mode 100644 skyvern-ts/client/src/api/types/TagKeyDeleteResponse.ts create mode 100644 skyvern-ts/client/src/api/types/TagResponse.ts create mode 100644 skyvern-ts/client/src/api/types/TagsResponse.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowTagsBatchResponse.ts rename skyvern-ts/client/tests/wire/{workflows.test.ts => agents.test.ts} (74%) delete mode 100644 skyvern-ts/client/tests/wire/server.test.ts rename skyvern/client/{server => agents}/__init__.py (100%) rename skyvern/client/{workflows => agents}/client.py (83%) rename skyvern/client/{workflows => agents}/raw_client.py (96%) delete mode 100644 skyvern/client/server/client.py delete mode 100644 skyvern/client/server/raw_client.py create mode 100644 skyvern/client/types/ai_fallback_mode.py create mode 100644 skyvern/client/types/browser_profile_proxy_location.py create mode 100644 skyvern/client/types/create_browser_profile_request_proxy_location.py create mode 100644 skyvern/client/types/create_credential_request_proxy_location.py create mode 100644 skyvern/client/types/tag_delete_input.py create mode 100644 skyvern/client/types/tag_history_item.py create mode 100644 skyvern/client/types/tag_history_response.py create mode 100644 skyvern/client/types/tag_input.py create mode 100644 skyvern/client/types/tag_item.py create mode 100644 skyvern/client/types/tag_key.py create mode 100644 skyvern/client/types/tag_key_delete_response.py create mode 100644 skyvern/client/types/tag_response.py create mode 100644 skyvern/client/types/tags_response.py create mode 100644 skyvern/client/types/update_browser_profile_request_proxy_location.py create mode 100644 skyvern/client/types/workflow_tags_batch_response.py delete mode 100644 skyvern/client/workflows/__init__.py diff --git a/fern/openapi/skyvern_openapi.json b/fern/openapi/skyvern_openapi.json index ef4bbb20c..057480da2 100644 --- a/fern/openapi/skyvern_openapi.json +++ b/fern/openapi/skyvern_openapi.json @@ -8301,6 +8301,62 @@ ], "title": "Source Browser Type" }, + "proxy_location": { + "anyOf": [ + { + "$ref": "#/components/schemas/ProxyLocation" + }, + { + "$ref": "#/components/schemas/GeoTarget" + }, + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Proxy Location" + }, + "proxy_session_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Proxy Session Id" + }, + "is_managed": { + "type": "boolean", + "title": "Is Managed", + "default": false + }, + "workflow_permanent_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Workflow Permanent Id" + }, + "browser_profile_key_digest": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Browser Profile Key Digest" + }, "created_at": { "type": "string", "format": "date-time", @@ -9255,6 +9311,37 @@ ], "title": "Workflow Run Id", "description": "Workflow run whose persisted session should be captured. Omit for a blank profile." + }, + "proxy_location": { + "anyOf": [ + { + "$ref": "#/components/schemas/ProxyLocation" + }, + { + "$ref": "#/components/schemas/GeoTarget" + }, + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Proxy Location", + "description": "Optional proxy location for this profile's pinned proxy identity." + }, + "proxy_session_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Proxy Session Id", + "description": "Explicit sticky-session id for this profile's pinned proxy identity." } }, "type": "object", @@ -9394,10 +9481,48 @@ ], "description": "Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization.", "examples": [ + "skyvern", "custom", "azure_vault", "bitwarden" ] + }, + "proxy_location": { + "anyOf": [ + { + "$ref": "#/components/schemas/ProxyLocation" + }, + { + "$ref": "#/components/schemas/GeoTarget" + }, + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Proxy Location", + "description": "Optional proxy location for this credential's pinned proxy identity." + }, + "proxy_session_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Proxy Session Id", + "description": "Optional advanced reuse key for this credential's pinned proxy identity." + }, + "rotate_proxy_session_id": { + "type": "boolean", + "title": "Rotate Proxy Session Id", + "description": "Rotate the Skyvern-managed proxy sticky-session id when updating this credential.", + "default": false } }, "type": "object", @@ -20340,6 +20465,43 @@ ], "title": "Description", "description": "New description for the browser profile" + }, + "proxy_location": { + "anyOf": [ + { + "$ref": "#/components/schemas/ProxyLocation" + }, + { + "$ref": "#/components/schemas/GeoTarget" + }, + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Proxy Location", + "description": "Optional proxy location for this profile's pinned proxy identity." + }, + "proxy_session_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Proxy Session Id", + "description": "Opaque Skyvern-managed proxy sticky-session id." + }, + "rotate_proxy_session_id": { + "type": "boolean", + "title": "Rotate Proxy Session Id", + "description": "Rotate the Skyvern-managed proxy sticky-session id for this profile.", + "default": false } }, "type": "object", diff --git a/packages/skyvern-ui/pyproject.toml b/packages/skyvern-ui/pyproject.toml index 07961b25e..0a73df5a5 100644 --- a/packages/skyvern-ui/pyproject.toml +++ b/packages/skyvern-ui/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "skyvern-ui" -version = "1.0.44" +version = "1.0.45" description = "Prebuilt Skyvern UI assets for the Skyvern CLI" authors = [{ name = "Skyvern AI", email = "info@skyvern.com" }] requires-python = ">=3.11,<3.14" diff --git a/pyproject.toml b/pyproject.toml index bde63944f..8bc7fce49 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "skyvern" -version = "1.0.44" +version = "1.0.45" description = "" authors = [{ name = "Skyvern AI", email = "info@skyvern.com" }] requires-python = ">=3.11,<3.14" diff --git a/scripts/fern_build_python_sdk.sh b/scripts/fern_build_python_sdk.sh index 20c1f256b..f37e28c3b 100755 --- a/scripts/fern_build_python_sdk.sh +++ b/scripts/fern_build_python_sdk.sh @@ -7,6 +7,9 @@ rm -fr skyvern/client mkdir -p skyvern/client cp -rf fern/.preview/fern-python-sdk/src/skyvern/* skyvern/client/ +# Post-processing: Reapply manual patches (circular imports, forward-ref KeyError) +python3 scripts/patch_generated_client.py || exit 1 + # Post-processing: Patch version.py to handle missing metadata gracefully VERSION_FILE="skyvern/client/version.py" if [ -f "$VERSION_FILE" ]; then diff --git a/scripts/patch_generated_client.py b/scripts/patch_generated_client.py new file mode 100644 index 000000000..de6cd8a6d --- /dev/null +++ b/scripts/patch_generated_client.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Reapply manual patches to the Fern-generated Python client. + +Run automatically by scripts/fern_build_python_sdk.sh after every regen. +Idempotent: running it twice leaves the files unchanged. + +Patches: +1. Loop-block circular imports — Fern v4.31.1 emits bottom-cross-imports that + deadlock at module load (for_loop <-> while_loop <-> *_loop_blocks_item). + Wrap them in try/except ImportError; the symmetric *_loop_blocks_item module + back-resolves once both unions are fully defined. +2. update_forward_refs — Pydantic v2 can raise internal schema-gathering + KeyErrors for Fern-generated recursive unions even with raise_errors=False. + Suppress KeyErrors that mention the "definitions" key. +""" + +from __future__ import annotations + +import sys +from pathlib import Path + +CLIENT = Path(__file__).resolve().parent.parent / "skyvern" / "client" + +LOOP_BLOCK_PATCHES = { + "types/for_loop_block.py": ( + """from .while_loop_block import WhileLoopBlock # noqa: E402, F401, I001 +from .for_loop_block_loop_blocks_item import ForLoopBlockLoopBlocksItem # noqa: E402, F401, I001""", + """ +# Manual patch: Fern v4.31.1 emits bottom-cross-imports that deadlock at module +# load (for_loop <-> while_loop <-> *_loop_blocks_item). Catch the mid-load +# ImportError; the symmetric *_loop_blocks_item module back-resolves once both +# unions are fully defined. Reapplied on every regen by scripts/patch_generated_client.py. +try: + from .while_loop_block import WhileLoopBlock # noqa: E402, F401, I001 + from .for_loop_block_loop_blocks_item import ForLoopBlockLoopBlocksItem # noqa: E402, F401, I001 +except ImportError: + pass""", + ), + "types/while_loop_block.py": ( + """from .for_loop_block import ForLoopBlock # noqa: E402, F401, I001 +from .while_loop_block_loop_blocks_item import WhileLoopBlockLoopBlocksItem # noqa: E402, F401, I001""", + """ +# Manual patch: Fern v4.31.1 emits bottom-cross-imports that deadlock at module +# load. See for_loop_block.py for the explanation. +try: + from .for_loop_block import ForLoopBlock # noqa: E402, F401, I001 + from .while_loop_block_loop_blocks_item import WhileLoopBlockLoopBlocksItem # noqa: E402, F401, I001 +except ImportError: + pass""", + ), + "types/for_loop_block_yaml.py": ( + """from .while_loop_block_yaml import WhileLoopBlockYaml # noqa: E402, F401, I001 +from .for_loop_block_yaml_loop_blocks_item import ForLoopBlockYamlLoopBlocksItem # noqa: E402, F401, I001""", + """ +# Manual patch: Fern v4.31.1 emits bottom-cross-imports that deadlock at module +# load. See for_loop_block.py for the explanation. +try: + from .while_loop_block_yaml import WhileLoopBlockYaml # noqa: E402, F401, I001 + from .for_loop_block_yaml_loop_blocks_item import ForLoopBlockYamlLoopBlocksItem # noqa: E402, F401, I001 +except ImportError: + pass""", + ), + "types/while_loop_block_yaml.py": ( + """from .for_loop_block_yaml import ForLoopBlockYaml # noqa: E402, F401, I001 +from .while_loop_block_yaml_loop_blocks_item import WhileLoopBlockYamlLoopBlocksItem # noqa: E402, F401, I001""", + """ +# Manual patch: Fern v4.31.1 emits bottom-cross-imports that deadlock at module +# load. See for_loop_block.py for the explanation. +try: + from .for_loop_block_yaml import ForLoopBlockYaml # noqa: E402, F401, I001 + from .while_loop_block_yaml_loop_blocks_item import WhileLoopBlockYamlLoopBlocksItem # noqa: E402, F401, I001 +except ImportError: + pass""", + ), +} + +FORWARD_REFS_OLD = """def update_forward_refs(model: Type["Model"], **localns: Any) -> None: + if IS_PYDANTIC_V2: + model.model_rebuild(raise_errors=False) # type: ignore[attr-defined] + else: + model.update_forward_refs(**localns)""" + +FORWARD_REFS_NEW = """def update_forward_refs(model: Type["Model"], **localns: Any) -> None: + if IS_PYDANTIC_V2: + try: + model.model_rebuild(raise_errors=False) # type: ignore[attr-defined] + except KeyError as exc: + # Manual patch (reapplied by scripts/patch_generated_client.py): + # Pydantic v2 can still raise internal schema-gathering KeyErrors + # for Fern-generated recursive unions even with raise_errors=False. + # Match on the "definitions" key rather than the exact args tuple so a + # Pydantic format change that adds context can't reintroduce the crash. + if "definitions" not in exc.args: + raise + else: + model.update_forward_refs(**localns)""" + + +def patch_file(rel_path: str, old: str, new: str) -> str: + path = CLIENT / rel_path + text = path.read_text() + if new in text: + return "already patched" + if old not in text: + return "PATTERN NOT FOUND" + path.write_text(text.replace(old, new, 1)) + return "patched" + + +def main() -> int: + failed = False + for rel_path, (old, new) in LOOP_BLOCK_PATCHES.items(): + result = patch_file(rel_path, old, new) + print(f"{rel_path}: {result}") + failed |= result == "PATTERN NOT FOUND" + + result = patch_file("core/pydantic_utilities.py", FORWARD_REFS_OLD, FORWARD_REFS_NEW) + print(f"core/pydantic_utilities.py: {result}") + failed |= result == "PATTERN NOT FOUND" + + if failed: + print( + "ERROR: some patch patterns no longer match the generated code. " + "The Fern generator output changed shape - update this script.", + file=sys.stderr, + ) + return 1 + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/skyvern-ts/client/.npmrc b/skyvern-ts/client/.npmrc deleted file mode 100644 index 5c429893e..000000000 --- a/skyvern-ts/client/.npmrc +++ /dev/null @@ -1,5 +0,0 @@ -# Supply chain protection: do not run lifecycle scripts (preinstall, install, -# postinstall) on npm install. Blocks worms like "Shai-Hulud" from executing -# on a compromised dependency before we notice. If a package genuinely needs -# its install script, use @lavamoat/allow-scripts to allowlist it. -ignore-scripts=true diff --git a/skyvern-ts/client/package-lock.json b/skyvern-ts/client/package-lock.json index aa170eeec..4b1279362 100644 --- a/skyvern-ts/client/package-lock.json +++ b/skyvern-ts/client/package-lock.json @@ -1,12 +1,12 @@ { "name": "@skyvern/client", - "version": "1.0.44", + "version": "1.0.45", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@skyvern/client", - "version": "1.0.44", + "version": "1.0.45", "dependencies": { "playwright": "^1.48.0" }, @@ -219,9 +219,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", - "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", "cpu": [ "ppc64" ], @@ -236,9 +236,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", - "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", "cpu": [ "arm" ], @@ -253,9 +253,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", - "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", "cpu": [ "arm64" ], @@ -270,9 +270,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", - "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", "cpu": [ "x64" ], @@ -287,9 +287,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", - "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", "cpu": [ "arm64" ], @@ -304,9 +304,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", - "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", "cpu": [ "x64" ], @@ -321,9 +321,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", - "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", "cpu": [ "arm64" ], @@ -338,9 +338,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", - "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", "cpu": [ "x64" ], @@ -355,9 +355,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", - "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", "cpu": [ "arm" ], @@ -372,9 +372,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", - "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", "cpu": [ "arm64" ], @@ -389,9 +389,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", - "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", "cpu": [ "ia32" ], @@ -406,9 +406,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", - "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", "cpu": [ "loong64" ], @@ -423,9 +423,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", - "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", "cpu": [ "mips64el" ], @@ -440,9 +440,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", - "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", "cpu": [ "ppc64" ], @@ -457,9 +457,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", - "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", "cpu": [ "riscv64" ], @@ -474,9 +474,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", - "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", "cpu": [ "s390x" ], @@ -491,9 +491,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", - "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", "cpu": [ "x64" ], @@ -508,9 +508,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", - "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", "cpu": [ "arm64" ], @@ -525,9 +525,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", - "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", "cpu": [ "x64" ], @@ -542,9 +542,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", - "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", "cpu": [ "arm64" ], @@ -559,9 +559,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", - "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", "cpu": [ "x64" ], @@ -576,9 +576,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", - "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", "cpu": [ "arm64" ], @@ -593,9 +593,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", - "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", "cpu": [ "x64" ], @@ -610,9 +610,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", - "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", "cpu": [ "arm64" ], @@ -627,9 +627,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", - "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", "cpu": [ "ia32" ], @@ -644,9 +644,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", - "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", "cpu": [ "x64" ], @@ -842,9 +842,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.61.1.tgz", - "integrity": "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", "cpu": [ "arm" ], @@ -856,9 +856,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.61.1.tgz", - "integrity": "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", "cpu": [ "arm64" ], @@ -870,9 +870,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.61.1.tgz", - "integrity": "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", "cpu": [ "arm64" ], @@ -884,9 +884,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.61.1.tgz", - "integrity": "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", "cpu": [ "x64" ], @@ -898,9 +898,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.61.1.tgz", - "integrity": "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", "cpu": [ "arm64" ], @@ -912,9 +912,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.61.1.tgz", - "integrity": "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", "cpu": [ "x64" ], @@ -926,9 +926,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.61.1.tgz", - "integrity": "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", "cpu": [ "arm" ], @@ -943,9 +943,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.61.1.tgz", - "integrity": "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", "cpu": [ "arm" ], @@ -960,9 +960,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.61.1.tgz", - "integrity": "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", "cpu": [ "arm64" ], @@ -977,9 +977,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.61.1.tgz", - "integrity": "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", "cpu": [ "arm64" ], @@ -994,9 +994,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.61.1.tgz", - "integrity": "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", "cpu": [ "loong64" ], @@ -1011,9 +1011,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.61.1.tgz", - "integrity": "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", "cpu": [ "loong64" ], @@ -1028,9 +1028,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.61.1.tgz", - "integrity": "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", "cpu": [ "ppc64" ], @@ -1045,9 +1045,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.61.1.tgz", - "integrity": "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", "cpu": [ "ppc64" ], @@ -1062,9 +1062,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.61.1.tgz", - "integrity": "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", "cpu": [ "riscv64" ], @@ -1079,9 +1079,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.61.1.tgz", - "integrity": "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", "cpu": [ "riscv64" ], @@ -1096,9 +1096,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.61.1.tgz", - "integrity": "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", "cpu": [ "s390x" ], @@ -1113,9 +1113,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.61.1.tgz", - "integrity": "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", "cpu": [ "x64" ], @@ -1130,9 +1130,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.61.1.tgz", - "integrity": "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", "cpu": [ "x64" ], @@ -1147,9 +1147,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.61.1.tgz", - "integrity": "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", "cpu": [ "x64" ], @@ -1161,9 +1161,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.61.1.tgz", - "integrity": "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", "cpu": [ "arm64" ], @@ -1175,9 +1175,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.61.1.tgz", - "integrity": "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", "cpu": [ "arm64" ], @@ -1189,9 +1189,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.61.1.tgz", - "integrity": "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", "cpu": [ "ia32" ], @@ -1203,9 +1203,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.61.1.tgz", - "integrity": "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", "cpu": [ "x64" ], @@ -1217,9 +1217,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.61.1.tgz", - "integrity": "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", "cpu": [ "x64" ], @@ -1287,15 +1287,15 @@ "license": "MIT" }, "node_modules/@vitest/expect": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.6.tgz", - "integrity": "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", + "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -1304,9 +1304,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz", - "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", + "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", "dev": true, "license": "MIT", "dependencies": { @@ -1317,13 +1317,13 @@ } }, "node_modules/@vitest/runner": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.6.tgz", - "integrity": "sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", + "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.6", + "@vitest/utils": "3.2.7", "pathe": "^2.0.3", "strip-literal": "^3.0.0" }, @@ -1332,13 +1332,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.6.tgz", - "integrity": "sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", + "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", + "@vitest/pretty-format": "3.2.7", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -1347,9 +1347,9 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.6.tgz", - "integrity": "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", + "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1360,13 +1360,13 @@ } }, "node_modules/@vitest/utils": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.6.tgz", - "integrity": "sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", + "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", + "@vitest/pretty-format": "3.2.7", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" }, @@ -1660,9 +1660,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.36", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.36.tgz", - "integrity": "sha512-lVq/Df7LXlO79MVaaUHztSwWiG9oXoWHlgvNS51v8Dpd4+G4/VIy6qYePTw31nAVls33nUtnfezYeLkYAak9dg==", + "version": "2.10.42", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.42.tgz", + "integrity": "sha512-c/jurFrDLyui7o1J86yLkRu4LMsTYcBohveus7/I2Hzdn9KIP2bdJPTue/lR1KH46enoPbD77GKeSYNdyPoD3Q==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1672,23 +1672,10 @@ "node": ">=6.0.0" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "version": "4.28.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.5.tgz", + "integrity": "sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ==", "dev": true, "funding": [ { @@ -1706,10 +1693,10 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001800", + "electron-to-chromium": "^1.5.387", + "node-releases": "^2.0.50", "update-browserslist-db": "^1.2.3" }, "bin": { @@ -1737,9 +1724,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001799", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", - "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "version": "1.0.30001803", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001803.tgz", + "integrity": "sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg==", "dev": true, "funding": [ { @@ -1920,9 +1907,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.371", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.371.tgz", - "integrity": "sha512-e9htk9mAYL6AzmkEhSvVVw7IWGSBJ/Bqdn2eRyRLrj1g6sncN4WbFt5qnILYoCktktr45pyjIrOiRvBThQ808w==", + "version": "1.5.388", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.388.tgz", + "integrity": "sha512-Pl/aJaqOOxYxda3vcx1IKSJimwYXHDkEnGn0F+kG2EE68dDtx2uCinaS+Vih8Z91B9t8CSAbiF/HKyWcnXjhzw==", "dev": true, "license": "ISC" }, @@ -1934,9 +1921,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.24.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.0.tgz", - "integrity": "sha512-SkE2t82KlkkxQRVMVLAGKxLfORGQfrkx5dkj+vlgXRVNEdPc4eZcR+J/Fvj8C+yKSFH5L0q3NFlyufOVQnCcYQ==", + "version": "5.24.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.2.tgz", + "integrity": "sha512-rpsZEGT1jFuve6QlpyRp9ckQ+kN61hvF9BzCPyMdaKTm8UJce96KBn3sorXOFXlzjPrs3Vc4T1NsSroZ3PxlFw==", "dev": true, "license": "MIT", "dependencies": { @@ -1955,9 +1942,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.27.7", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", - "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1968,32 +1955,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.7", - "@esbuild/android-arm": "0.27.7", - "@esbuild/android-arm64": "0.27.7", - "@esbuild/android-x64": "0.27.7", - "@esbuild/darwin-arm64": "0.27.7", - "@esbuild/darwin-x64": "0.27.7", - "@esbuild/freebsd-arm64": "0.27.7", - "@esbuild/freebsd-x64": "0.27.7", - "@esbuild/linux-arm": "0.27.7", - "@esbuild/linux-arm64": "0.27.7", - "@esbuild/linux-ia32": "0.27.7", - "@esbuild/linux-loong64": "0.27.7", - "@esbuild/linux-mips64el": "0.27.7", - "@esbuild/linux-ppc64": "0.27.7", - "@esbuild/linux-riscv64": "0.27.7", - "@esbuild/linux-s390x": "0.27.7", - "@esbuild/linux-x64": "0.27.7", - "@esbuild/netbsd-arm64": "0.27.7", - "@esbuild/netbsd-x64": "0.27.7", - "@esbuild/openbsd-arm64": "0.27.7", - "@esbuild/openbsd-x64": "0.27.7", - "@esbuild/openharmony-arm64": "0.27.7", - "@esbuild/sunos-x64": "0.27.7", - "@esbuild/win32-arm64": "0.27.7", - "@esbuild/win32-ia32": "0.27.7", - "@esbuild/win32-x64": "0.27.7" + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" } }, "node_modules/escalade": { @@ -2074,9 +2061,9 @@ } }, "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2091,9 +2078,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz", + "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==", "dev": true, "funding": [ { @@ -2107,17 +2094,22 @@ ], "license": "BSD-3-Clause" }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/fsevents": { @@ -2144,13 +2136,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2202,16 +2187,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -2295,20 +2270,6 @@ "dev": true, "license": "MIT" }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", @@ -2319,6 +2280,67 @@ "node": ">= 0.6" } }, + "node_modules/minimizer-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2383,9 +2405,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", "dev": true, "funding": [ { @@ -2409,9 +2431,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.47", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.47.tgz", - "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz", + "integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==", "dev": true, "license": "MIT", "engines": { @@ -2457,25 +2479,25 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/playwright": { - "version": "1.60.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz", - "integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==", + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz", + "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==", "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.60.0" + "playwright-core": "1.61.1" }, "bin": { "playwright": "cli.js" @@ -2488,9 +2510,9 @@ } }, "node_modules/playwright-core": { - "version": "1.60.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz", - "integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==", + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz", + "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==", "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" @@ -2500,9 +2522,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", "dev": true, "funding": [ { @@ -2556,9 +2578,9 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.61.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.61.1.tgz", - "integrity": "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA==", + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", "dev": true, "license": "MIT", "dependencies": { @@ -2572,31 +2594,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.61.1", - "@rollup/rollup-android-arm64": "4.61.1", - "@rollup/rollup-darwin-arm64": "4.61.1", - "@rollup/rollup-darwin-x64": "4.61.1", - "@rollup/rollup-freebsd-arm64": "4.61.1", - "@rollup/rollup-freebsd-x64": "4.61.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", - "@rollup/rollup-linux-arm-musleabihf": "4.61.1", - "@rollup/rollup-linux-arm64-gnu": "4.61.1", - "@rollup/rollup-linux-arm64-musl": "4.61.1", - "@rollup/rollup-linux-loong64-gnu": "4.61.1", - "@rollup/rollup-linux-loong64-musl": "4.61.1", - "@rollup/rollup-linux-ppc64-gnu": "4.61.1", - "@rollup/rollup-linux-ppc64-musl": "4.61.1", - "@rollup/rollup-linux-riscv64-gnu": "4.61.1", - "@rollup/rollup-linux-riscv64-musl": "4.61.1", - "@rollup/rollup-linux-s390x-gnu": "4.61.1", - "@rollup/rollup-linux-x64-gnu": "4.61.1", - "@rollup/rollup-linux-x64-musl": "4.61.1", - "@rollup/rollup-openbsd-x64": "4.61.1", - "@rollup/rollup-openharmony-arm64": "4.61.1", - "@rollup/rollup-win32-arm64-msvc": "4.61.1", - "@rollup/rollup-win32-ia32-msvc": "4.61.1", - "@rollup/rollup-win32-x64-gnu": "4.61.1", - "@rollup/rollup-win32-x64-msvc": "4.61.1", + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", "fsevents": "~2.3.2" } }, @@ -2620,19 +2642,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -2812,67 +2821,6 @@ "node": ">=10" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz", - "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@minify-html/node": { - "optional": true - }, - "@swc/core": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "@swc/html": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "cssnano": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "html-minifier-terser": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "postcss": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -2904,37 +2852,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/tinypool": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", @@ -2966,42 +2883,29 @@ } }, "node_modules/tldts": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.2.tgz", - "integrity": "sha512-kCwffuaH8ntKtygnWe1b4BJKWiCUH30n5KfoTr6IchcXOwR7chAOFJxFrH3vjANafUYrIA4a7SDL+nn7SiR4Sw==", + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.7.tgz", + "integrity": "sha512-56L0/9HELHSsG1bFCzay8UoLxzRL7kpFf7Wl5q/kSYwiSJGACvro61xnKzPNM+SadxllzdtXsKDSXE7HPeqIAw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.4.2" + "tldts-core": "^7.4.7" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.2.tgz", - "integrity": "sha512-nwEyF4vl4RSJjwSjBUmOSxc3BFPoIFdlRthJ6e+5v9P3bHNsoD06UjuqMUspqp7vsEZ1beaHi1km+optiE17yA==", + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.7.tgz", + "integrity": "sha512-rNlAI8fKn/JckBMUSbNL/ES2kmDiurWaE49l+ikwEc9A6lFR7gMx9AhgQMQKBK4H5w4pKLH64JzZfB99uRsGNQ==", "dev": true, "license": "MIT" }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/tough-cookie": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", - "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -3012,16 +2916,14 @@ } }, "node_modules/ts-loader": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.6.0.tgz", - "integrity": "sha512-dsJO0S+T7grTDWTc4a0nTygXGjKncVUpx8Y+af8EvI/D5WgTJby5UEk5eoMCB9EcLQmnvitqh99MqtjtHgAwFQ==", + "version": "9.6.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.6.2.tgz", + "integrity": "sha512-R4iuczmtgxvtuI556s+hTZ6/7Ee03VCAk/l/M8LY1OAsUgB7YydsCxkgq9D9pKRaD7GJqUi2u8fp9zZP/ufjKA==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", + "picomatch": "^4.0.0", "source-map": "^0.7.4" }, "engines": { @@ -3127,31 +3029,13 @@ } }, "node_modules/vite-node/node_modules/@types/node": { - "version": "25.9.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz", - "integrity": "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==", + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.0.tgz", + "integrity": "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==", "extraneous": true, "license": "MIT", "dependencies": { - "undici-types": ">=7.24.0 <7.24.7" - } - }, - "node_modules/vite-node/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "undici-types": "~8.3.0" } }, "node_modules/vite-node/node_modules/fsevents": { @@ -3169,34 +3053,21 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/vite-node/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/vite-node/node_modules/undici-types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", - "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "extraneous": true, "license": "MIT" }, "node_modules/vite-node/node_modules/vite": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", - "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", + "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -3265,20 +3136,20 @@ } }, "node_modules/vitest": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.6.tgz", - "integrity": "sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", + "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.6", - "@vitest/mocker": "3.2.6", - "@vitest/pretty-format": "^3.2.6", - "@vitest/runner": "3.2.6", - "@vitest/snapshot": "3.2.6", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", + "@vitest/expect": "3.2.7", + "@vitest/mocker": "3.2.7", + "@vitest/pretty-format": "^3.2.7", + "@vitest/runner": "3.2.7", + "@vitest/snapshot": "3.2.7", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", @@ -3308,8 +3179,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.6", - "@vitest/ui": "3.2.6", + "@vitest/browser": "3.2.7", + "@vitest/ui": "3.2.7", "happy-dom": "*", "jsdom": "*" }, @@ -3338,13 +3209,13 @@ } }, "node_modules/vitest/node_modules/@vitest/mocker": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.6.tgz", - "integrity": "sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", + "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.6", + "@vitest/spy": "3.2.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -3364,24 +3235,6 @@ } } }, - "node_modules/vitest/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/vitest/node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3397,27 +3250,14 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/vitest/node_modules/vite": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", - "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.27.0", + "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -3499,9 +3339,9 @@ } }, "node_modules/webpack": { - "version": "5.107.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.107.2.tgz", - "integrity": "sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ==", + "version": "5.108.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.4.tgz", + "integrity": "sha512-yur8LyJoeiWh47dErD+Ok7vlbmDsJ3UbbRPAoxbGJ54WpE2y5yVo5G/inUzujnYgw3tPmBRdn+G7PoxXaYC33w==", "dev": true, "license": "MIT", "dependencies": { @@ -3514,19 +3354,18 @@ "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.22.0", + "enhanced-resolve": "^5.22.2", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "loader-runner": "^4.3.2", "mime-db": "^1.54.0", + "minimizer-webpack-plugin": "^5.6.1", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.5.0", - "watchpack": "^2.5.1", + "watchpack": "^2.5.2", "webpack-sources": "^3.5.0" }, "bin": { @@ -3546,9 +3385,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz", - "integrity": "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", + "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", "dev": true, "license": "MIT", "engines": { @@ -3556,9 +3395,9 @@ } }, "node_modules/webpack/node_modules/es-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", - "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.0.tgz", + "integrity": "sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==", "dev": true, "license": "MIT" }, @@ -3605,9 +3444,9 @@ } }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", "dev": true, "license": "MIT", "dependencies": { diff --git a/skyvern-ts/client/package.json b/skyvern-ts/client/package.json index 6d4c44c49..a458570fc 100644 --- a/skyvern-ts/client/package.json +++ b/skyvern-ts/client/package.json @@ -1,6 +1,6 @@ { "name": "@skyvern/client", - "version": "1.0.44", + "version": "1.0.45", "private": false, "repository": { "type": "git", @@ -52,7 +52,7 @@ "devDependencies": { "webpack": "^5.97.1", "ts-loader": "^9.5.1", - "vitest": "^3.2.6", + "vitest": "^3.2.4", "msw": "2.11.2", "@types/node": "^18.19.70", "typescript": "~5.7.2", @@ -73,13 +73,5 @@ "publishConfig": { "access": "public", "provenance": true - }, - "pnpm": { - "overrides": { - "fast-uri": ">=3.1.2", - "rollup": ">=4.59.0", - "serialize-javascript": ">=7.0.3", - "vite": ">=7.3.5" - } } } diff --git a/skyvern-ts/client/pnpm-lock.yaml b/skyvern-ts/client/pnpm-lock.yaml index 16afaab96..65765f91d 100644 --- a/skyvern-ts/client/pnpm-lock.yaml +++ b/skyvern-ts/client/pnpm-lock.yaml @@ -2,17 +2,12 @@ lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -overrides: - fast-uri: '>=3.1.2' - rollup: '>=4.59.0' - serialize-javascript: '>=7.0.3' - vite: '>=7.3.5' importers: .: dependencies: playwright: specifier: ^1.48.0 - version: 1.60.0 + version: 1.61.1 devDependencies: '@biomejs/biome': specifier: 2.2.5 @@ -30,8 +25,8 @@ importers: specifier: ~5.7.2 version: 5.7.3 vitest: - specifier: ^3.2.6 - version: 3.2.6(@types/node@18.19.130)(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(terser@5.44.0) + specifier: ^3.2.4 + version: 3.2.4(@types/node@18.19.130)(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(terser@5.44.0) webpack: specifier: ^5.97.1 version: 5.102.1 @@ -84,12 +79,136 @@ packages: resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} '@bundled-es-modules/statuses@1.0.1': resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} - '@emnapi/core@1.11.1': - resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - '@emnapi/runtime@1.11.1': - resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@esbuild/aix-ppc64@0.25.11': + resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.25.11': + resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.25.11': + resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.25.11': + resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.25.11': + resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.25.11': + resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.25.11': + resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.11': + resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.25.11': + resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.25.11': + resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.25.11': + resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.25.11': + resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.25.11': + resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.25.11': + resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.25.11': + resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.25.11': + resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.25.11': + resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.11': + resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.11': + resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.11': + resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.11': + resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.11': + resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.25.11': + resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.25.11': + resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.25.11': + resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.25.11': + resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] '@inquirer/ansi@1.0.1': resolution: {integrity: sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==} engines: {node: '>=18'} @@ -134,97 +253,100 @@ packages: '@mswjs/interceptors@0.39.8': resolution: {integrity: sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==} engines: {node: '>=18'} - '@napi-rs/wasm-runtime@1.1.6': - resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} - peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} '@open-draft/logger@0.3.0': resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@oxc-project/types@0.138.0': - resolution: {integrity: sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA==} - '@rolldown/binding-android-arm64@1.1.4': - resolution: {integrity: sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-android-arm-eabi@4.52.5': + resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.52.5': + resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.1.4': - resolution: {integrity: sha512-aUi+HBvmYb7j8krl1+qJgkG8C17fO79gk3c+jPw4S8glRFc1DTija9S3EyaTSQUm5GJXYKDAsugBEhFHH2vYiQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-darwin-arm64@4.52.5': + resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.1.4': - resolution: {integrity: sha512-F7hHC3gwY11+vByKPRWqwGbeXWVgKmL+pTGCinaEhdihzBV2aQ0fvZOch9cXYUOKuKKq429HeYXOqQLc7wFCEg==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-darwin-x64@4.52.5': + resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.1.4': - resolution: {integrity: sha512-sI5yw+7s92SK6odiEhD5lKCBlWcpjHS5qyqpVQbZAJ0fIzEUXrmbl3DH2ybR3PZogulNJF+COLtmA8hUfvkCCQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-freebsd-arm64@4.52.5': + resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} + cpu: [arm64] + os: [freebsd] + '@rollup/rollup-freebsd-x64@4.52.5': + resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.1.4': - resolution: {integrity: sha512-mCi0OKgEieFircrtVYmQAFGszRtMnZ6fpZAXrxanXAu7lqZcsK1E1RAaZNG0uKAnxox3B1f4EyQNnoyMfN1vAA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.1.4': - resolution: {integrity: sha512-B9Ial3Kv5sh0SHnB1g/QWcUQCEvCF6QKGAl4zXypYj65mVI+B4AhFBwPtSN7pDrJeIx8Z7zdy4ntx+wQABom7w==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.52.5': + resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.1.4': - resolution: {integrity: sha512-lZVym0PuHE1KZ22gmFTC15lAkrg9iTszR617oYRB/iPY1A56ywoJzVKOJBKaot5RiikCObmur6pogpse3gRcng==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-linux-arm64-musl@4.52.5': + resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-ppc64-gnu@1.1.4': - resolution: {integrity: sha512-t2DNiLJWNTbnEHyUzTumldML6ET4/g16467LZoDDJ3tSxGvguL5/NyC2lCsNKuyRycg9XeDQF5SSv+TNOhQEXg==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-linux-loong64-gnu@4.52.5': + resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} + cpu: [loong64] + os: [linux] + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} cpu: [ppc64] os: [linux] - '@rolldown/binding-linux-s390x-gnu@1.1.4': - resolution: {integrity: sha512-0WIRnL1Uw4BvTZRLQt+PVgo6ZKTJadlC2btP+/EOXv2f/DWbY0rEgl+y834mIVwP1FkTlWVTrGGJXf12lru7EQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-riscv64-musl@4.52.5': + resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.52.5': + resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} cpu: [s390x] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.1.4': - resolution: {integrity: sha512-JWtGshGfX+oENAKonoNkqEJX+7hC8yfhi9GUyPX1VX4mdh1y5r+ZiJLR5XzAB0aoP6s/PcILsGjKq8O0mm24bw==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-linux-x64-gnu@4.52.5': + resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.1.4': - resolution: {integrity: sha512-rT6yQcxUuXs4CnbofqwHRRV0iem349rLMYpTjkgQGLjrY4ado/eDzwPZPTCgTOlF6Nkp8NEv70yLMTn6qkWxsQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-linux-x64-musl@4.52.5': + resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.1.4': - resolution: {integrity: sha512-KXMGoboq5cyaCQjDA4GLuRiOwBQ0EyFnJoVViLeZ45/3rFItRODEr+NdsBcVpll40hhNArlm/speWGRvj08LzA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-openharmony-arm64@4.52.5': + resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.1.4': - resolution: {integrity: sha512-5K83rb36oJiY7BCyE9zLZtGcPV4g5wvq+xwdO0XPIwDVZI8cyB/AUjkNXGb92/rnmezEkjMOpgY61rtwjQtFwg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.1.4': - resolution: {integrity: sha512-PnWBtw3TV5KOg69HQQDR0mnQuyCmSGR2pAB4DC1rPF808fgKeTUMj2EOEyKATpgiuxuR5APQmiDO7PDgEjTFSA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-win32-arm64-msvc@4.52.5': + resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.1.4': - resolution: {integrity: sha512-M1lpniBePobTfsa7Ks9a199e1akxsXn+GYBUKsEzv3YFzOm1HJAMNwKI3qr0Zq+mxwx9gOZoTdP1yXRYsZUocQ==} - engines: {node: ^20.19.0 || >=22.12.0} + '@rollup/rollup-win32-ia32-msvc@4.52.5': + resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} + cpu: [ia32] + os: [win32] + '@rollup/rollup-win32-x64-gnu@4.52.5': + resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.52.5': + resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/cookie@0.6.0': @@ -243,28 +365,28 @@ packages: resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} '@types/statuses@2.0.6': resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - '@vitest/expect@3.2.6': - resolution: {integrity: sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==} - '@vitest/mocker@3.2.6': - resolution: {integrity: sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw==} + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} peerDependencies: msw: ^2.4.9 - vite: '>=7.3.5' + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@3.2.6': - resolution: {integrity: sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==} - '@vitest/runner@3.2.6': - resolution: {integrity: sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q==} - '@vitest/snapshot@3.2.6': - resolution: {integrity: sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw==} - '@vitest/spy@3.2.6': - resolution: {integrity: sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==} - '@vitest/utils@3.2.6': - resolution: {integrity: sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} '@webassemblyjs/floating-point-hex-parser@1.13.2': @@ -386,9 +508,6 @@ packages: deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} electron-to-chromium@1.5.238: resolution: {integrity: sha512-khBdc+w/Gv+cS8e/Pbnaw/FXcBUeKrRVik9IxfXtgREOWyJhR4tj43n3amkVogJ/yeQUqzkrZcFhtIxIdqmmcQ==} emoji-regex@8.0.0: @@ -398,6 +517,10 @@ packages: engines: {node: '>=10.13.0'} es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + esbuild@0.25.11: + resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} + engines: {node: '>=18'} + hasBin: true escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -423,8 +546,8 @@ packages: engines: {node: '>=12.0.0'} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-uri@4.1.0: - resolution: {integrity: sha512-ZodJ2cRiLVWGi9IgPb3mbgSqM4CD3LexCHkuv0FfBXHJI1ADfucTD06m6clO2Cy5RZYsw/SiCVl/dyrFI/SYWA==} + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -476,64 +599,6 @@ packages: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} loader-runner@4.3.1: resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} @@ -566,8 +631,8 @@ packages: mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} - nanoid@3.3.15: - resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true neo-async@2.6.2: @@ -591,20 +656,19 @@ packages: picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} - picomatch@4.0.5: - resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} - engines: {node: '>=12'} - playwright-core@1.60.0: - resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} + playwright-core@1.61.1: + resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==} engines: {node: '>=18'} hasBin: true - playwright@1.60.0: - resolution: {integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==} + playwright@1.61.1: + resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==} engines: {node: '>=18'} hasBin: true - postcss@8.5.16: - resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -613,10 +677,12 @@ packages: engines: {node: '>=0.10.0'} rettime@0.7.0: resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} - rolldown@1.1.4: - resolution: {integrity: sha512-IjZYiLxZwpnhwhdBH2ugdTGVSdhCQUmLxLoqyjiL0JxYjyRst+5a0P3xfrTxJ5F638j4Mvvw5FAX5XE6eHpXbA==} - engines: {node: ^20.19.0 || >=22.12.0} + rollup@4.52.5: + resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} schema-utils@4.3.3: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} @@ -624,9 +690,8 @@ packages: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true - serialize-javascript@7.0.7: - resolution: {integrity: sha512-YAy8Od6KV+uuwUuU50np8fGB/Aues6Y0nAhA9y/hId74PlKUcme4pXcBD46NWKr1Q4osN/iseZ17YqO1XfmI8g==} - engines: {node: '>=20.0.0'} + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} signal-exit@4.1.0: @@ -695,9 +760,6 @@ packages: tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} tinypool@1.1.1: resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -724,8 +786,6 @@ packages: peerDependencies: typescript: '*' webpack: ^5.0.0 - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} type-fest@4.41.0: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} @@ -744,16 +804,15 @@ packages: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@8.1.3: - resolution: {integrity: sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==} + vite@7.1.11: + resolution: {integrity: sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.3.0 - esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 + lightningcss: ^1.21.0 sass: ^1.70.0 sass-embedded: ^1.70.0 stylus: '>=0.54.8' @@ -764,14 +823,12 @@ packages: peerDependenciesMeta: '@types/node': optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true jiti: optional: true less: optional: true + lightningcss: + optional: true sass: optional: true sass-embedded: @@ -786,16 +843,16 @@ packages: optional: true yaml: optional: true - vitest@3.2.6: - resolution: {integrity: sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw==} + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.6 - '@vitest/ui': 3.2.6 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -883,18 +940,57 @@ snapshots: '@bundled-es-modules/statuses@1.0.1': dependencies: statuses: 2.0.2 - '@emnapi/core@1.11.1': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 + '@esbuild/aix-ppc64@0.25.11': optional: true - '@emnapi/runtime@1.11.1': - dependencies: - tslib: 2.8.1 + '@esbuild/android-arm64@0.25.11': optional: true - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 + '@esbuild/android-arm@0.25.11': + optional: true + '@esbuild/android-x64@0.25.11': + optional: true + '@esbuild/darwin-arm64@0.25.11': + optional: true + '@esbuild/darwin-x64@0.25.11': + optional: true + '@esbuild/freebsd-arm64@0.25.11': + optional: true + '@esbuild/freebsd-x64@0.25.11': + optional: true + '@esbuild/linux-arm64@0.25.11': + optional: true + '@esbuild/linux-arm@0.25.11': + optional: true + '@esbuild/linux-ia32@0.25.11': + optional: true + '@esbuild/linux-loong64@0.25.11': + optional: true + '@esbuild/linux-mips64el@0.25.11': + optional: true + '@esbuild/linux-ppc64@0.25.11': + optional: true + '@esbuild/linux-riscv64@0.25.11': + optional: true + '@esbuild/linux-s390x@0.25.11': + optional: true + '@esbuild/linux-x64@0.25.11': + optional: true + '@esbuild/netbsd-arm64@0.25.11': + optional: true + '@esbuild/netbsd-x64@0.25.11': + optional: true + '@esbuild/openbsd-arm64@0.25.11': + optional: true + '@esbuild/openbsd-x64@0.25.11': + optional: true + '@esbuild/openharmony-arm64@0.25.11': + optional: true + '@esbuild/sunos-x64@0.25.11': + optional: true + '@esbuild/win32-arm64@0.25.11': + optional: true + '@esbuild/win32-ia32@0.25.11': + optional: true + '@esbuild/win32-x64@0.25.11': optional: true '@inquirer/ansi@1.0.1': {} '@inquirer/confirm@5.1.19(@types/node@18.19.130)': @@ -941,57 +1037,55 @@ snapshots: is-node-process: 1.2.0 outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@tybys/wasm-util': 0.10.3 - optional: true '@open-draft/deferred-promise@2.2.0': {} '@open-draft/logger@0.3.0': dependencies: is-node-process: 1.2.0 outvariant: 1.4.3 '@open-draft/until@2.1.0': {} - '@oxc-project/types@0.138.0': {} - '@rolldown/binding-android-arm64@1.1.4': + '@rollup/rollup-android-arm-eabi@4.52.5': optional: true - '@rolldown/binding-darwin-arm64@1.1.4': + '@rollup/rollup-android-arm64@4.52.5': optional: true - '@rolldown/binding-darwin-x64@1.1.4': + '@rollup/rollup-darwin-arm64@4.52.5': optional: true - '@rolldown/binding-freebsd-x64@1.1.4': + '@rollup/rollup-darwin-x64@4.52.5': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.1.4': + '@rollup/rollup-freebsd-arm64@4.52.5': optional: true - '@rolldown/binding-linux-arm64-gnu@1.1.4': + '@rollup/rollup-freebsd-x64@4.52.5': optional: true - '@rolldown/binding-linux-arm64-musl@1.1.4': + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.1.4': + '@rollup/rollup-linux-arm-musleabihf@4.52.5': optional: true - '@rolldown/binding-linux-s390x-gnu@1.1.4': + '@rollup/rollup-linux-arm64-gnu@4.52.5': optional: true - '@rolldown/binding-linux-x64-gnu@1.1.4': + '@rollup/rollup-linux-arm64-musl@4.52.5': optional: true - '@rolldown/binding-linux-x64-musl@1.1.4': + '@rollup/rollup-linux-loong64-gnu@4.52.5': optional: true - '@rolldown/binding-openharmony-arm64@1.1.4': + '@rollup/rollup-linux-ppc64-gnu@4.52.5': optional: true - '@rolldown/binding-wasm32-wasi@1.1.4': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + '@rollup/rollup-linux-riscv64-gnu@4.52.5': optional: true - '@rolldown/binding-win32-arm64-msvc@1.1.4': + '@rollup/rollup-linux-riscv64-musl@4.52.5': optional: true - '@rolldown/binding-win32-x64-msvc@1.1.4': + '@rollup/rollup-linux-s390x-gnu@4.52.5': optional: true - '@rolldown/pluginutils@1.0.1': {} - '@tybys/wasm-util@0.10.3': - dependencies: - tslib: 2.8.1 + '@rollup/rollup-linux-x64-gnu@4.52.5': + optional: true + '@rollup/rollup-linux-x64-musl@4.52.5': + optional: true + '@rollup/rollup-openharmony-arm64@4.52.5': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.52.5': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.52.5': + optional: true + '@rollup/rollup-win32-x64-gnu@4.52.5': + optional: true + '@rollup/rollup-win32-x64-msvc@4.52.5': optional: true '@types/chai@5.2.3': dependencies: @@ -1013,40 +1107,40 @@ snapshots: dependencies: undici-types: 5.26.5 '@types/statuses@2.0.6': {} - '@vitest/expect@3.2.6': + '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.3 - '@vitest/spy': 3.2.6 - '@vitest/utils': 3.2.6 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.6(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(vite@8.1.3(@types/node@18.19.130)(terser@5.44.0))': + '@vitest/mocker@3.2.4(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(vite@7.1.11(@types/node@18.19.130)(terser@5.44.0))': dependencies: - '@vitest/spy': 3.2.6 + '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: msw: 2.11.2(@types/node@18.19.130)(typescript@5.7.3) - vite: 8.1.3(@types/node@18.19.130)(terser@5.44.0) - '@vitest/pretty-format@3.2.6': + vite: 7.1.11(@types/node@18.19.130)(terser@5.44.0) + '@vitest/pretty-format@3.2.4': dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.2.6': + '@vitest/runner@3.2.4': dependencies: - '@vitest/utils': 3.2.6 + '@vitest/utils': 3.2.4 pathe: 2.0.3 strip-literal: 3.1.0 - '@vitest/snapshot@3.2.6': + '@vitest/snapshot@3.2.4': dependencies: - '@vitest/pretty-format': 3.2.6 + '@vitest/pretty-format': 3.2.4 magic-string: 0.30.19 pathe: 2.0.3 - '@vitest/spy@3.2.6': + '@vitest/spy@3.2.4': dependencies: tinyspy: 4.0.4 - '@vitest/utils@3.2.6': + '@vitest/utils@3.2.4': dependencies: - '@vitest/pretty-format': 3.2.6 + '@vitest/pretty-format': 3.2.4 loupe: 3.2.1 tinyrainbow: 2.0.0 '@webassemblyjs/ast@1.14.1': @@ -1126,7 +1220,7 @@ snapshots: ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 4.1.0 + fast-uri: 3.1.0 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 ansi-regex@5.0.1: {} @@ -1177,7 +1271,6 @@ snapshots: dependencies: ms: 2.1.3 deep-eql@5.0.2: {} - detect-libc@2.1.2: {} electron-to-chromium@1.5.238: {} emoji-regex@8.0.0: {} enhanced-resolve@5.18.3: @@ -1185,6 +1278,34 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.0 es-module-lexer@1.7.0: {} + esbuild@0.25.11: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.11 + '@esbuild/android-arm': 0.25.11 + '@esbuild/android-arm64': 0.25.11 + '@esbuild/android-x64': 0.25.11 + '@esbuild/darwin-arm64': 0.25.11 + '@esbuild/darwin-x64': 0.25.11 + '@esbuild/freebsd-arm64': 0.25.11 + '@esbuild/freebsd-x64': 0.25.11 + '@esbuild/linux-arm': 0.25.11 + '@esbuild/linux-arm64': 0.25.11 + '@esbuild/linux-ia32': 0.25.11 + '@esbuild/linux-loong64': 0.25.11 + '@esbuild/linux-mips64el': 0.25.11 + '@esbuild/linux-ppc64': 0.25.11 + '@esbuild/linux-riscv64': 0.25.11 + '@esbuild/linux-s390x': 0.25.11 + '@esbuild/linux-x64': 0.25.11 + '@esbuild/netbsd-arm64': 0.25.11 + '@esbuild/netbsd-x64': 0.25.11 + '@esbuild/openbsd-arm64': 0.25.11 + '@esbuild/openbsd-x64': 0.25.11 + '@esbuild/openharmony-arm64': 0.25.11 + '@esbuild/sunos-x64': 0.25.11 + '@esbuild/win32-arm64': 0.25.11 + '@esbuild/win32-ia32': 0.25.11 + '@esbuild/win32-x64': 0.25.11 escalade@3.2.0: {} eslint-scope@5.1.1: dependencies: @@ -1201,13 +1322,10 @@ snapshots: events@3.3.0: {} expect-type@1.2.2: {} fast-deep-equal@3.1.3: {} - fast-uri@4.1.0: {} + fast-uri@3.1.0: {} fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 - fdir@6.5.0(picomatch@4.0.5): - optionalDependencies: - picomatch: 4.0.5 fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -1232,43 +1350,6 @@ snapshots: js-tokens@9.0.1: {} json-parse-even-better-errors@2.3.1: {} json-schema-traverse@1.0.0: {} - lightningcss-android-arm64@1.32.0: - optional: true - lightningcss-darwin-arm64@1.32.0: - optional: true - lightningcss-darwin-x64@1.32.0: - optional: true - lightningcss-freebsd-x64@1.32.0: - optional: true - lightningcss-linux-arm-gnueabihf@1.32.0: - optional: true - lightningcss-linux-arm64-gnu@1.32.0: - optional: true - lightningcss-linux-arm64-musl@1.32.0: - optional: true - lightningcss-linux-x64-gnu@1.32.0: - optional: true - lightningcss-linux-x64-musl@1.32.0: - optional: true - lightningcss-win32-arm64-msvc@1.32.0: - optional: true - lightningcss-win32-x64-msvc@1.32.0: - optional: true - lightningcss@1.32.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 loader-runner@4.3.1: {} loupe@3.2.1: {} magic-string@0.30.19: @@ -1310,7 +1391,7 @@ snapshots: transitivePeerDependencies: - '@types/node' mute-stream@2.0.0: {} - nanoid@3.3.15: {} + nanoid@3.3.11: {} neo-async@2.6.2: {} node-releases@2.0.26: {} outvariant@1.4.3: {} @@ -1320,41 +1401,51 @@ snapshots: picocolors@1.1.1: {} picomatch@2.3.1: {} picomatch@4.0.3: {} - picomatch@4.0.5: {} - playwright-core@1.60.0: {} - playwright@1.60.0: + playwright-core@1.61.1: {} + playwright@1.61.1: dependencies: - playwright-core: 1.60.0 + playwright-core: 1.61.1 optionalDependencies: fsevents: 2.3.2 - postcss@8.5.16: + postcss@8.5.6: dependencies: - nanoid: 3.3.15 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 require-directory@2.1.1: {} require-from-string@2.0.2: {} rettime@0.7.0: {} - rolldown@1.1.4: + rollup@4.52.5: dependencies: - '@oxc-project/types': 0.138.0 - '@rolldown/pluginutils': 1.0.1 + '@types/estree': 1.0.8 optionalDependencies: - '@rolldown/binding-android-arm64': 1.1.4 - '@rolldown/binding-darwin-arm64': 1.1.4 - '@rolldown/binding-darwin-x64': 1.1.4 - '@rolldown/binding-freebsd-x64': 1.1.4 - '@rolldown/binding-linux-arm-gnueabihf': 1.1.4 - '@rolldown/binding-linux-arm64-gnu': 1.1.4 - '@rolldown/binding-linux-arm64-musl': 1.1.4 - '@rolldown/binding-linux-ppc64-gnu': 1.1.4 - '@rolldown/binding-linux-s390x-gnu': 1.1.4 - '@rolldown/binding-linux-x64-gnu': 1.1.4 - '@rolldown/binding-linux-x64-musl': 1.1.4 - '@rolldown/binding-openharmony-arm64': 1.1.4 - '@rolldown/binding-wasm32-wasi': 1.1.4 - '@rolldown/binding-win32-arm64-msvc': 1.1.4 - '@rolldown/binding-win32-x64-msvc': 1.1.4 + '@rollup/rollup-android-arm-eabi': 4.52.5 + '@rollup/rollup-android-arm64': 4.52.5 + '@rollup/rollup-darwin-arm64': 4.52.5 + '@rollup/rollup-darwin-x64': 4.52.5 + '@rollup/rollup-freebsd-arm64': 4.52.5 + '@rollup/rollup-freebsd-x64': 4.52.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 + '@rollup/rollup-linux-arm-musleabihf': 4.52.5 + '@rollup/rollup-linux-arm64-gnu': 4.52.5 + '@rollup/rollup-linux-arm64-musl': 4.52.5 + '@rollup/rollup-linux-loong64-gnu': 4.52.5 + '@rollup/rollup-linux-ppc64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-musl': 4.52.5 + '@rollup/rollup-linux-s390x-gnu': 4.52.5 + '@rollup/rollup-linux-x64-gnu': 4.52.5 + '@rollup/rollup-linux-x64-musl': 4.52.5 + '@rollup/rollup-openharmony-arm64': 4.52.5 + '@rollup/rollup-win32-arm64-msvc': 4.52.5 + '@rollup/rollup-win32-ia32-msvc': 4.52.5 + '@rollup/rollup-win32-x64-gnu': 4.52.5 + '@rollup/rollup-win32-x64-msvc': 4.52.5 + fsevents: 2.3.3 + safe-buffer@5.2.1: {} schema-utils@4.3.3: dependencies: '@types/json-schema': 7.0.15 @@ -1362,7 +1453,9 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1) semver@7.7.3: {} - serialize-javascript@7.0.7: {} + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 siginfo@2.0.0: {} signal-exit@4.1.0: {} source-map-js@1.2.1: {} @@ -1399,7 +1492,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - serialize-javascript: 7.0.7 + serialize-javascript: 6.0.2 terser: 5.44.0 webpack: 5.102.1 terser@5.44.0: @@ -1414,10 +1507,6 @@ snapshots: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - tinyglobby@0.2.17: - dependencies: - fdir: 6.5.0(picomatch@4.0.5) - picomatch: 4.0.5 tinypool@1.1.1: {} tinyrainbow@2.0.0: {} tinyspy@4.0.4: {} @@ -1440,8 +1529,6 @@ snapshots: source-map: 0.7.6 typescript: 5.7.3 webpack: 5.102.1 - tslib@2.8.1: - optional: true type-fest@4.41.0: {} typescript@5.7.3: {} undici-types@5.26.5: {} @@ -1456,13 +1543,12 @@ snapshots: debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 8.1.3(@types/node@18.19.130)(terser@5.44.0) + vite: 7.1.11(@types/node@18.19.130)(terser@5.44.0) transitivePeerDependencies: - '@types/node' - - '@vitejs/devtools' - - esbuild - jiti - less + - lightningcss - sass - sass-embedded - stylus @@ -1471,27 +1557,28 @@ snapshots: - terser - tsx - yaml - vite@8.1.3(@types/node@18.19.130)(terser@5.44.0): + vite@7.1.11(@types/node@18.19.130)(terser@5.44.0): dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.5 - postcss: 8.5.16 - rolldown: 1.1.4 - tinyglobby: 0.2.17 + esbuild: 0.25.11 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.52.5 + tinyglobby: 0.2.15 optionalDependencies: '@types/node': 18.19.130 fsevents: 2.3.3 terser: 5.44.0 - vitest@3.2.6(@types/node@18.19.130)(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(terser@5.44.0): + vitest@3.2.4(@types/node@18.19.130)(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(terser@5.44.0): dependencies: '@types/chai': 5.2.3 - '@vitest/expect': 3.2.6 - '@vitest/mocker': 3.2.6(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(vite@8.1.3(@types/node@18.19.130)(terser@5.44.0)) - '@vitest/pretty-format': 3.2.6 - '@vitest/runner': 3.2.6 - '@vitest/snapshot': 3.2.6 - '@vitest/spy': 3.2.6 - '@vitest/utils': 3.2.6 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(vite@7.1.11(@types/node@18.19.130)(terser@5.44.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 chai: 5.3.3 debug: 4.4.3 expect-type: 1.2.2 @@ -1504,16 +1591,15 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 8.1.3(@types/node@18.19.130)(terser@5.44.0) + vite: 7.1.11(@types/node@18.19.130)(terser@5.44.0) vite-node: 3.2.4(@types/node@18.19.130)(terser@5.44.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 18.19.130 transitivePeerDependencies: - - '@vitejs/devtools' - - esbuild - jiti - less + - lightningcss - msw - sass - sass-embedded diff --git a/skyvern-ts/client/reference.md b/skyvern-ts/client/reference.md index 28e50443b..d5f6f5b23 100644 --- a/skyvern-ts/client/reference.md +++ b/skyvern-ts/client/reference.md @@ -1,5 +1,5 @@ # Reference -
client.runSdkAction({ ...params }) -> Skyvern.RunSdkActionResponse +
client.getWorkflowVersions(workflowPermanentId, { ...params }) -> Skyvern.Workflow[]
@@ -11,7 +11,7 @@
-Execute a single SDK action with the specified parameters +Get all versions of a workflow by its permanent ID.
@@ -26,11 +26,8 @@ Execute a single SDK action with the specified parameters
```typescript -await client.runSdkAction({ - url: "url", - action: { - type: "ai_act" - } +await client.getWorkflowVersions("workflow_permanent_id", { + template: true }); ``` @@ -47,7 +44,15 @@ await client.runSdkAction({
-**request:** `Skyvern.RunSdkActionRequest` +**workflowPermanentId:** `string` + +
+
+ +
+
+ +**request:** `Skyvern.GetWorkflowVersionsRequest`
@@ -128,126 +133,6 @@ await client.artifacts.getArtifactContent("artifact_id");
- - -
- -## Server -
client.server.getVersion() -> Record<string, string> -
-
- -#### 📝 Description - -
-
- -
-
- -Returns the current Skyvern server version (git SHA for official builds). -
-
-
-
- -#### 🔌 Usage - -
-
- -
-
- -```typescript -await client.server.getVersion(); - -``` -
-
-
-
- -#### ⚙️ Parameters - -
-
- -
-
- -**requestOptions:** `Server.RequestOptions` - -
-
-
-
- - -
-
-
- -## Workflows -
client.workflows.resetWorkflowBrowserProfile(workflowPermanentId) -> void -
-
- -#### 📝 Description - -
-
- -
-
- -Clear the persisted browser profile for a workflow that uses `Save & Reuse Session`. The next run will start from a fresh browser state. Use when a saved profile is corrupted. -
-
-
-
- -#### 🔌 Usage - -
-
- -
-
- -```typescript -await client.workflows.resetWorkflowBrowserProfile("wpid_123"); - -``` -
-
-
-
- -#### ⚙️ Parameters - -
-
- -
-
- -**workflowPermanentId:** `string` — The permanent ID of the workflow. Starts with `wpid_`. - -
-
- -
-
- -**requestOptions:** `Workflows.RequestOptions` - -
-
-
-
- -
@@ -772,6 +657,70 @@ await client.schedules.disable("workflow_permanent_id", "workflow_schedule_id"); + + +
+ +## Agents +
client.agents.resetWorkflowBrowserProfile(workflowPermanentId) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Clear the persisted browser profile for a workflow that uses `Save & Reuse Session`. The next run will start from a fresh browser state. Use when a saved profile is corrupted. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.resetWorkflowBrowserProfile("wpid_123"); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**workflowPermanentId:** `string` — The permanent ID of the workflow. Starts with `wpid_`. + +
+
+ +
+
+ +**requestOptions:** `Agents.RequestOptions` + +
+
+
+
+ +
diff --git a/skyvern-ts/client/src/Client.ts b/skyvern-ts/client/src/Client.ts index 9e1905fba..02a008868 100644 --- a/skyvern-ts/client/src/Client.ts +++ b/skyvern-ts/client/src/Client.ts @@ -1,11 +1,10 @@ // This file was auto-generated by Fern from our API Definition. import * as Skyvern from "./api/index.js"; +import { Agents } from "./api/resources/agents/client/Client.js"; import { Artifacts } from "./api/resources/artifacts/client/Client.js"; import { Schedules } from "./api/resources/schedules/client/Client.js"; import { Scripts } from "./api/resources/scripts/client/Client.js"; -import { Server } from "./api/resources/server/client/Client.js"; -import { Workflows } from "./api/resources/workflows/client/Client.js"; import type { BaseClientOptions, BaseRequestOptions } from "./BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "./core/headers.js"; import * as core from "./core/index.js"; @@ -21,10 +20,9 @@ export declare namespace SkyvernClient { export class SkyvernClient { protected readonly _options: SkyvernClient.Options; protected _artifacts: Artifacts | undefined; - protected _server: Server | undefined; - protected _workflows: Workflows | undefined; protected _scripts: Scripts | undefined; protected _schedules: Schedules | undefined; + protected _agents: Agents | undefined; constructor(_options: SkyvernClient.Options = {}) { this._options = { @@ -34,8 +32,8 @@ export class SkyvernClient { "x-api-key": _options?.apiKey, "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "@skyvern/client", - "X-Fern-SDK-Version": "1.0.37", - "User-Agent": "@skyvern/client/1.0.37", + "X-Fern-SDK-Version": "1.0.45", + "User-Agent": "@skyvern/client/1.0.45", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, }, @@ -48,14 +46,6 @@ export class SkyvernClient { return (this._artifacts ??= new Artifacts(this._options)); } - public get server(): Server { - return (this._server ??= new Server(this._options)); - } - - public get workflows(): Workflows { - return (this._workflows ??= new Workflows(this._options)); - } - public get scripts(): Scripts { return (this._scripts ??= new Scripts(this._options)); } @@ -64,6 +54,10 @@ export class SkyvernClient { return (this._schedules ??= new Schedules(this._options)); } + public get agents(): Agents { + return (this._agents ??= new Agents(this._options)); + } + /** * Run a task * @@ -153,7 +147,7 @@ export class SkyvernClient { } /** - * Run a workflow + * Run an agent * * @param {Skyvern.WorkflowRunRequestInput} request * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. @@ -166,7 +160,7 @@ export class SkyvernClient { * "x-max-steps-override": 1, * "x-user-agent": "x-user-agent", * template: true, - * workflow_id: "wpid_123" + * agent_id: "wpid_123" * }) */ public runWorkflow( @@ -200,7 +194,7 @@ export class SkyvernClient { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - "v1/run/workflows", + "v1/run/agents", ), method: "POST", headers: _headers, @@ -239,7 +233,7 @@ export class SkyvernClient { rawResponse: _response.rawResponse, }); case "timeout": - throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/run/workflows."); + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/run/agents."); case "unknown": throw new errors.SkyvernError({ message: _response.error.errorMessage, @@ -527,6 +521,7 @@ export class SkyvernClient { title, folder_id: folderId, status, + tags, template, } = request; const _queryParams: Record = {}; @@ -570,6 +565,14 @@ export class SkyvernClient { } } + if (tags != null) { + if (Array.isArray(tags)) { + _queryParams.tags = tags.map((item) => item); + } else { + _queryParams.tags = tags; + } + } + if (template != null) { _queryParams.template = template.toString(); } @@ -584,7 +587,7 @@ export class SkyvernClient { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - "v1/workflows", + "v1/agents", ), method: "GET", headers: _headers, @@ -618,7 +621,7 @@ export class SkyvernClient { rawResponse: _response.rawResponse, }); case "timeout": - throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/workflows."); + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/agents."); case "unknown": throw new errors.SkyvernError({ message: _response.error.errorMessage, @@ -628,7 +631,7 @@ export class SkyvernClient { } /** - * Create a new workflow + * Create a new agent * * @param {Skyvern.CreateWorkflowRequest} request * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. @@ -668,7 +671,7 @@ export class SkyvernClient { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - "v1/workflows", + "v1/agents", ), method: "POST", headers: _headers, @@ -705,7 +708,7 @@ export class SkyvernClient { rawResponse: _response.rawResponse, }); case "timeout": - throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/workflows."); + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/agents."); case "unknown": throw new errors.SkyvernError({ message: _response.error.errorMessage, @@ -715,9 +718,9 @@ export class SkyvernClient { } /** - * Update a workflow + * Update an agent * - * @param {string} workflowId - The ID of the workflow to update. Workflow ID starts with `wpid_`. + * @param {string} workflowId - The ID of the agent to update. Starts with `wpid_`. * @param {Skyvern.WorkflowRequest} request * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. * @@ -749,7 +752,7 @@ export class SkyvernClient { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowId)}`, + `v1/agents/${core.url.encodePathParam(workflowId)}`, ), method: "POST", headers: _headers, @@ -786,7 +789,7 @@ export class SkyvernClient { rawResponse: _response.rawResponse, }); case "timeout": - throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/workflows/{workflow_id}."); + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/agents/{workflow_id}."); case "unknown": throw new errors.SkyvernError({ message: _response.error.errorMessage, @@ -796,9 +799,9 @@ export class SkyvernClient { } /** - * Delete a workflow + * Delete an agent * - * @param {string} workflowId - The ID of the workflow to delete. Workflow ID starts with `wpid_`. + * @param {string} workflowId - The ID of the agent to delete. Starts with `wpid_`. * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Skyvern.UnprocessableEntityError} @@ -827,7 +830,7 @@ export class SkyvernClient { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowId)}/delete`, + `v1/agents/${core.url.encodePathParam(workflowId)}/delete`, ), method: "POST", headers: _headers, @@ -862,7 +865,7 @@ export class SkyvernClient { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling POST /v1/workflows/{workflow_id}/delete.", + "Timeout exceeded when calling POST /v1/agents/{workflow_id}/delete.", ); case "unknown": throw new errors.SkyvernError({ @@ -1300,34 +1303,22 @@ export class SkyvernClient { } /** - * Update a workflow's folder assignment for the latest version + * List all tag keys registered for the organization with their descriptions. * - * @param {string} workflowPermanentId - Workflow permanent ID - * @param {Skyvern.UpdateWorkflowFolderRequest} request * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. * - * @throws {@link Skyvern.BadRequestError} - * @throws {@link Skyvern.NotFoundError} * @throws {@link Skyvern.UnprocessableEntityError} * * @example - * await client.updateWorkflowFolder("wpid_123") + * await client.listTagKeys() */ - public updateWorkflowFolder( - workflowPermanentId: string, - request: Skyvern.UpdateWorkflowFolderRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise( - this.__updateWorkflowFolder(workflowPermanentId, request, requestOptions), - ); + public listTagKeys(requestOptions?: SkyvernClient.RequestOptions): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__listTagKeys(requestOptions)); } - private async __updateWorkflowFolder( - workflowPermanentId: string, - request: Skyvern.UpdateWorkflowFolderRequest = {}, + private async __listTagKeys( requestOptions?: SkyvernClient.RequestOptions, - ): Promise> { + ): Promise> { const _headers: core.Fetcher.Args["headers"] = mergeHeaders( this._options?.headers, mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), @@ -1338,26 +1329,97 @@ export class SkyvernClient { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/folder`, + "v1/tag-keys", ), - method: "PUT", + method: "GET", headers: _headers, - contentType: "application/json", queryParameters: requestOptions?.queryParams, - requestType: "json", - body: request, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, }); if (_response.ok) { - return { data: _response.body as Skyvern.Workflow, rawResponse: _response.rawResponse }; + return { data: _response.body as Skyvern.TagKey[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/tag-keys."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Delete a tag key from the organization registry and remove that tag from every workflow that currently has it (cascade). Returns how many workflows the tag was removed from. + * + * @param {string} key - Tag key to delete + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.deleteTagKey("env") + */ + public deleteTagKey( + key: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__deleteTagKey(key, requestOptions)); + } + + private async __deleteTagKey( + key: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/tag-keys/${core.url.encodePathParam(key)}`, + ), + method: "DELETE", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.TagKeyDeleteResponse, rawResponse: _response.rawResponse }; } if (_response.error.reason === "status-code") { switch (_response.error.statusCode) { - case 400: - throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); case 404: throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); case 422: @@ -1379,9 +1441,258 @@ export class SkyvernClient { rawResponse: _response.rawResponse, }); case "timeout": - throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling PUT /v1/workflows/{workflow_permanent_id}/folder.", - ); + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling DELETE /v1/tag-keys/{key}."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Update the description for a tag key. + * + * @param {string} key - Tag key to update + * @param {Skyvern.TagKeyUpdate} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.updateTagKey("key") + */ + public updateTagKey( + key: string, + request: Skyvern.TagKeyUpdate = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__updateTagKey(key, request, requestOptions)); + } + + private async __updateTagKey( + key: string, + request: Skyvern.TagKeyUpdate = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/tag-keys/${core.url.encodePathParam(key)}`, + ), + method: "PATCH", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.TagKey, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling PATCH /v1/tag-keys/{key}."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Batch fetch current tags for many workflows. Avoids N+1 on the workflows-list page. + * + * @param {Skyvern.BatchGetWorkflowTagsRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.BadRequestError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.batchGetWorkflowTags({ + * workflow_permanent_ids: "workflow_permanent_ids" + * }) + */ + public batchGetWorkflowTags( + request: Skyvern.BatchGetWorkflowTagsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__batchGetWorkflowTags(request, requestOptions)); + } + + private async __batchGetWorkflowTags( + request: Skyvern.BatchGetWorkflowTagsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { workflow_permanent_ids: workflowPermanentIds } = request; + const _queryParams: Record = {}; + if (workflowPermanentIds != null) { + _queryParams.workflow_permanent_ids = workflowPermanentIds; + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + "v1/workflow-tags", + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.WorkflowTagsBatchResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/workflow-tags."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Batch fetch current tags for many workflows (POST variant for id lists exceeding URL length). + * + * @param {Skyvern.WorkflowTagsBatchRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.BadRequestError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.batchGetWorkflowTagsPost() + */ + public batchGetWorkflowTagsPost( + request: Skyvern.WorkflowTagsBatchRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__batchGetWorkflowTagsPost(request, requestOptions)); + } + + private async __batchGetWorkflowTagsPost( + request: Skyvern.WorkflowTagsBatchRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + "v1/workflow-tags", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.WorkflowTagsBatchResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/workflow-tags."); case "unknown": throw new errors.SkyvernError({ message: _response.error.errorMessage, @@ -1643,43 +1954,23 @@ export class SkyvernClient { } /** - * Retry a workflow run using the original run parameters. + * Returns the current Skyvern server version (git SHA for official builds). * - * @param {string} workflowRunId - The id of the workflow run to retry. - * @param {Skyvern.RetryWorkflowRunRequest} request * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. * - * @throws {@link Skyvern.BadRequestError} - * @throws {@link Skyvern.NotFoundError} - * @throws {@link Skyvern.UnprocessableEntityError} - * * @example - * await client.retryWorkflowRun("wr_123", { - * "x-max-steps-override": 1, - * "x-user-agent": "x-user-agent" - * }) + * await client.getVersion() */ - public retryWorkflowRun( - workflowRunId: string, - request: Skyvern.RetryWorkflowRunRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__retryWorkflowRun(workflowRunId, request, requestOptions)); + public getVersion(requestOptions?: SkyvernClient.RequestOptions): core.HttpResponsePromise> { + return core.HttpResponsePromise.fromPromise(this.__getVersion(requestOptions)); } - private async __retryWorkflowRun( - workflowRunId: string, - request: Skyvern.RetryWorkflowRunRequest = {}, + private async __getVersion( requestOptions?: SkyvernClient.RequestOptions, - ): Promise> { - const { "x-max-steps-override": maxStepsOverride, "x-user-agent": userAgent } = request; + ): Promise>> { const _headers: core.Fetcher.Args["headers"] = mergeHeaders( this._options?.headers, - mergeOnlyDefinedHeaders({ - "x-max-steps-override": maxStepsOverride != null ? maxStepsOverride.toString() : undefined, - "x-user-agent": userAgent != null ? userAgent : undefined, - "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, - }), + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), requestOptions?.headers, ); const _response = await core.fetcher({ @@ -1687,9 +1978,9 @@ export class SkyvernClient { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/runs/${core.url.encodePathParam(workflowRunId)}/retry`, + "v1/version", ), - method: "POST", + method: "GET", headers: _headers, queryParameters: requestOptions?.queryParams, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, @@ -1697,24 +1988,15 @@ export class SkyvernClient { abortSignal: requestOptions?.abortSignal, }); if (_response.ok) { - return { data: _response.body as Skyvern.WorkflowRunResponse, rawResponse: _response.rawResponse }; + return { data: _response.body as Record, rawResponse: _response.rawResponse }; } if (_response.error.reason === "status-code") { - switch (_response.error.statusCode) { - case 400: - throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); - case 404: - throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); - case 422: - throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); - default: - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); - } + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); } switch (_response.error.reason) { @@ -1725,9 +2007,7 @@ export class SkyvernClient { rawResponse: _response.rawResponse, }); case "timeout": - throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling POST /v1/workflows/runs/{workflow_run_id}/retry.", - ); + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/version."); case "unknown": throw new errors.SkyvernError({ message: _response.error.errorMessage, @@ -1835,441 +2115,6 @@ export class SkyvernClient { } } - /** - * List workflow runs across all workflows for the current organization. - * - * Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. - * - * ### search_key - * - * A case-insensitive substring search that matches against **any** of the following fields: - * - * | Searched field | Description | - * |---|---| - * | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | - * | Parameter **key** | The `key` of any workflow parameter definition associated with the run | - * | Parameter **description** | The `description` of any workflow parameter definition | - * | Run parameter **value** | The actual value supplied for any parameter when the run was created | - * | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | - * - * Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. - * - * ### error_code - * - * An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). - * - * ### Combining filters - * - * All query parameters use AND logic: - * - `?status=failed` — only failed runs - * - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error - * - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match - * - * @param {Skyvern.GetWorkflowRunsRequest} request - * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @throws {@link Skyvern.UnprocessableEntityError} - * - * @example - * await client.getWorkflowRuns({ - * page: 1, - * page_size: 1, - * search_key: "search_key", - * error_code: "error_code" - * }) - */ - public getWorkflowRuns( - request: Skyvern.GetWorkflowRunsRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__getWorkflowRuns(request, requestOptions)); - } - - private async __getWorkflowRuns( - request: Skyvern.GetWorkflowRunsRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): Promise> { - const { page, page_size: pageSize, status, search_key: searchKey, error_code: errorCode } = request; - const _queryParams: Record = {}; - if (page != null) { - _queryParams.page = page.toString(); - } - - if (pageSize != null) { - _queryParams.page_size = pageSize.toString(); - } - - if (status != null) { - if (Array.isArray(status)) { - _queryParams.status = status.map((item) => item); - } else { - _queryParams.status = status; - } - } - - if (searchKey != null) { - _queryParams.search_key = searchKey; - } - - if (errorCode != null) { - _queryParams.error_code = errorCode; - } - - const _headers: core.Fetcher.Args["headers"] = mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), - requestOptions?.headers, - ); - const _response = await core.fetcher({ - url: core.url.join( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)) ?? - environments.SkyvernEnvironment.Cloud, - "v1/workflows/runs", - ), - method: "GET", - headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, - timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, - maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return { data: _response.body as Skyvern.WorkflowRun[], rawResponse: _response.rawResponse }; - } - - if (_response.error.reason === "status-code") { - switch (_response.error.statusCode) { - case 422: - throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); - default: - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); - } - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/workflows/runs."); - case "unknown": - throw new errors.SkyvernError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - /** - * List runs for a specific workflow. - * - * Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. - * - * ### search_key - * - * Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. - * - * ### error_code - * - * Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. - * - * @param {string} workflowId - * @param {Skyvern.GetWorkflowRunsByIdRequest} request - * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @throws {@link Skyvern.UnprocessableEntityError} - * - * @example - * await client.getWorkflowRunsById("workflow_id", { - * page: 1, - * page_size: 1, - * search_key: "search_key", - * error_code: "error_code" - * }) - */ - public getWorkflowRunsById( - workflowId: string, - request: Skyvern.GetWorkflowRunsByIdRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__getWorkflowRunsById(workflowId, request, requestOptions)); - } - - private async __getWorkflowRunsById( - workflowId: string, - request: Skyvern.GetWorkflowRunsByIdRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): Promise> { - const { page, page_size: pageSize, status, search_key: searchKey, error_code: errorCode } = request; - const _queryParams: Record = {}; - if (page != null) { - _queryParams.page = page.toString(); - } - - if (pageSize != null) { - _queryParams.page_size = pageSize.toString(); - } - - if (status != null) { - if (Array.isArray(status)) { - _queryParams.status = status.map((item) => item); - } else { - _queryParams.status = status; - } - } - - if (searchKey != null) { - _queryParams.search_key = searchKey; - } - - if (errorCode != null) { - _queryParams.error_code = errorCode; - } - - const _headers: core.Fetcher.Args["headers"] = mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), - requestOptions?.headers, - ); - const _response = await core.fetcher({ - url: core.url.join( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)) ?? - environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowId)}/runs`, - ), - method: "GET", - headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, - timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, - maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return { data: _response.body as Skyvern.WorkflowRun[], rawResponse: _response.rawResponse }; - } - - if (_response.error.reason === "status-code") { - switch (_response.error.statusCode) { - case 422: - throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); - default: - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); - } - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling GET /v1/workflows/{workflow_id}/runs.", - ); - case "unknown": - throw new errors.SkyvernError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - /** - * @param {string} workflowPermanentId - * @param {Skyvern.GetWorkflowRequest} request - * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @throws {@link Skyvern.UnprocessableEntityError} - * - * @example - * await client.getWorkflow("workflow_permanent_id", { - * version: 1, - * template: true - * }) - */ - public getWorkflow( - workflowPermanentId: string, - request: Skyvern.GetWorkflowRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__getWorkflow(workflowPermanentId, request, requestOptions)); - } - - private async __getWorkflow( - workflowPermanentId: string, - request: Skyvern.GetWorkflowRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): Promise> { - const { version, template } = request; - const _queryParams: Record = {}; - if (version != null) { - _queryParams.version = version.toString(); - } - - if (template != null) { - _queryParams.template = template.toString(); - } - - const _headers: core.Fetcher.Args["headers"] = mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), - requestOptions?.headers, - ); - const _response = await core.fetcher({ - url: core.url.join( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)) ?? - environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}`, - ), - method: "GET", - headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, - timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, - maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return { data: _response.body as Skyvern.Workflow, rawResponse: _response.rawResponse }; - } - - if (_response.error.reason === "status-code") { - switch (_response.error.statusCode) { - case 422: - throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); - default: - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); - } - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling GET /v1/workflows/{workflow_permanent_id}.", - ); - case "unknown": - throw new errors.SkyvernError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - /** - * Get all versions of a workflow by its permanent ID. - * - * @param {string} workflowPermanentId - * @param {Skyvern.GetWorkflowVersionsRequest} request - * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @throws {@link Skyvern.UnprocessableEntityError} - * - * @example - * await client.getWorkflowVersions("workflow_permanent_id", { - * template: true - * }) - */ - public getWorkflowVersions( - workflowPermanentId: string, - request: Skyvern.GetWorkflowVersionsRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise( - this.__getWorkflowVersions(workflowPermanentId, request, requestOptions), - ); - } - - private async __getWorkflowVersions( - workflowPermanentId: string, - request: Skyvern.GetWorkflowVersionsRequest = {}, - requestOptions?: SkyvernClient.RequestOptions, - ): Promise> { - const { template } = request; - const _queryParams: Record = {}; - if (template != null) { - _queryParams.template = template.toString(); - } - - const _headers: core.Fetcher.Args["headers"] = mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), - requestOptions?.headers, - ); - const _response = await core.fetcher({ - url: core.url.join( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)) ?? - environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/versions`, - ), - method: "GET", - headers: _headers, - queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, - timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, - maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return { data: _response.body as Skyvern.Workflow[], rawResponse: _response.rawResponse }; - } - - if (_response.error.reason === "status-code") { - switch (_response.error.statusCode) { - case 422: - throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); - default: - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); - } - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling GET /v1/workflows/{workflow_permanent_id}/versions.", - ); - case "unknown": - throw new errors.SkyvernError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - /** * @param {Skyvern.BodyUploadFileV1UploadFilePost} request * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. @@ -2454,7 +2299,7 @@ export class SkyvernClient { } /** - * Create a browser profile from a persistent browser session or workflow run. + * Create a blank browser profile, or create one from a persistent browser session or workflow run. * * @param {Skyvern.CreateBrowserProfileRequest} request * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. @@ -3110,6 +2955,102 @@ export class SkyvernClient { } } + /** + * Update a live browser session. Currently supports toggling generate_browser_profile, which is read when the session ends to decide whether to save its browser profile. + * + * @param {string} browserSessionId - The ID of the browser session. browser_session_id starts with `pbs_` + * @param {Skyvern.UpdateBrowserSessionRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.ForbiddenError} + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.ConflictError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.updateBrowserSession("pbs_123456", { + * generate_browser_profile: true + * }) + */ + public updateBrowserSession( + browserSessionId: string, + request: Skyvern.UpdateBrowserSessionRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise( + this.__updateBrowserSession(browserSessionId, request, requestOptions), + ); + } + + private async __updateBrowserSession( + browserSessionId: string, + request: Skyvern.UpdateBrowserSessionRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/browser_sessions/${core.url.encodePathParam(browserSessionId)}`, + ), + method: "PATCH", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.BrowserSessionResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 403: + throw new Skyvern.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 409: + throw new Skyvern.ConflictError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling PATCH /v1/browser_sessions/{browser_session_id}.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + /** * Forward a TOTP (2FA, MFA) email or sms message containing the code to Skyvern. This endpoint stores the code in database so that Skyvern can use it while running tasks/workflows. * @@ -3203,7 +3144,9 @@ export class SkyvernClient { * await client.getCredentials({ * page: 1, * page_size: 10, - * vault_type: "bitwarden" + * vault_type: "skyvern", + * credential_type: "password", + * search: "search" * }) */ public getCredentials( @@ -3217,7 +3160,7 @@ export class SkyvernClient { request: Skyvern.GetCredentialsRequest = {}, requestOptions?: SkyvernClient.RequestOptions, ): Promise> { - const { page, page_size: pageSize, vault_type: vaultType } = request; + const { page, page_size: pageSize, vault_type: vaultType, credential_type: credentialType, search } = request; const _queryParams: Record = {}; if (page != null) { _queryParams.page = page.toString(); @@ -3231,6 +3174,14 @@ export class SkyvernClient { _queryParams.vault_type = vaultType; } + if (credentialType != null) { + _queryParams.credential_type = credentialType; + } + + if (search != null) { + _queryParams.search = search; + } + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( this._options?.headers, mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), @@ -4196,4 +4147,978 @@ export class SkyvernClient { }); } } + + /** + * Update a workflow's folder assignment for the latest version + * + * @param {string} workflowPermanentId - Workflow permanent ID + * @param {Skyvern.UpdateWorkflowFolderRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.BadRequestError} + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.updateWorkflowFolder("wpid_123") + */ + public updateWorkflowFolder( + workflowPermanentId: string, + request: Skyvern.UpdateWorkflowFolderRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise( + this.__updateWorkflowFolder(workflowPermanentId, request, requestOptions), + ); + } + + private async __updateWorkflowFolder( + workflowPermanentId: string, + request: Skyvern.UpdateWorkflowFolderRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/folder`, + ), + method: "PUT", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Workflow, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling PUT /v1/agents/{workflow_permanent_id}/folder.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get the current tag state for a workflow. + * + * @param {string} workflowPermanentId - Workflow permanent ID + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getWorkflowTags("wpid_123") + */ + public getWorkflowTags( + workflowPermanentId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getWorkflowTags(workflowPermanentId, requestOptions)); + } + + private async __getWorkflowTags( + workflowPermanentId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/tags`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.TagsResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling GET /v1/agents/{workflow_permanent_id}/tags.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Atomically apply tag changes to a workflow. Sets and deletes happen in one transaction; same-key collisions resolve set-wins. + * + * @param {string} workflowPermanentId - Workflow permanent ID + * @param {Skyvern.TagApplyRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.applyWorkflowTags("wpid_123") + */ + public applyWorkflowTags( + workflowPermanentId: string, + request: Skyvern.TagApplyRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise( + this.__applyWorkflowTags(workflowPermanentId, request, requestOptions), + ); + } + + private async __applyWorkflowTags( + workflowPermanentId: string, + request: Skyvern.TagApplyRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/tags`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.TagsResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling POST /v1/agents/{workflow_permanent_id}/tags.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Soft-delete a single tag from a workflow. Writes a DELETE event row. + * + * @param {string} workflowPermanentId - Workflow permanent ID + * @param {string} key - Tag key to delete + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.deleteWorkflowTag("wpid_123", "env") + */ + public deleteWorkflowTag( + workflowPermanentId: string, + key: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__deleteWorkflowTag(workflowPermanentId, key, requestOptions)); + } + + private async __deleteWorkflowTag( + workflowPermanentId: string, + key: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/tags/${core.url.encodePathParam(key)}`, + ), + method: "DELETE", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.TagsResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling DELETE /v1/agents/{workflow_permanent_id}/tags/{key}.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Chronological tag-event log for a workflow (newest first). Includes SET and DELETE events. + * + * @param {string} workflowPermanentId - Workflow permanent ID + * @param {Skyvern.GetWorkflowTagHistoryRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getWorkflowTagHistory("wpid_123", { + * limit: 1, + * since: "2024-01-15T09:30:00Z", + * key: "key" + * }) + */ + public getWorkflowTagHistory( + workflowPermanentId: string, + request: Skyvern.GetWorkflowTagHistoryRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise( + this.__getWorkflowTagHistory(workflowPermanentId, request, requestOptions), + ); + } + + private async __getWorkflowTagHistory( + workflowPermanentId: string, + request: Skyvern.GetWorkflowTagHistoryRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { limit, since, key } = request; + const _queryParams: Record = {}; + if (limit != null) { + _queryParams.limit = limit.toString(); + } + + if (since != null) { + _queryParams.since = since; + } + + if (key != null) { + _queryParams.key = key; + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/tags/history`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.TagHistoryResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling GET /v1/agents/{workflow_permanent_id}/tags/history.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retry a workflow run using the original run parameters. + * + * @param {string} workflowRunId - The id of the workflow run to retry. + * @param {Skyvern.RetryWorkflowRunRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.BadRequestError} + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.retryWorkflowRun("wr_123", { + * "x-max-steps-override": 1, + * "x-user-agent": "x-user-agent" + * }) + */ + public retryWorkflowRun( + workflowRunId: string, + request: Skyvern.RetryWorkflowRunRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__retryWorkflowRun(workflowRunId, request, requestOptions)); + } + + private async __retryWorkflowRun( + workflowRunId: string, + request: Skyvern.RetryWorkflowRunRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { "x-max-steps-override": maxStepsOverride, "x-user-agent": userAgent } = request; + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-max-steps-override": maxStepsOverride != null ? maxStepsOverride.toString() : undefined, + "x-user-agent": userAgent != null ? userAgent : undefined, + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/runs/${core.url.encodePathParam(workflowRunId)}/retry`, + ), + method: "POST", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.WorkflowRunResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling POST /v1/agents/runs/{workflow_run_id}/retry.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * List workflow runs across all workflows for the current organization. + * + * Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. + * + * ### search_key + * + * A case-insensitive substring search that matches against **any** of the following fields: + * + * | Searched field | Description | + * |---|---| + * | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | + * | Parameter **key** | The `key` of any workflow parameter definition associated with the run | + * | Parameter **description** | The `description` of any workflow parameter definition | + * | Run parameter **value** | The actual value supplied for any parameter when the run was created | + * | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | + * + * Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. + * + * ### error_code + * + * An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). + * + * ### Combining filters + * + * All query parameters use AND logic: + * - `?status=failed` — only failed runs + * - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error + * - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match + * + * @param {Skyvern.GetWorkflowRunsRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getWorkflowRuns({ + * page: 1, + * page_size: 1, + * search_key: "search_key", + * error_code: "error_code" + * }) + */ + public getWorkflowRuns( + request: Skyvern.GetWorkflowRunsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getWorkflowRuns(request, requestOptions)); + } + + private async __getWorkflowRuns( + request: Skyvern.GetWorkflowRunsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { page, page_size: pageSize, status, search_key: searchKey, error_code: errorCode } = request; + const _queryParams: Record = {}; + if (page != null) { + _queryParams.page = page.toString(); + } + + if (pageSize != null) { + _queryParams.page_size = pageSize.toString(); + } + + if (status != null) { + if (Array.isArray(status)) { + _queryParams.status = status.map((item) => item); + } else { + _queryParams.status = status; + } + } + + if (searchKey != null) { + _queryParams.search_key = searchKey; + } + + if (errorCode != null) { + _queryParams.error_code = errorCode; + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + "v1/agents/runs", + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.WorkflowRun[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/agents/runs."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * List runs for a specific workflow. + * + * Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. + * + * ### search_key + * + * Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. + * + * ### error_code + * + * Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. + * + * @param {string} workflowId + * @param {Skyvern.GetWorkflowRunsByIdRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getWorkflowRunsById("workflow_id", { + * page: 1, + * page_size: 1, + * search_key: "search_key", + * error_code: "error_code" + * }) + */ + public getWorkflowRunsById( + workflowId: string, + request: Skyvern.GetWorkflowRunsByIdRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getWorkflowRunsById(workflowId, request, requestOptions)); + } + + private async __getWorkflowRunsById( + workflowId: string, + request: Skyvern.GetWorkflowRunsByIdRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { page, page_size: pageSize, status, search_key: searchKey, error_code: errorCode } = request; + const _queryParams: Record = {}; + if (page != null) { + _queryParams.page = page.toString(); + } + + if (pageSize != null) { + _queryParams.page_size = pageSize.toString(); + } + + if (status != null) { + if (Array.isArray(status)) { + _queryParams.status = status.map((item) => item); + } else { + _queryParams.status = status; + } + } + + if (searchKey != null) { + _queryParams.search_key = searchKey; + } + + if (errorCode != null) { + _queryParams.error_code = errorCode; + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/${core.url.encodePathParam(workflowId)}/runs`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.WorkflowRun[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling GET /v1/agents/{workflow_id}/runs.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * @param {string} workflowPermanentId + * @param {Skyvern.GetWorkflowRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getWorkflow("workflow_permanent_id", { + * version: 1, + * template: true + * }) + */ + public getWorkflow( + workflowPermanentId: string, + request: Skyvern.GetWorkflowRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getWorkflow(workflowPermanentId, request, requestOptions)); + } + + private async __getWorkflow( + workflowPermanentId: string, + request: Skyvern.GetWorkflowRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { version, template } = request; + const _queryParams: Record = {}; + if (version != null) { + _queryParams.version = version.toString(); + } + + if (template != null) { + _queryParams.template = template.toString(); + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Workflow, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling GET /v1/agents/{workflow_permanent_id}.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get all versions of a workflow by its permanent ID. + * + * @param {string} workflowPermanentId + * @param {Skyvern.GetWorkflowVersionsRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getWorkflowVersions("workflow_permanent_id", { + * template: true + * }) + */ + public getWorkflowVersions( + workflowPermanentId: string, + request: Skyvern.GetWorkflowVersionsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise( + this.__getWorkflowVersions(workflowPermanentId, request, requestOptions), + ); + } + + private async __getWorkflowVersions( + workflowPermanentId: string, + request: Skyvern.GetWorkflowVersionsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { template } = request; + const _queryParams: Record = {}; + if (template != null) { + _queryParams.template = template.toString(); + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.SkyvernEnvironment.Cloud, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/versions`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Workflow[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling GET /v1/agents/{workflow_permanent_id}/versions.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } } diff --git a/skyvern-ts/client/src/api/client/requests/BatchGetWorkflowTagsRequest.ts b/skyvern-ts/client/src/api/client/requests/BatchGetWorkflowTagsRequest.ts new file mode 100644 index 000000000..9e9dd58c3 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/BatchGetWorkflowTagsRequest.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * workflow_permanent_ids: "workflow_permanent_ids" + * } + */ +export interface BatchGetWorkflowTagsRequest { + /** Comma-separated workflow permanent IDs */ + workflow_permanent_ids?: string; +} diff --git a/skyvern-ts/client/src/api/client/requests/CreateBrowserProfileRequest.ts b/skyvern-ts/client/src/api/client/requests/CreateBrowserProfileRequest.ts index e45d2bb4b..ef5df6a3e 100644 --- a/skyvern-ts/client/src/api/client/requests/CreateBrowserProfileRequest.ts +++ b/skyvern-ts/client/src/api/client/requests/CreateBrowserProfileRequest.ts @@ -1,5 +1,7 @@ // This file was auto-generated by Fern from our API Definition. +import type * as Skyvern from "../../index.js"; + /** * @example * { @@ -11,8 +13,19 @@ export interface CreateBrowserProfileRequest { name: string; /** Optional profile description */ description?: string; - /** Persistent browser session to convert into a profile */ + /** Persistent browser session to convert into a profile. Omit for a blank profile. */ browser_session_id?: string; - /** Workflow run whose persisted session should be captured */ + /** Workflow run whose persisted session should be captured. Omit for a blank profile. */ workflow_run_id?: string; + /** Optional proxy location for this profile's pinned proxy identity. */ + proxy_location?: CreateBrowserProfileRequest.ProxyLocation; + /** Explicit sticky-session id for this profile's pinned proxy identity. */ + proxy_session_id?: string; +} + +export namespace CreateBrowserProfileRequest { + /** + * Optional proxy location for this profile's pinned proxy identity. + */ + export type ProxyLocation = Skyvern.ProxyLocation | Skyvern.GeoTarget | Record; } diff --git a/skyvern-ts/client/src/api/client/requests/CreateBrowserSessionRequest.ts b/skyvern-ts/client/src/api/client/requests/CreateBrowserSessionRequest.ts index 071dc3516..b2aa4f57a 100644 --- a/skyvern-ts/client/src/api/client/requests/CreateBrowserSessionRequest.ts +++ b/skyvern-ts/client/src/api/client/requests/CreateBrowserSessionRequest.ts @@ -52,6 +52,8 @@ export interface CreateBrowserSessionRequest { browser_type?: Skyvern.PersistentBrowserType; /** ID of a browser profile to load into this session (restores cookies, localStorage, etc.). browser_profile_id starts with `bp_`. */ browser_profile_id?: string; + /** When true, the session's browser profile (cookies, localStorage, etc.) is saved to storage when the session ends so it can be turned into a reusable browser profile. Defaults to false to avoid storing profiles for sessions that never need them. Sessions started with a browser_profile_id always persist their profile regardless of this flag. */ + generate_browser_profile?: boolean; } export namespace CreateBrowserSessionRequest { diff --git a/skyvern-ts/client/src/api/client/requests/GetCredentialsRequest.ts b/skyvern-ts/client/src/api/client/requests/GetCredentialsRequest.ts index 123c0050e..46b7bdbd9 100644 --- a/skyvern-ts/client/src/api/client/requests/GetCredentialsRequest.ts +++ b/skyvern-ts/client/src/api/client/requests/GetCredentialsRequest.ts @@ -7,7 +7,9 @@ import type * as Skyvern from "../../index.js"; * { * page: 1, * page_size: 10, - * vault_type: "bitwarden" + * vault_type: "skyvern", + * credential_type: "password", + * search: "search" * } */ export interface GetCredentialsRequest { @@ -17,4 +19,8 @@ export interface GetCredentialsRequest { page_size?: number; /** Filter credentials by vault type (e.g. 'skyvern', 'custom', 'bitwarden', 'azure_vault') */ vault_type?: Skyvern.CredentialVaultType; + /** Filter credentials by type (e.g. 'password', 'credit_card', 'secret') */ + credential_type?: Skyvern.SkyvernForgeSdkSchemasCredentialsCredentialType; + /** Case-insensitive search across credential name, username, secret label, and card details */ + search?: string; } diff --git a/skyvern-ts/client/src/api/client/requests/GetWorkflowTagHistoryRequest.ts b/skyvern-ts/client/src/api/client/requests/GetWorkflowTagHistoryRequest.ts new file mode 100644 index 000000000..a0c713d27 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/GetWorkflowTagHistoryRequest.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * limit: 1, + * since: "2024-01-15T09:30:00Z", + * key: "key" + * } + */ +export interface GetWorkflowTagHistoryRequest { + /** Max events to return */ + limit?: number; + /** Only return events at or after this timestamp */ + since?: string; + /** Filter to events for a single tag key */ + key?: string; +} diff --git a/skyvern-ts/client/src/api/client/requests/GetWorkflowsRequest.ts b/skyvern-ts/client/src/api/client/requests/GetWorkflowsRequest.ts index d59de276b..f570f59cf 100644 --- a/skyvern-ts/client/src/api/client/requests/GetWorkflowsRequest.ts +++ b/skyvern-ts/client/src/api/client/requests/GetWorkflowsRequest.ts @@ -29,5 +29,7 @@ export interface GetWorkflowsRequest { /** Filter workflows by folder ID */ folder_id?: string; status?: Skyvern.WorkflowStatus | Skyvern.WorkflowStatus[]; + /** Filter by tags. Each term is a label (`production`), a group (`env:*`), or a group:label (`env:prod`). Repeat the param or comma-separate (`?tags=env:prod,env:staging`). AND across distinct terms, OR within a group's labels (`?tags=customer:acme,env:prod,env:staging` -> customer=acme AND env in (prod, staging)). A label term matches the value across any/no group. Matches current tag values only. Not supported with `template=true`. */ + tags?: string | string[]; template?: boolean; } diff --git a/skyvern-ts/client/src/api/client/requests/TagApplyRequest.ts b/skyvern-ts/client/src/api/client/requests/TagApplyRequest.ts new file mode 100644 index 000000000..1c7146069 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/TagApplyRequest.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * {} + */ +export interface TagApplyRequest { + /** Tags to set (overwrite). List of {key?, value} objects. */ + tags?: Skyvern.TagInput[]; + /** Tags to soft-delete. List of {key?, value?} targets. */ + tags_to_delete?: Skyvern.TagDeleteInput[]; +} diff --git a/skyvern-ts/client/src/api/client/requests/TagKeyUpdate.ts b/skyvern-ts/client/src/api/client/requests/TagKeyUpdate.ts new file mode 100644 index 000000000..15340edc4 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/TagKeyUpdate.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * {} + */ +export interface TagKeyUpdate { + /** Free-form description (max 500 chars). Pass null to clear. */ + description?: string; +} diff --git a/skyvern-ts/client/src/api/client/requests/UpdateBrowserProfileRequest.ts b/skyvern-ts/client/src/api/client/requests/UpdateBrowserProfileRequest.ts index c07d5d55f..602399991 100644 --- a/skyvern-ts/client/src/api/client/requests/UpdateBrowserProfileRequest.ts +++ b/skyvern-ts/client/src/api/client/requests/UpdateBrowserProfileRequest.ts @@ -1,5 +1,7 @@ // This file was auto-generated by Fern from our API Definition. +import type * as Skyvern from "../../index.js"; + /** * @example * {} @@ -9,4 +11,17 @@ export interface UpdateBrowserProfileRequest { name?: string; /** New description for the browser profile */ description?: string; + /** Optional proxy location for this profile's pinned proxy identity. */ + proxy_location?: UpdateBrowserProfileRequest.ProxyLocation; + /** Opaque Skyvern-managed proxy sticky-session id. */ + proxy_session_id?: string; + /** Rotate the Skyvern-managed proxy sticky-session id for this profile. */ + rotate_proxy_session_id?: boolean; +} + +export namespace UpdateBrowserProfileRequest { + /** + * Optional proxy location for this profile's pinned proxy identity. + */ + export type ProxyLocation = Skyvern.ProxyLocation | Skyvern.GeoTarget | Record; } diff --git a/skyvern-ts/client/src/api/client/requests/UpdateBrowserSessionRequest.ts b/skyvern-ts/client/src/api/client/requests/UpdateBrowserSessionRequest.ts new file mode 100644 index 000000000..94051545b --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/UpdateBrowserSessionRequest.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * generate_browser_profile: true + * } + */ +export interface UpdateBrowserSessionRequest { + /** Enable or disable saving this session's browser profile when it ends. Can be toggled while the session is still alive; the value is read at session teardown. */ + generate_browser_profile: boolean; +} diff --git a/skyvern-ts/client/src/api/client/requests/WorkflowRunRequestInput.ts b/skyvern-ts/client/src/api/client/requests/WorkflowRunRequestInput.ts index c1e62cd84..0a16da1dc 100644 --- a/skyvern-ts/client/src/api/client/requests/WorkflowRunRequestInput.ts +++ b/skyvern-ts/client/src/api/client/requests/WorkflowRunRequestInput.ts @@ -8,15 +8,15 @@ import type * as Skyvern from "../../index.js"; * "x-max-steps-override": 1, * "x-user-agent": "x-user-agent", * template: true, - * workflow_id: "wpid_123" + * agent_id: "wpid_123" * } */ export interface WorkflowRunRequestInput { template?: boolean; "x-max-steps-override"?: number; "x-user-agent"?: string; - /** ID of the workflow to run. Workflow ID starts with `wpid_`. */ - workflow_id: string; + /** ID of the agent to run. Starts with `wpid_`. `workflow_id` is accepted as an alias. */ + agent_id: string; /** Parameters to pass to the workflow */ parameters?: Record; /** The title for this workflow run */ @@ -74,7 +74,7 @@ export interface WorkflowRunRequestInput { browser_profile_id?: string; /** The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. */ max_screenshot_scrolls?: number; - /** Timeout this workflow run after the configured elapsed runtime in minutes. Maximum runtime is 4 hours. */ + /** Timeout this workflow run after the configured elapsed runtime in minutes. When omitted, the platform default is 240 minutes. The maximum configurable value is 480 minutes. */ max_elapsed_time_minutes?: number; /** The extra HTTP headers for the requests in browser. */ extra_http_headers?: Record; diff --git a/skyvern-ts/client/src/api/client/requests/WorkflowTagsBatchRequest.ts b/skyvern-ts/client/src/api/client/requests/WorkflowTagsBatchRequest.ts new file mode 100644 index 000000000..96f58b8cf --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/WorkflowTagsBatchRequest.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * {} + */ +export interface WorkflowTagsBatchRequest { + /** Workflow permanent IDs to fetch tags for. */ + workflow_permanent_ids?: string[]; +} diff --git a/skyvern-ts/client/src/api/client/requests/index.ts b/skyvern-ts/client/src/api/client/requests/index.ts index 6364e6c03..d116ad137 100644 --- a/skyvern-ts/client/src/api/client/requests/index.ts +++ b/skyvern-ts/client/src/api/client/requests/index.ts @@ -1,3 +1,4 @@ +export type { BatchGetWorkflowTagsRequest } from "./BatchGetWorkflowTagsRequest.js"; export type { BodyUploadFileV1UploadFilePost } from "./BodyUploadFileV1UploadFilePost.js"; export type { BulkCancelRunsRequest } from "./BulkCancelRunsRequest.js"; export type { CreateBrowserProfileRequest } from "./CreateBrowserProfileRequest.js"; @@ -18,13 +19,18 @@ export type { GetWorkflowRequest } from "./GetWorkflowRequest.js"; export type { GetWorkflowRunsByIdRequest } from "./GetWorkflowRunsByIdRequest.js"; export type { GetWorkflowRunsRequest } from "./GetWorkflowRunsRequest.js"; export type { GetWorkflowsRequest } from "./GetWorkflowsRequest.js"; +export type { GetWorkflowTagHistoryRequest } from "./GetWorkflowTagHistoryRequest.js"; export type { GetWorkflowVersionsRequest } from "./GetWorkflowVersionsRequest.js"; export type { ListBrowserProfilesRequest } from "./ListBrowserProfilesRequest.js"; export type { LoginRequest } from "./LoginRequest.js"; export type { RetryWorkflowRunRequest } from "./RetryWorkflowRunRequest.js"; export type { RunSdkActionRequest } from "./RunSdkActionRequest.js"; +export type { TagApplyRequest } from "./TagApplyRequest.js"; +export type { TagKeyUpdate } from "./TagKeyUpdate.js"; export type { TaskRunRequestInput } from "./TaskRunRequestInput.js"; export type { TotpCodeCreate } from "./TotpCodeCreate.js"; export type { UpdateBrowserProfileRequest } from "./UpdateBrowserProfileRequest.js"; +export type { UpdateBrowserSessionRequest } from "./UpdateBrowserSessionRequest.js"; export type { UpdateWorkflowFolderRequest } from "./UpdateWorkflowFolderRequest.js"; export type { WorkflowRunRequestInput } from "./WorkflowRunRequestInput.js"; +export type { WorkflowTagsBatchRequest } from "./WorkflowTagsBatchRequest.js"; diff --git a/skyvern-ts/client/src/api/resources/workflows/client/Client.ts b/skyvern-ts/client/src/api/resources/agents/client/Client.ts similarity index 85% rename from skyvern-ts/client/src/api/resources/workflows/client/Client.ts rename to skyvern-ts/client/src/api/resources/agents/client/Client.ts index 9990acae6..09378e350 100644 --- a/skyvern-ts/client/src/api/resources/workflows/client/Client.ts +++ b/skyvern-ts/client/src/api/resources/agents/client/Client.ts @@ -7,16 +7,16 @@ import * as environments from "../../../../environments.js"; import * as errors from "../../../../errors/index.js"; import * as Skyvern from "../../../index.js"; -export declare namespace Workflows { +export declare namespace Agents { export interface Options extends BaseClientOptions {} export interface RequestOptions extends BaseRequestOptions {} } -export class Workflows { - protected readonly _options: Workflows.Options; +export class Agents { + protected readonly _options: Agents.Options; - constructor(_options: Workflows.Options = {}) { + constructor(_options: Agents.Options = {}) { this._options = _options; } @@ -24,18 +24,18 @@ export class Workflows { * Clear the persisted browser profile for a workflow that uses `Save & Reuse Session`. The next run will start from a fresh browser state. Use when a saved profile is corrupted. * * @param {string} workflowPermanentId - The permanent ID of the workflow. Starts with `wpid_`. - * @param {Workflows.RequestOptions} requestOptions - Request-specific configuration. + * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Skyvern.NotFoundError} * @throws {@link Skyvern.UnprocessableEntityError} * @throws {@link Skyvern.InternalServerError} * * @example - * await client.workflows.resetWorkflowBrowserProfile("wpid_123") + * await client.agents.resetWorkflowBrowserProfile("wpid_123") */ public resetWorkflowBrowserProfile( workflowPermanentId: string, - requestOptions?: Workflows.RequestOptions, + requestOptions?: Agents.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise( this.__resetWorkflowBrowserProfile(workflowPermanentId, requestOptions), @@ -44,7 +44,7 @@ export class Workflows { private async __resetWorkflowBrowserProfile( workflowPermanentId: string, - requestOptions?: Workflows.RequestOptions, + requestOptions?: Agents.RequestOptions, ): Promise> { const _headers: core.Fetcher.Args["headers"] = mergeHeaders( this._options?.headers, @@ -56,7 +56,7 @@ export class Workflows { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/browser_session/reset_profile`, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/browser_session/reset_profile`, ), method: "POST", headers: _headers, @@ -95,7 +95,7 @@ export class Workflows { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling POST /v1/workflows/{workflow_permanent_id}/browser_session/reset_profile.", + "Timeout exceeded when calling POST /v1/agents/{workflow_permanent_id}/browser_session/reset_profile.", ); case "unknown": throw new errors.SkyvernError({ diff --git a/skyvern-ts/client/src/api/resources/server/client/index.ts b/skyvern-ts/client/src/api/resources/agents/client/index.ts similarity index 100% rename from skyvern-ts/client/src/api/resources/server/client/index.ts rename to skyvern-ts/client/src/api/resources/agents/client/index.ts diff --git a/skyvern-ts/client/src/api/resources/server/index.ts b/skyvern-ts/client/src/api/resources/agents/index.ts similarity index 100% rename from skyvern-ts/client/src/api/resources/server/index.ts rename to skyvern-ts/client/src/api/resources/agents/index.ts diff --git a/skyvern-ts/client/src/api/resources/index.ts b/skyvern-ts/client/src/api/resources/index.ts index bf89d9d16..341e36aba 100644 --- a/skyvern-ts/client/src/api/resources/index.ts +++ b/skyvern-ts/client/src/api/resources/index.ts @@ -1,7 +1,6 @@ +export * as agents from "./agents/index.js"; export * as artifacts from "./artifacts/index.js"; export * from "./schedules/client/requests/index.js"; export * as schedules from "./schedules/index.js"; export * from "./schedules/types/index.js"; export * as scripts from "./scripts/index.js"; -export * as server from "./server/index.js"; -export * as workflows from "./workflows/index.js"; diff --git a/skyvern-ts/client/src/api/resources/schedules/client/Client.ts b/skyvern-ts/client/src/api/resources/schedules/client/Client.ts index 1a4448697..5e715bfdf 100644 --- a/skyvern-ts/client/src/api/resources/schedules/client/Client.ts +++ b/skyvern-ts/client/src/api/resources/schedules/client/Client.ts @@ -149,7 +149,7 @@ export class Schedules { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/schedules`, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/schedules`, ), method: "GET", headers: _headers, @@ -184,7 +184,7 @@ export class Schedules { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling GET /v1/workflows/{workflow_permanent_id}/schedules.", + "Timeout exceeded when calling GET /v1/agents/{workflow_permanent_id}/schedules.", ); case "unknown": throw new errors.SkyvernError({ @@ -230,7 +230,7 @@ export class Schedules { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/schedules`, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/schedules`, ), method: "POST", headers: _headers, @@ -268,7 +268,7 @@ export class Schedules { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling POST /v1/workflows/{workflow_permanent_id}/schedules.", + "Timeout exceeded when calling POST /v1/agents/{workflow_permanent_id}/schedules.", ); case "unknown": throw new errors.SkyvernError({ @@ -313,7 +313,7 @@ export class Schedules { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}`, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}`, ), method: "GET", headers: _headers, @@ -348,7 +348,7 @@ export class Schedules { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling GET /v1/workflows/{workflow_permanent_id}/schedules/{workflow_schedule_id}.", + "Timeout exceeded when calling GET /v1/agents/{workflow_permanent_id}/schedules/{workflow_schedule_id}.", ); case "unknown": throw new errors.SkyvernError({ @@ -399,7 +399,7 @@ export class Schedules { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}`, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}`, ), method: "PUT", headers: _headers, @@ -437,7 +437,7 @@ export class Schedules { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling PUT /v1/workflows/{workflow_permanent_id}/schedules/{workflow_schedule_id}.", + "Timeout exceeded when calling PUT /v1/agents/{workflow_permanent_id}/schedules/{workflow_schedule_id}.", ); case "unknown": throw new errors.SkyvernError({ @@ -482,7 +482,7 @@ export class Schedules { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}`, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}`, ), method: "DELETE", headers: _headers, @@ -517,7 +517,7 @@ export class Schedules { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling DELETE /v1/workflows/{workflow_permanent_id}/schedules/{workflow_schedule_id}.", + "Timeout exceeded when calling DELETE /v1/agents/{workflow_permanent_id}/schedules/{workflow_schedule_id}.", ); case "unknown": throw new errors.SkyvernError({ @@ -562,7 +562,7 @@ export class Schedules { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}/enable`, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}/enable`, ), method: "POST", headers: _headers, @@ -597,7 +597,7 @@ export class Schedules { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling POST /v1/workflows/{workflow_permanent_id}/schedules/{workflow_schedule_id}/enable.", + "Timeout exceeded when calling POST /v1/agents/{workflow_permanent_id}/schedules/{workflow_schedule_id}/enable.", ); case "unknown": throw new errors.SkyvernError({ @@ -642,7 +642,7 @@ export class Schedules { (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)) ?? environments.SkyvernEnvironment.Cloud, - `v1/workflows/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}/disable`, + `v1/agents/${core.url.encodePathParam(workflowPermanentId)}/schedules/${core.url.encodePathParam(workflowScheduleId)}/disable`, ), method: "POST", headers: _headers, @@ -677,7 +677,7 @@ export class Schedules { }); case "timeout": throw new errors.SkyvernTimeoutError( - "Timeout exceeded when calling POST /v1/workflows/{workflow_permanent_id}/schedules/{workflow_schedule_id}/disable.", + "Timeout exceeded when calling POST /v1/agents/{workflow_permanent_id}/schedules/{workflow_schedule_id}/disable.", ); case "unknown": throw new errors.SkyvernError({ diff --git a/skyvern-ts/client/src/api/resources/server/client/Client.ts b/skyvern-ts/client/src/api/resources/server/client/Client.ts deleted file mode 100644 index 2eb32c82c..000000000 --- a/skyvern-ts/client/src/api/resources/server/client/Client.ts +++ /dev/null @@ -1,84 +0,0 @@ -// This file was auto-generated by Fern from our API Definition. - -import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; -import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as core from "../../../../core/index.js"; -import * as environments from "../../../../environments.js"; -import * as errors from "../../../../errors/index.js"; - -export declare namespace Server { - export interface Options extends BaseClientOptions {} - - export interface RequestOptions extends BaseRequestOptions {} -} - -export class Server { - protected readonly _options: Server.Options; - - constructor(_options: Server.Options = {}) { - this._options = _options; - } - - /** - * Returns the current Skyvern server version (git SHA for official builds). - * - * @param {Server.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.server.getVersion() - */ - public getVersion(requestOptions?: Server.RequestOptions): core.HttpResponsePromise> { - return core.HttpResponsePromise.fromPromise(this.__getVersion(requestOptions)); - } - - private async __getVersion( - requestOptions?: Server.RequestOptions, - ): Promise>> { - const _headers: core.Fetcher.Args["headers"] = mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), - requestOptions?.headers, - ); - const _response = await core.fetcher({ - url: core.url.join( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)) ?? - environments.SkyvernEnvironment.Cloud, - "v1/version", - ), - method: "GET", - headers: _headers, - queryParameters: requestOptions?.queryParams, - timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, - maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return { data: _response.body as Record, rawResponse: _response.rawResponse }; - } - - if (_response.error.reason === "status-code") { - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.SkyvernError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/version."); - case "unknown": - throw new errors.SkyvernError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } -} diff --git a/skyvern-ts/client/src/api/resources/workflows/client/index.ts b/skyvern-ts/client/src/api/resources/workflows/client/index.ts deleted file mode 100644 index cb0ff5c3b..000000000 --- a/skyvern-ts/client/src/api/resources/workflows/client/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/skyvern-ts/client/src/api/resources/workflows/index.ts b/skyvern-ts/client/src/api/resources/workflows/index.ts deleted file mode 100644 index 914b8c3c7..000000000 --- a/skyvern-ts/client/src/api/resources/workflows/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./client/index.js"; diff --git a/skyvern-ts/client/src/api/types/ActionBlock.ts b/skyvern-ts/client/src/api/types/ActionBlock.ts index 9cc95a5f3..496d8b333 100644 --- a/skyvern-ts/client/src/api/types/ActionBlock.ts +++ b/skyvern-ts/client/src/api/types/ActionBlock.ts @@ -34,6 +34,8 @@ export interface ActionBlock { include_action_history_in_verification?: boolean; download_timeout?: number; include_extracted_text?: boolean; + selector?: string; + ai_fallback?: Skyvern.AiFallbackMode; } export namespace ActionBlock { diff --git a/skyvern-ts/client/src/api/types/ActionBlockYaml.ts b/skyvern-ts/client/src/api/types/ActionBlockYaml.ts index 865650060..df2dfd18e 100644 --- a/skyvern-ts/client/src/api/types/ActionBlockYaml.ts +++ b/skyvern-ts/client/src/api/types/ActionBlockYaml.ts @@ -15,6 +15,8 @@ export interface ActionBlockYaml { title?: string; engine?: Skyvern.RunEngine; navigation_goal?: string; + selector?: string; + ai_fallback?: Skyvern.AiFallbackMode; error_code_mapping?: Record; max_retries?: number; parameter_keys?: string[]; diff --git a/skyvern-ts/client/src/api/types/ActionType.ts b/skyvern-ts/client/src/api/types/ActionType.ts index 1cfe539c4..8c84c0011 100644 --- a/skyvern-ts/client/src/api/types/ActionType.ts +++ b/skyvern-ts/client/src/api/types/ActionType.ts @@ -15,6 +15,8 @@ export const ActionType = { Complete: "complete", ReloadPage: "reload_page", ClosePage: "close_page", + NewTab: "new_tab", + SwitchTab: "switch_tab", Extract: "extract", VerificationCode: "verification_code", GotoUrl: "goto_url", diff --git a/skyvern-ts/client/src/api/types/AiFallbackMode.ts b/skyvern-ts/client/src/api/types/AiFallbackMode.ts new file mode 100644 index 000000000..9620aceaa --- /dev/null +++ b/skyvern-ts/client/src/api/types/AiFallbackMode.ts @@ -0,0 +1,16 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Controls how an action block uses a CSS/XPath selector relative to AI. + * + * - `fallback`: attempt the selector first; fall back to AI on failure. + * - `proactive`: always use AI; the selector (if any) is a hint only. + * + * When `selector` is None, both modes degrade to AI-only — the difference + * is purely semantic (whether the author expected to have a selector here). + */ +export const AiFallbackMode = { + Fallback: "fallback", + Proactive: "proactive", +} as const; +export type AiFallbackMode = (typeof AiFallbackMode)[keyof typeof AiFallbackMode]; diff --git a/skyvern-ts/client/src/api/types/ArtifactType.ts b/skyvern-ts/client/src/api/types/ArtifactType.ts index 71db94de6..5f980a03c 100644 --- a/skyvern-ts/client/src/api/types/ArtifactType.ts +++ b/skyvern-ts/client/src/api/types/ArtifactType.ts @@ -2,6 +2,8 @@ export const ArtifactType = { Recording: "recording", + Audio: "audio", + SessionReplay: "session_replay", BrowserConsoleLog: "browser_console_log", SkyvernLog: "skyvern_log", SkyvernLogRaw: "skyvern_log_raw", diff --git a/skyvern-ts/client/src/api/types/BrowserProfile.ts b/skyvern-ts/client/src/api/types/BrowserProfile.ts index 7f23fab98..b2924a7bb 100644 --- a/skyvern-ts/client/src/api/types/BrowserProfile.ts +++ b/skyvern-ts/client/src/api/types/BrowserProfile.ts @@ -1,12 +1,23 @@ // This file was auto-generated by Fern from our API Definition. +import type * as Skyvern from "../index.js"; + export interface BrowserProfile { browser_profile_id: string; organization_id: string; name: string; description?: string; source_browser_type?: string; + proxy_location?: BrowserProfile.ProxyLocation; + proxy_session_id?: string; + is_managed?: boolean; + workflow_permanent_id?: string; + browser_profile_key_digest?: string; created_at: string; modified_at: string; deleted_at?: string; } + +export namespace BrowserProfile { + export type ProxyLocation = Skyvern.ProxyLocation | Skyvern.GeoTarget | Record; +} diff --git a/skyvern-ts/client/src/api/types/BrowserSessionResponse.ts b/skyvern-ts/client/src/api/types/BrowserSessionResponse.ts index e2481d1aa..102a64d38 100644 --- a/skyvern-ts/client/src/api/types/BrowserSessionResponse.ts +++ b/skyvern-ts/client/src/api/types/BrowserSessionResponse.ts @@ -28,6 +28,8 @@ export interface BrowserSessionResponse { browser_type?: Skyvern.PersistentBrowserType; /** ID of the browser profile loaded into this session, if any. browser_profile_id starts with `bp_`. */ browser_profile_id?: string; + /** Whether this session's browser profile will be saved when it ends so it can become a reusable browser profile. */ + generate_browser_profile?: boolean; /** Whether the browser session supports VNC streaming */ vnc_streaming_supported?: boolean; /** The path where the browser session downloads files */ diff --git a/skyvern-ts/client/src/api/types/CreateCredentialRequest.ts b/skyvern-ts/client/src/api/types/CreateCredentialRequest.ts index 0cf67ed86..b0a34d9ab 100644 --- a/skyvern-ts/client/src/api/types/CreateCredentialRequest.ts +++ b/skyvern-ts/client/src/api/types/CreateCredentialRequest.ts @@ -14,6 +14,12 @@ export interface CreateCredentialRequest { credential: CreateCredentialRequest.Credential; /** Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. */ vault_type?: Skyvern.CredentialVaultType; + /** Optional proxy location for this credential's pinned proxy identity. */ + proxy_location?: CreateCredentialRequest.ProxyLocation; + /** Optional advanced reuse key for this credential's pinned proxy identity. */ + proxy_session_id?: string; + /** Rotate the Skyvern-managed proxy sticky-session id when updating this credential. */ + rotate_proxy_session_id?: boolean; } export namespace CreateCredentialRequest { @@ -24,4 +30,8 @@ export namespace CreateCredentialRequest { | Skyvern.NonEmptyPasswordCredential | Skyvern.NonEmptyCreditCardCredential | Skyvern.SecretCredential; + /** + * Optional proxy location for this credential's pinned proxy identity. + */ + export type ProxyLocation = Skyvern.ProxyLocation | Skyvern.GeoTarget | Record; } diff --git a/skyvern-ts/client/src/api/types/CredentialResponse.ts b/skyvern-ts/client/src/api/types/CredentialResponse.ts index d1b566b97..3d22cf980 100644 --- a/skyvern-ts/client/src/api/types/CredentialResponse.ts +++ b/skyvern-ts/client/src/api/types/CredentialResponse.ts @@ -24,6 +24,8 @@ export interface CredentialResponse { user_context?: string; /** Whether the user intends to save a browser session, regardless of test outcome */ save_browser_session_intent?: boolean; + /** ID of the credential folder this credential belongs to, if any */ + folder_id?: string; } export namespace CredentialResponse { diff --git a/skyvern-ts/client/src/api/types/FileStorageType.ts b/skyvern-ts/client/src/api/types/FileStorageType.ts index 18d06becd..b72f6cce4 100644 --- a/skyvern-ts/client/src/api/types/FileStorageType.ts +++ b/skyvern-ts/client/src/api/types/FileStorageType.ts @@ -3,5 +3,6 @@ export const FileStorageType = { S3: "s3", Azure: "azure", + GoogleDrive: "google_drive", } as const; export type FileStorageType = (typeof FileStorageType)[keyof typeof FileStorageType]; diff --git a/skyvern-ts/client/src/api/types/FileUploadBlock.ts b/skyvern-ts/client/src/api/types/FileUploadBlock.ts index ccc6b969d..1bb853e66 100644 --- a/skyvern-ts/client/src/api/types/FileUploadBlock.ts +++ b/skyvern-ts/client/src/api/types/FileUploadBlock.ts @@ -21,5 +21,7 @@ export interface FileUploadBlock { azure_storage_account_name?: string; azure_storage_account_key?: string; azure_blob_container_name?: string; + google_credential_id?: string; + google_drive_folder_id?: string; path?: string; } diff --git a/skyvern-ts/client/src/api/types/FileUploadBlockYaml.ts b/skyvern-ts/client/src/api/types/FileUploadBlockYaml.ts index b1a366903..3c21f228f 100644 --- a/skyvern-ts/client/src/api/types/FileUploadBlockYaml.ts +++ b/skyvern-ts/client/src/api/types/FileUploadBlockYaml.ts @@ -20,5 +20,7 @@ export interface FileUploadBlockYaml { azure_storage_account_key?: string; azure_blob_container_name?: string; azure_folder_path?: string; + google_credential_id?: string; + google_drive_folder_id?: string; path?: string; } diff --git a/skyvern-ts/client/src/api/types/LoginBlock.ts b/skyvern-ts/client/src/api/types/LoginBlock.ts index bd001ccba..f8d892e94 100644 --- a/skyvern-ts/client/src/api/types/LoginBlock.ts +++ b/skyvern-ts/client/src/api/types/LoginBlock.ts @@ -34,6 +34,7 @@ export interface LoginBlock { include_action_history_in_verification?: boolean; download_timeout?: number; include_extracted_text?: boolean; + skip_saved_profile?: boolean; } export namespace LoginBlock { diff --git a/skyvern-ts/client/src/api/types/LoginBlockYaml.ts b/skyvern-ts/client/src/api/types/LoginBlockYaml.ts index c88702f90..778f8499f 100644 --- a/skyvern-ts/client/src/api/types/LoginBlockYaml.ts +++ b/skyvern-ts/client/src/api/types/LoginBlockYaml.ts @@ -25,4 +25,5 @@ export interface LoginBlockYaml { complete_criterion?: string; terminate_criterion?: string; complete_verification?: boolean; + skip_saved_profile?: boolean; } diff --git a/skyvern-ts/client/src/api/types/TagDeleteInput.ts b/skyvern-ts/client/src/api/types/TagDeleteInput.ts new file mode 100644 index 000000000..46eeaf64d --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagDeleteInput.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * One tag to soft-delete: a grouped tag by its ``key``, or a standalone label + * by its ``value`` (omit the key). + */ +export interface TagDeleteInput { + /** Group (key) to delete. Use for grouped tags. */ + key?: string; + /** Label (value) to delete. Use for standalone labels. */ + value?: string; +} diff --git a/skyvern-ts/client/src/api/types/TagHistoryItem.ts b/skyvern-ts/client/src/api/types/TagHistoryItem.ts new file mode 100644 index 000000000..75109a364 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagHistoryItem.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * One row from ``GET /v1/workflows/{wpid}/tags/history``. + */ +export interface TagHistoryItem { + tag_event_id: string; + key?: string; + value?: string; + event_type: string; + source: string; + set_at: string; + set_by: string; + superseded_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/TagHistoryResponse.ts b/skyvern-ts/client/src/api/types/TagHistoryResponse.ts new file mode 100644 index 000000000..3d1b37191 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagHistoryResponse.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface TagHistoryResponse { + workflow_permanent_id: string; + events: Skyvern.TagHistoryItem[]; +} diff --git a/skyvern-ts/client/src/api/types/TagInput.ts b/skyvern-ts/client/src/api/types/TagInput.ts new file mode 100644 index 000000000..0fffcb588 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagInput.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * One tag to set. ``value`` is the required label; ``key`` is the optional + * group — null for a standalone label, set for a grouped label (e.g. env:prod). + */ +export interface TagInput { + /** Optional group (key). Omit for a standalone label. */ + key?: string; + /** Label (value). Always required. */ + value: string; +} diff --git a/skyvern-ts/client/src/api/types/TagItem.ts b/skyvern-ts/client/src/api/types/TagItem.ts new file mode 100644 index 000000000..2a7c93f1b --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagItem.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * A single tag (key + label) without per-tag attribution. ``key`` is null + * for a standalone label. + */ +export interface TagItem { + key?: string; + value: string; +} diff --git a/skyvern-ts/client/src/api/types/TagKey.ts b/skyvern-ts/client/src/api/types/TagKey.ts new file mode 100644 index 000000000..3ec4a0af4 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagKey.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Tag-key registry entry. + */ +export interface TagKey { + key: string; + description?: string; + workflow_count?: number; +} diff --git a/skyvern-ts/client/src/api/types/TagKeyDeleteResponse.ts b/skyvern-ts/client/src/api/types/TagKeyDeleteResponse.ts new file mode 100644 index 000000000..9869f0d55 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagKeyDeleteResponse.ts @@ -0,0 +1,9 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Response for ``DELETE /v1/tag-keys/{key}``. + */ +export interface TagKeyDeleteResponse { + key: string; + removed_from_workflow_count: number; +} diff --git a/skyvern-ts/client/src/api/types/TagResponse.ts b/skyvern-ts/client/src/api/types/TagResponse.ts new file mode 100644 index 000000000..c6c0d972a --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagResponse.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Current state of one tag (``GET /v1/workflows/{wpid}/tags`` row). + * ``key`` is null for a standalone label. + */ +export interface TagResponse { + key?: string; + value: string; + source: string; + set_at: string; + set_by: string; +} diff --git a/skyvern-ts/client/src/api/types/TagsResponse.ts b/skyvern-ts/client/src/api/types/TagsResponse.ts new file mode 100644 index 000000000..b18f5994b --- /dev/null +++ b/skyvern-ts/client/src/api/types/TagsResponse.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * Current tags for a workflow. A list (not a key-map) so standalone labels, + * which have no key, are representable. + */ +export interface TagsResponse { + workflow_permanent_id: string; + tags: Skyvern.TagResponse[]; +} diff --git a/skyvern-ts/client/src/api/types/Workflow.ts b/skyvern-ts/client/src/api/types/Workflow.ts index 7b6582f40..2ac49403b 100644 --- a/skyvern-ts/client/src/api/types/Workflow.ts +++ b/skyvern-ts/client/src/api/types/Workflow.ts @@ -39,6 +39,8 @@ export interface Workflow { created_at: string; modified_at: string; deleted_at?: string; + /** Alias of `workflow_permanent_id` — the stable agent identifier (starts with `wpid_`). */ + agent_id?: string; } export namespace Workflow { diff --git a/skyvern-ts/client/src/api/types/WorkflowRunRequestOutput.ts b/skyvern-ts/client/src/api/types/WorkflowRunRequestOutput.ts index 91cdee726..1475de28b 100644 --- a/skyvern-ts/client/src/api/types/WorkflowRunRequestOutput.ts +++ b/skyvern-ts/client/src/api/types/WorkflowRunRequestOutput.ts @@ -3,7 +3,7 @@ import type * as Skyvern from "../index.js"; export interface WorkflowRunRequestOutput { - /** ID of the workflow to run. Workflow ID starts with `wpid_`. */ + /** ID of the agent to run. Starts with `wpid_`. `workflow_id` is accepted as an alias. */ workflow_id: string; /** Parameters to pass to the workflow */ parameters?: Record; @@ -62,7 +62,7 @@ export interface WorkflowRunRequestOutput { browser_profile_id?: string; /** The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. */ max_screenshot_scrolls?: number; - /** Timeout this workflow run after the configured elapsed runtime in minutes. Maximum runtime is 4 hours. */ + /** Timeout this workflow run after the configured elapsed runtime in minutes. When omitted, the platform default is 240 minutes. The maximum configurable value is 480 minutes. */ max_elapsed_time_minutes?: number; /** The extra HTTP headers for the requests in browser. */ extra_http_headers?: Record; diff --git a/skyvern-ts/client/src/api/types/WorkflowTagsBatchResponse.ts b/skyvern-ts/client/src/api/types/WorkflowTagsBatchResponse.ts new file mode 100644 index 000000000..2dbdd51cc --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowTagsBatchResponse.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * Response for the batch endpoint. + * + * Workflows with no tags are present with an empty list so the frontend can + * distinguish "fetched, none set" from "not fetched" without a second call. + * Workflows outside the caller's org are silently absent (no leakage). + */ +export interface WorkflowTagsBatchResponse { + workflow_tags: Record; +} diff --git a/skyvern-ts/client/src/api/types/index.ts b/skyvern-ts/client/src/api/types/index.ts index f266a31ce..90b552590 100644 --- a/skyvern-ts/client/src/api/types/index.ts +++ b/skyvern-ts/client/src/api/types/index.ts @@ -5,6 +5,7 @@ export * from "./ActionBlockParametersItem.js"; export * from "./ActionBlockYaml.js"; export * from "./ActionStatus.js"; export * from "./ActionType.js"; +export * from "./AiFallbackMode.js"; export * from "./Artifact.js"; export * from "./ArtifactType.js"; export * from "./AwsSecretParameter.js"; @@ -132,6 +133,15 @@ export * from "./SendEmailBlock.js"; export * from "./SendEmailBlockYaml.js"; export * from "./SkyvernForgeSdkSchemasCredentialsCredentialType.js"; export * from "./SkyvernSchemasCredentialTypeCredentialType.js"; +export * from "./TagDeleteInput.js"; +export * from "./TagHistoryItem.js"; +export * from "./TagHistoryResponse.js"; +export * from "./TagInput.js"; +export * from "./TagItem.js"; +export * from "./TagKey.js"; +export * from "./TagKeyDeleteResponse.js"; +export * from "./TagResponse.js"; +export * from "./TagsResponse.js"; export * from "./TaskBlock.js"; export * from "./TaskBlockParametersItem.js"; export * from "./TaskBlockYaml.js"; @@ -194,6 +204,7 @@ export * from "./WorkflowScheduleListResponse.js"; export * from "./WorkflowScheduleResponse.js"; export * from "./WorkflowScheduleUpsertRequest.js"; export * from "./WorkflowStatus.js"; +export * from "./WorkflowTagsBatchResponse.js"; export * from "./WorkflowTriggerBlock.js"; export * from "./WorkflowTriggerBlockParametersItem.js"; export * from "./WorkflowTriggerBlockYaml.js"; diff --git a/skyvern-ts/client/src/library/Skyvern.ts b/skyvern-ts/client/src/library/Skyvern.ts index 888d7a1d3..b8d692535 100644 --- a/skyvern-ts/client/src/library/Skyvern.ts +++ b/skyvern-ts/client/src/library/Skyvern.ts @@ -17,12 +17,12 @@ export interface SkyvernOptions extends BaseClientOptions { apiKey: string; } -export interface RunTaskOptions extends SkyvernApi.RunTaskRequest { +export interface RunTaskOptions extends SkyvernApi.TaskRunRequestInput { waitForCompletion?: boolean; timeout?: number; } -export interface RunWorkflowOptions extends SkyvernApi.RunWorkflowRequest { +export interface RunWorkflowOptions extends SkyvernApi.WorkflowRunRequestInput { waitForCompletion?: boolean; timeout?: number; } diff --git a/skyvern-ts/client/src/library/SkyvernBrowserPageAgent.ts b/skyvern-ts/client/src/library/SkyvernBrowserPageAgent.ts index 0607865e6..b0f4d813a 100644 --- a/skyvern-ts/client/src/library/SkyvernBrowserPageAgent.ts +++ b/skyvern-ts/client/src/library/SkyvernBrowserPageAgent.ts @@ -64,21 +64,19 @@ export class SkyvernBrowserPageAgent { const taskRun = await this._browser.skyvern.runTask({ "x-user-agent": "skyvern-sdk", - body: { - prompt: prompt, - engine: options?.engine, - model: options?.model, - url: options?.url ?? this._getPageUrl(), - webhook_url: options?.webhookUrl, - totp_identifier: options?.totpIdentifier, - totp_url: options?.totpUrl, - title: options?.title, - error_code_mapping: options?.errorCodeMapping, - data_extraction_schema: options?.dataExtractionSchema, - max_steps: options?.maxSteps, - browser_session_id: this._browser.browserSessionId, - browser_address: this._browser.browserAddress, - }, + prompt: prompt, + engine: options?.engine, + model: options?.model, + url: options?.url ?? this._getPageUrl(), + webhook_url: options?.webhookUrl, + totp_identifier: options?.totpIdentifier, + totp_url: options?.totpUrl, + title: options?.title, + error_code_mapping: options?.errorCodeMapping, + data_extraction_schema: options?.dataExtractionSchema, + max_steps: options?.maxSteps, + browser_session_id: this._browser.browserSessionId, + browser_address: this._browser.browserAddress, }); if (this._browser.skyvern.environment === SkyvernEnvironment.Cloud) { @@ -191,7 +189,7 @@ export class SkyvernBrowserPageAgent { }, ): Promise; async login( - credentialType: Skyvern.SkyvernSchemasRunBlocksCredentialType, + credentialType: Skyvern.SkyvernSchemasCredentialTypeCredentialType, options: { url?: string; credentialId?: string; @@ -350,16 +348,14 @@ export class SkyvernBrowserPageAgent { { "x-user-agent": "skyvern-sdk", template: options?.template, - body: { - workflow_id: workflowId, - parameters: options?.parameters, - title: options?.title, - webhook_url: options?.webhookUrl, - totp_url: options?.totpUrl, - totp_identifier: options?.totpIdentifier, - browser_session_id: this._browser.browserSessionId, - browser_address: this._browser.browserAddress, - }, + agent_id: workflowId, + parameters: options?.parameters, + title: options?.title, + webhook_url: options?.webhookUrl, + totp_url: options?.totpUrl, + totp_identifier: options?.totpIdentifier, + browser_session_id: this._browser.browserSessionId, + browser_address: this._browser.browserAddress, }, { headers: { "x-user-agent": "skyvern-sdk" }, diff --git a/skyvern-ts/client/src/version.ts b/skyvern-ts/client/src/version.ts index 2add499ed..7ef1f0ee1 100644 --- a/skyvern-ts/client/src/version.ts +++ b/skyvern-ts/client/src/version.ts @@ -1 +1 @@ -export const SDK_VERSION = "1.0.37"; +export const SDK_VERSION = "1.0.45"; diff --git a/skyvern-ts/client/tests/wire/workflows.test.ts b/skyvern-ts/client/tests/wire/agents.test.ts similarity index 74% rename from skyvern-ts/client/tests/wire/workflows.test.ts rename to skyvern-ts/client/tests/wire/agents.test.ts index 93a7cdb6f..cadda440f 100644 --- a/skyvern-ts/client/tests/wire/workflows.test.ts +++ b/skyvern-ts/client/tests/wire/agents.test.ts @@ -4,19 +4,19 @@ import * as Skyvern from "../../src/api/index"; import { SkyvernClient } from "../../src/Client"; import { mockServerPool } from "../mock-server/MockServerPool"; -describe("Workflows", () => { +describe("Agents", () => { test("reset_workflow_browser_profile (1)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); server .mockEndpoint() - .post("/v1/workflows/wpid_123/browser_session/reset_profile") + .post("/v1/agents/wpid_123/browser_session/reset_profile") .respondWith() .statusCode(200) .build(); - const response = await client.workflows.resetWorkflowBrowserProfile("wpid_123"); + const response = await client.agents.resetWorkflowBrowserProfile("wpid_123"); expect(response).toEqual(undefined); }); @@ -27,14 +27,14 @@ describe("Workflows", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/browser_session/reset_profile") + .post("/v1/agents/workflow_permanent_id/browser_session/reset_profile") .respondWith() .statusCode(404) .jsonBody(rawResponseBody) .build(); await expect(async () => { - return await client.workflows.resetWorkflowBrowserProfile("workflow_permanent_id"); + return await client.agents.resetWorkflowBrowserProfile("workflow_permanent_id"); }).rejects.toThrow(Skyvern.NotFoundError); }); @@ -45,14 +45,14 @@ describe("Workflows", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/browser_session/reset_profile") + .post("/v1/agents/workflow_permanent_id/browser_session/reset_profile") .respondWith() .statusCode(422) .jsonBody(rawResponseBody) .build(); await expect(async () => { - return await client.workflows.resetWorkflowBrowserProfile("workflow_permanent_id"); + return await client.agents.resetWorkflowBrowserProfile("workflow_permanent_id"); }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); @@ -63,14 +63,14 @@ describe("Workflows", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/browser_session/reset_profile") + .post("/v1/agents/workflow_permanent_id/browser_session/reset_profile") .respondWith() .statusCode(500) .jsonBody(rawResponseBody) .build(); await expect(async () => { - return await client.workflows.resetWorkflowBrowserProfile("workflow_permanent_id"); + return await client.agents.resetWorkflowBrowserProfile("workflow_permanent_id"); }).rejects.toThrow(Skyvern.InternalServerError); }); }); diff --git a/skyvern-ts/client/tests/wire/main.test.ts b/skyvern-ts/client/tests/wire/main.test.ts index 7f9802a0d..1dcac2a57 100644 --- a/skyvern-ts/client/tests/wire/main.test.ts +++ b/skyvern-ts/client/tests/wire/main.test.ts @@ -198,7 +198,7 @@ describe("SkyvernClient", () => { test("run_workflow (1)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { workflow_id: "wpid_123" }; + const rawRequestBody = { agent_id: "wpid_123" }; const rawResponseBody = { run_id: "tsk_123", status: "created", @@ -258,7 +258,7 @@ describe("SkyvernClient", () => { }; server .mockEndpoint() - .post("/v1/run/workflows") + .post("/v1/run/agents") .header("x-max-steps-override", "1") .header("x-user-agent", "x-user-agent") .jsonBody(rawRequestBody) @@ -271,7 +271,7 @@ describe("SkyvernClient", () => { "x-max-steps-override": 1, "x-user-agent": "x-user-agent", template: true, - workflow_id: "wpid_123", + agent_id: "wpid_123", }); expect(response).toEqual({ run_id: "tsk_123", @@ -349,11 +349,11 @@ describe("SkyvernClient", () => { test("run_workflow (2)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { workflow_id: "workflow_id" }; + const rawRequestBody = { agent_id: "agent_id" }; const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/run/workflows") + .post("/v1/run/agents") .jsonBody(rawRequestBody) .respondWith() .statusCode(400) @@ -362,7 +362,7 @@ describe("SkyvernClient", () => { await expect(async () => { return await client.runWorkflow({ - workflow_id: "workflow_id", + agent_id: "agent_id", }); }).rejects.toThrow(Skyvern.BadRequestError); }); @@ -370,11 +370,11 @@ describe("SkyvernClient", () => { test("run_workflow (3)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = { workflow_id: "workflow_id" }; + const rawRequestBody = { agent_id: "agent_id" }; const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/run/workflows") + .post("/v1/run/agents") .jsonBody(rawRequestBody) .respondWith() .statusCode(422) @@ -383,7 +383,7 @@ describe("SkyvernClient", () => { await expect(async () => { return await client.runWorkflow({ - workflow_id: "workflow_id", + agent_id: "agent_id", }); }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); @@ -703,9 +703,10 @@ describe("SkyvernClient", () => { created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", }, ]; - server.mockEndpoint().get("/v1/workflows").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + server.mockEndpoint().get("/v1/agents").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); const response = await client.getWorkflows({ page: 1, @@ -791,6 +792,7 @@ describe("SkyvernClient", () => { created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", }, ]); }); @@ -800,7 +802,7 @@ describe("SkyvernClient", () => { const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); const rawResponseBody = { key: "value" }; - server.mockEndpoint().get("/v1/workflows").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); + server.mockEndpoint().get("/v1/agents").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); await expect(async () => { return await client.getWorkflows(); @@ -877,10 +879,11 @@ describe("SkyvernClient", () => { created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", }; server .mockEndpoint() - .post("/v1/workflows") + .post("/v1/agents") .jsonBody(rawRequestBody) .respondWith() .statusCode(200) @@ -965,6 +968,7 @@ describe("SkyvernClient", () => { created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", }); }); @@ -975,7 +979,7 @@ describe("SkyvernClient", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows") + .post("/v1/agents") .jsonBody(rawRequestBody) .respondWith() .statusCode(422) @@ -1059,10 +1063,11 @@ describe("SkyvernClient", () => { created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", }; server .mockEndpoint() - .post("/v1/workflows/wpid_123") + .post("/v1/agents/wpid_123") .jsonBody(rawRequestBody) .respondWith() .statusCode(200) @@ -1144,6 +1149,7 @@ describe("SkyvernClient", () => { created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", }); }); @@ -1154,7 +1160,7 @@ describe("SkyvernClient", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/workflow_id") + .post("/v1/agents/workflow_id") .jsonBody(rawRequestBody) .respondWith() .statusCode(422) @@ -1173,7 +1179,7 @@ describe("SkyvernClient", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/wpid_123/delete") + .post("/v1/agents/wpid_123/delete") .respondWith() .statusCode(200) .jsonBody(rawResponseBody) @@ -1192,7 +1198,7 @@ describe("SkyvernClient", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/workflow_id/delete") + .post("/v1/agents/workflow_id/delete") .respondWith() .statusCode(422) .jsonBody(rawResponseBody) @@ -1526,191 +1532,121 @@ describe("SkyvernClient", () => { }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); - test("update_workflow_folder (1)", async () => { + test("list_tag_keys (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [{ key: "key", description: "description", workflow_count: 1 }]; + server.mockEndpoint().get("/v1/tag-keys").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.listTagKeys(); + expect(response).toEqual([ + { + key: "key", + description: "description", + workflow_count: 1, + }, + ]); + }); + + test("list_tag_keys (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/tag-keys").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.listTagKeys(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("delete_tag_key (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "key", removed_from_workflow_count: 1 }; + server + .mockEndpoint() + .delete("/v1/tag-keys/env") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.deleteTagKey("env"); + expect(response).toEqual({ + key: "key", + removed_from_workflow_count: 1, + }); + }); + + test("delete_tag_key (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/tag-keys/key") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deleteTagKey("key"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("delete_tag_key (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/tag-keys/key") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deleteTagKey("key"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("update_tag_key (1)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); const rawRequestBody = {}; - const rawResponseBody = { - workflow_id: "workflow_id", - organization_id: "organization_id", - title: "title", - workflow_permanent_id: "workflow_permanent_id", - version: 1, - is_saved_task: true, - is_template: true, - description: "description", - workflow_definition: { - version: 1, - parameters: [ - { - parameter_type: "aws_secret", - key: "key", - aws_secret_parameter_id: "aws_secret_parameter_id", - workflow_id: "workflow_id", - aws_key: "aws_key", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ], - blocks: [ - { - block_type: "action", - label: "label", - output_parameter: { - key: "key", - output_parameter_id: "output_parameter_id", - workflow_id: "workflow_id", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - }, - ], - finally_block_label: "finally_block_label", - error_code_mapping: { key: "value" }, - workflow_system_prompt: "workflow_system_prompt", - }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - persist_browser_session: true, - browser_profile_id: "browser_profile_id", - model: { key: "value" }, - status: "published", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - extra_http_headers: { key: "value" }, - cdp_connect_headers: { key: "value" }, - run_with: "run_with", - ai_fallback: true, - cache_key: "cache_key", - adaptive_caching: true, - code_version: 1, - generate_script_on_terminal: true, - run_sequentially: true, - sequential_key: "sequential_key", - folder_id: "folder_id", - import_error: "import_error", - created_by: "created_by", - edited_by: "edited_by", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - deleted_at: "2024-01-15T09:30:00Z", - }; + const rawResponseBody = { key: "key", description: "description", workflow_count: 1 }; server .mockEndpoint() - .put("/v1/workflows/wpid_123/folder") + .patch("/v1/tag-keys/key") .jsonBody(rawRequestBody) .respondWith() .statusCode(200) .jsonBody(rawResponseBody) .build(); - const response = await client.updateWorkflowFolder("wpid_123"); + const response = await client.updateTagKey("key"); expect(response).toEqual({ - workflow_id: "workflow_id", - organization_id: "organization_id", - title: "title", - workflow_permanent_id: "workflow_permanent_id", - version: 1, - is_saved_task: true, - is_template: true, + key: "key", description: "description", - workflow_definition: { - version: 1, - parameters: [ - { - parameter_type: "aws_secret", - key: "key", - aws_secret_parameter_id: "aws_secret_parameter_id", - workflow_id: "workflow_id", - aws_key: "aws_key", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ], - blocks: [ - { - block_type: "action", - label: "label", - output_parameter: { - key: "key", - output_parameter_id: "output_parameter_id", - workflow_id: "workflow_id", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - }, - ], - finally_block_label: "finally_block_label", - error_code_mapping: { - key: "value", - }, - workflow_system_prompt: "workflow_system_prompt", - }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - persist_browser_session: true, - browser_profile_id: "browser_profile_id", - model: { - key: "value", - }, - status: "published", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - extra_http_headers: { - key: "value", - }, - cdp_connect_headers: { - key: "value", - }, - run_with: "run_with", - ai_fallback: true, - cache_key: "cache_key", - adaptive_caching: true, - code_version: 1, - generate_script_on_terminal: true, - run_sequentially: true, - sequential_key: "sequential_key", - folder_id: "folder_id", - import_error: "import_error", - created_by: "created_by", - edited_by: "edited_by", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - deleted_at: "2024-01-15T09:30:00Z", + workflow_count: 1, }); }); - test("update_workflow_folder (2)", async () => { + test("update_tag_key (2)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); const rawRequestBody = {}; const rawResponseBody = { key: "value" }; server .mockEndpoint() - .put("/v1/workflows/workflow_permanent_id/folder") - .jsonBody(rawRequestBody) - .respondWith() - .statusCode(400) - .jsonBody(rawResponseBody) - .build(); - - await expect(async () => { - return await client.updateWorkflowFolder("workflow_permanent_id"); - }).rejects.toThrow(Skyvern.BadRequestError); - }); - - test("update_workflow_folder (3)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - const rawRequestBody = {}; - const rawResponseBody = { key: "value" }; - server - .mockEndpoint() - .put("/v1/workflows/workflow_permanent_id/folder") + .patch("/v1/tag-keys/key") .jsonBody(rawRequestBody) .respondWith() .statusCode(404) @@ -1718,18 +1654,18 @@ describe("SkyvernClient", () => { .build(); await expect(async () => { - return await client.updateWorkflowFolder("workflow_permanent_id"); + return await client.updateTagKey("key"); }).rejects.toThrow(Skyvern.NotFoundError); }); - test("update_workflow_folder (4)", async () => { + test("update_tag_key (3)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); const rawRequestBody = {}; const rawResponseBody = { key: "value" }; server .mockEndpoint() - .put("/v1/workflows/workflow_permanent_id/folder") + .patch("/v1/tag-keys/key") .jsonBody(rawRequestBody) .respondWith() .statusCode(422) @@ -1737,7 +1673,116 @@ describe("SkyvernClient", () => { .build(); await expect(async () => { - return await client.updateWorkflowFolder("workflow_permanent_id"); + return await client.updateTagKey("key"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("batch_get_workflow_tags (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { workflow_tags: { key: [{ value: "value" }] } }; + server.mockEndpoint().get("/v1/workflow-tags").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.batchGetWorkflowTags({ + workflow_permanent_ids: "workflow_permanent_ids", + }); + expect(response).toEqual({ + workflow_tags: { + key: [ + { + value: "value", + }, + ], + }, + }); + }); + + test("batch_get_workflow_tags (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/workflow-tags").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.batchGetWorkflowTags(); + }).rejects.toThrow(Skyvern.BadRequestError); + }); + + test("batch_get_workflow_tags (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/workflow-tags").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.batchGetWorkflowTags(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("batch_get_workflow_tags_post (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { workflow_tags: { key: [{ value: "value" }] } }; + server + .mockEndpoint() + .post("/v1/workflow-tags") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.batchGetWorkflowTagsPost(); + expect(response).toEqual({ + workflow_tags: { + key: [ + { + value: "value", + }, + ], + }, + }); + }); + + test("batch_get_workflow_tags_post (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/workflow-tags") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.batchGetWorkflowTagsPost(); + }).rejects.toThrow(Skyvern.BadRequestError); + }); + + test("batch_get_workflow_tags_post (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/workflow-tags") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.batchGetWorkflowTagsPost(); }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); @@ -2114,208 +2159,19 @@ describe("SkyvernClient", () => { }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); - test("retry_workflow_run (1)", async () => { + test("get_version", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - const rawResponseBody = { - run_id: "tsk_123", - status: "created", - output: { key: "value" }, - downloaded_files: [ - { - url: "url", - checksum: "checksum", - filename: "filename", - file_size: 1, - modified_at: "2024-01-15T09:30:00Z", - artifact_id: "artifact_id", - }, - ], - recording_url: "recording_url", - recording_archived: true, - screenshot_urls: ["screenshot_urls"], - failure_reason: "failure_reason", - created_at: "2025-01-01T00:00:00Z", - modified_at: "2025-01-01T00:05:00Z", - queued_at: "2024-01-15T09:30:00Z", - started_at: "2024-01-15T09:30:00Z", - finished_at: "2024-01-15T09:30:00Z", - app_url: "app_url", - browser_session_id: "browser_session_id", - browser_profile_id: "browser_profile_id", - max_screenshot_scrolls: 1, - script_run: { - ai_fallback_triggered: true, - script_id: "script_id", - script_revision_id: "script_revision_id", - }, - errors: [{ key: "value" }], - step_count: 1, - run_with: "agent", - ai_fallback: true, - script_id: "script_id", - run_request: { - workflow_id: "wpid_123", - parameters: { key: "value" }, - title: "title", - proxy_location: "RESIDENTIAL", - webhook_url: "webhook_url", - totp_url: "totp_url", - totp_identifier: "totp_identifier", - browser_session_id: "browser_session_id", - browser_profile_id: "browser_profile_id", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - extra_http_headers: { key: "value" }, - cdp_connect_headers: { key: "value" }, - browser_address: "browser_address", - ai_fallback: true, - run_with: "run_with", - run_metadata: { key: "value" }, - }, - }; - server - .mockEndpoint() - .post("/v1/workflows/runs/wr_123/retry") - .header("x-max-steps-override", "1") - .header("x-user-agent", "x-user-agent") - .respondWith() - .statusCode(200) - .jsonBody(rawResponseBody) - .build(); + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/version").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); - const response = await client.retryWorkflowRun("wr_123", { - "x-max-steps-override": 1, - "x-user-agent": "x-user-agent", - }); + const response = await client.getVersion(); expect(response).toEqual({ - run_id: "tsk_123", - status: "created", - output: { - key: "value", - }, - downloaded_files: [ - { - url: "url", - checksum: "checksum", - filename: "filename", - file_size: 1, - modified_at: "2024-01-15T09:30:00Z", - artifact_id: "artifact_id", - }, - ], - recording_url: "recording_url", - recording_archived: true, - screenshot_urls: ["screenshot_urls"], - failure_reason: "failure_reason", - created_at: "2025-01-01T00:00:00Z", - modified_at: "2025-01-01T00:05:00Z", - queued_at: "2024-01-15T09:30:00Z", - started_at: "2024-01-15T09:30:00Z", - finished_at: "2024-01-15T09:30:00Z", - app_url: "app_url", - browser_session_id: "browser_session_id", - browser_profile_id: "browser_profile_id", - max_screenshot_scrolls: 1, - script_run: { - ai_fallback_triggered: true, - script_id: "script_id", - script_revision_id: "script_revision_id", - }, - errors: [ - { - key: "value", - }, - ], - step_count: 1, - run_with: "agent", - ai_fallback: true, - script_id: "script_id", - run_request: { - workflow_id: "wpid_123", - parameters: { - key: "value", - }, - title: "title", - proxy_location: "RESIDENTIAL", - webhook_url: "webhook_url", - totp_url: "totp_url", - totp_identifier: "totp_identifier", - browser_session_id: "browser_session_id", - browser_profile_id: "browser_profile_id", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - extra_http_headers: { - key: "value", - }, - cdp_connect_headers: { - key: "value", - }, - browser_address: "browser_address", - ai_fallback: true, - run_with: "run_with", - run_metadata: { - key: "value", - }, - }, + key: "value", }); }); - test("retry_workflow_run (2)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { key: "value" }; - server - .mockEndpoint() - .post("/v1/workflows/runs/workflow_run_id/retry") - .respondWith() - .statusCode(400) - .jsonBody(rawResponseBody) - .build(); - - await expect(async () => { - return await client.retryWorkflowRun("workflow_run_id"); - }).rejects.toThrow(Skyvern.BadRequestError); - }); - - test("retry_workflow_run (3)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { key: "value" }; - server - .mockEndpoint() - .post("/v1/workflows/runs/workflow_run_id/retry") - .respondWith() - .statusCode(404) - .jsonBody(rawResponseBody) - .build(); - - await expect(async () => { - return await client.retryWorkflowRun("workflow_run_id"); - }).rejects.toThrow(Skyvern.NotFoundError); - }); - - test("retry_workflow_run (4)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { key: "value" }; - server - .mockEndpoint() - .post("/v1/workflows/runs/workflow_run_id/retry") - .respondWith() - .statusCode(422) - .jsonBody(rawResponseBody) - .build(); - - await expect(async () => { - return await client.retryWorkflowRun("workflow_run_id"); - }).rejects.toThrow(Skyvern.UnprocessableEntityError); - }); - test("get_runs_v2 (1)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); @@ -2371,635 +2227,6 @@ describe("SkyvernClient", () => { }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); - test("get_workflow_runs (1)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = [ - { - workflow_run_id: "workflow_run_id", - workflow_id: "workflow_id", - workflow_permanent_id: "workflow_permanent_id", - organization_id: "organization_id", - browser_session_id: "browser_session_id", - browser_profile_id: "browser_profile_id", - debug_session_id: "debug_session_id", - status: "created", - extra_http_headers: { key: "value" }, - cdp_connect_headers: { key: "value" }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - webhook_failure_reason: "webhook_failure_reason", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - failure_reason: "failure_reason", - failure_category: [{ key: "value" }], - parent_workflow_run_id: "parent_workflow_run_id", - workflow_title: "workflow_title", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - browser_address: "browser_address", - run_with: "run_with", - script_run: { - ai_fallback_triggered: true, - script_id: "script_id", - script_revision_id: "script_revision_id", - }, - job_id: "job_id", - depends_on_workflow_run_id: "depends_on_workflow_run_id", - sequential_key: "sequential_key", - ai_fallback: true, - code_gen: true, - trigger_type: "manual", - workflow_schedule_id: "workflow_schedule_id", - ignore_inherited_workflow_system_prompt: true, - copilot_session_id: "copilot_session_id", - credits_used: 1, - cached_credits_used: 1, - queued_at: "2024-01-15T09:30:00Z", - started_at: "2024-01-15T09:30:00Z", - finished_at: "2024-01-15T09:30:00Z", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ]; - server.mockEndpoint().get("/v1/workflows/runs").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); - - const response = await client.getWorkflowRuns({ - page: 1, - page_size: 1, - search_key: "search_key", - error_code: "error_code", - }); - expect(response).toEqual([ - { - workflow_run_id: "workflow_run_id", - workflow_id: "workflow_id", - workflow_permanent_id: "workflow_permanent_id", - organization_id: "organization_id", - browser_session_id: "browser_session_id", - browser_profile_id: "browser_profile_id", - debug_session_id: "debug_session_id", - status: "created", - extra_http_headers: { - key: "value", - }, - cdp_connect_headers: { - key: "value", - }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - webhook_failure_reason: "webhook_failure_reason", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - failure_reason: "failure_reason", - failure_category: [ - { - key: "value", - }, - ], - parent_workflow_run_id: "parent_workflow_run_id", - workflow_title: "workflow_title", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - browser_address: "browser_address", - run_with: "run_with", - script_run: { - ai_fallback_triggered: true, - script_id: "script_id", - script_revision_id: "script_revision_id", - }, - job_id: "job_id", - depends_on_workflow_run_id: "depends_on_workflow_run_id", - sequential_key: "sequential_key", - ai_fallback: true, - code_gen: true, - trigger_type: "manual", - workflow_schedule_id: "workflow_schedule_id", - ignore_inherited_workflow_system_prompt: true, - copilot_session_id: "copilot_session_id", - credits_used: 1, - cached_credits_used: 1, - queued_at: "2024-01-15T09:30:00Z", - started_at: "2024-01-15T09:30:00Z", - finished_at: "2024-01-15T09:30:00Z", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ]); - }); - - test("get_workflow_runs (2)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { key: "value" }; - server.mockEndpoint().get("/v1/workflows/runs").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); - - await expect(async () => { - return await client.getWorkflowRuns(); - }).rejects.toThrow(Skyvern.UnprocessableEntityError); - }); - - test("get_workflow_runs_by_id (1)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = [ - { - workflow_run_id: "workflow_run_id", - workflow_id: "workflow_id", - workflow_permanent_id: "workflow_permanent_id", - organization_id: "organization_id", - browser_session_id: "browser_session_id", - browser_profile_id: "browser_profile_id", - debug_session_id: "debug_session_id", - status: "created", - extra_http_headers: { key: "value" }, - cdp_connect_headers: { key: "value" }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - webhook_failure_reason: "webhook_failure_reason", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - failure_reason: "failure_reason", - failure_category: [{ key: "value" }], - parent_workflow_run_id: "parent_workflow_run_id", - workflow_title: "workflow_title", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - browser_address: "browser_address", - run_with: "run_with", - script_run: { - ai_fallback_triggered: true, - script_id: "script_id", - script_revision_id: "script_revision_id", - }, - job_id: "job_id", - depends_on_workflow_run_id: "depends_on_workflow_run_id", - sequential_key: "sequential_key", - ai_fallback: true, - code_gen: true, - trigger_type: "manual", - workflow_schedule_id: "workflow_schedule_id", - ignore_inherited_workflow_system_prompt: true, - copilot_session_id: "copilot_session_id", - credits_used: 1, - cached_credits_used: 1, - queued_at: "2024-01-15T09:30:00Z", - started_at: "2024-01-15T09:30:00Z", - finished_at: "2024-01-15T09:30:00Z", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ]; - server - .mockEndpoint() - .get("/v1/workflows/workflow_id/runs") - .respondWith() - .statusCode(200) - .jsonBody(rawResponseBody) - .build(); - - const response = await client.getWorkflowRunsById("workflow_id", { - page: 1, - page_size: 1, - search_key: "search_key", - error_code: "error_code", - }); - expect(response).toEqual([ - { - workflow_run_id: "workflow_run_id", - workflow_id: "workflow_id", - workflow_permanent_id: "workflow_permanent_id", - organization_id: "organization_id", - browser_session_id: "browser_session_id", - browser_profile_id: "browser_profile_id", - debug_session_id: "debug_session_id", - status: "created", - extra_http_headers: { - key: "value", - }, - cdp_connect_headers: { - key: "value", - }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - webhook_failure_reason: "webhook_failure_reason", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - failure_reason: "failure_reason", - failure_category: [ - { - key: "value", - }, - ], - parent_workflow_run_id: "parent_workflow_run_id", - workflow_title: "workflow_title", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - browser_address: "browser_address", - run_with: "run_with", - script_run: { - ai_fallback_triggered: true, - script_id: "script_id", - script_revision_id: "script_revision_id", - }, - job_id: "job_id", - depends_on_workflow_run_id: "depends_on_workflow_run_id", - sequential_key: "sequential_key", - ai_fallback: true, - code_gen: true, - trigger_type: "manual", - workflow_schedule_id: "workflow_schedule_id", - ignore_inherited_workflow_system_prompt: true, - copilot_session_id: "copilot_session_id", - credits_used: 1, - cached_credits_used: 1, - queued_at: "2024-01-15T09:30:00Z", - started_at: "2024-01-15T09:30:00Z", - finished_at: "2024-01-15T09:30:00Z", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ]); - }); - - test("get_workflow_runs_by_id (2)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { key: "value" }; - server - .mockEndpoint() - .get("/v1/workflows/workflow_id/runs") - .respondWith() - .statusCode(422) - .jsonBody(rawResponseBody) - .build(); - - await expect(async () => { - return await client.getWorkflowRunsById("workflow_id"); - }).rejects.toThrow(Skyvern.UnprocessableEntityError); - }); - - test("get_workflow (1)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { - workflow_id: "workflow_id", - organization_id: "organization_id", - title: "title", - workflow_permanent_id: "workflow_permanent_id", - version: 1, - is_saved_task: true, - is_template: true, - description: "description", - workflow_definition: { - version: 1, - parameters: [ - { - parameter_type: "aws_secret", - key: "key", - aws_secret_parameter_id: "aws_secret_parameter_id", - workflow_id: "workflow_id", - aws_key: "aws_key", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ], - blocks: [ - { - block_type: "action", - label: "label", - output_parameter: { - key: "key", - output_parameter_id: "output_parameter_id", - workflow_id: "workflow_id", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - }, - ], - finally_block_label: "finally_block_label", - error_code_mapping: { key: "value" }, - workflow_system_prompt: "workflow_system_prompt", - }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - persist_browser_session: true, - browser_profile_id: "browser_profile_id", - model: { key: "value" }, - status: "published", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - extra_http_headers: { key: "value" }, - cdp_connect_headers: { key: "value" }, - run_with: "run_with", - ai_fallback: true, - cache_key: "cache_key", - adaptive_caching: true, - code_version: 1, - generate_script_on_terminal: true, - run_sequentially: true, - sequential_key: "sequential_key", - folder_id: "folder_id", - import_error: "import_error", - created_by: "created_by", - edited_by: "edited_by", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - deleted_at: "2024-01-15T09:30:00Z", - }; - server - .mockEndpoint() - .get("/v1/workflows/workflow_permanent_id") - .respondWith() - .statusCode(200) - .jsonBody(rawResponseBody) - .build(); - - const response = await client.getWorkflow("workflow_permanent_id", { - version: 1, - template: true, - }); - expect(response).toEqual({ - workflow_id: "workflow_id", - organization_id: "organization_id", - title: "title", - workflow_permanent_id: "workflow_permanent_id", - version: 1, - is_saved_task: true, - is_template: true, - description: "description", - workflow_definition: { - version: 1, - parameters: [ - { - parameter_type: "aws_secret", - key: "key", - aws_secret_parameter_id: "aws_secret_parameter_id", - workflow_id: "workflow_id", - aws_key: "aws_key", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ], - blocks: [ - { - block_type: "action", - label: "label", - output_parameter: { - key: "key", - output_parameter_id: "output_parameter_id", - workflow_id: "workflow_id", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - }, - ], - finally_block_label: "finally_block_label", - error_code_mapping: { - key: "value", - }, - workflow_system_prompt: "workflow_system_prompt", - }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - persist_browser_session: true, - browser_profile_id: "browser_profile_id", - model: { - key: "value", - }, - status: "published", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - extra_http_headers: { - key: "value", - }, - cdp_connect_headers: { - key: "value", - }, - run_with: "run_with", - ai_fallback: true, - cache_key: "cache_key", - adaptive_caching: true, - code_version: 1, - generate_script_on_terminal: true, - run_sequentially: true, - sequential_key: "sequential_key", - folder_id: "folder_id", - import_error: "import_error", - created_by: "created_by", - edited_by: "edited_by", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - deleted_at: "2024-01-15T09:30:00Z", - }); - }); - - test("get_workflow (2)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { key: "value" }; - server - .mockEndpoint() - .get("/v1/workflows/workflow_permanent_id") - .respondWith() - .statusCode(422) - .jsonBody(rawResponseBody) - .build(); - - await expect(async () => { - return await client.getWorkflow("workflow_permanent_id"); - }).rejects.toThrow(Skyvern.UnprocessableEntityError); - }); - - test("get_workflow_versions (1)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = [ - { - workflow_id: "workflow_id", - organization_id: "organization_id", - title: "title", - workflow_permanent_id: "workflow_permanent_id", - version: 1, - is_saved_task: true, - is_template: true, - description: "description", - workflow_definition: { - version: 1, - parameters: [ - { - parameter_type: "aws_secret", - key: "key", - aws_secret_parameter_id: "aws_secret_parameter_id", - workflow_id: "workflow_id", - aws_key: "aws_key", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ], - blocks: [ - { - block_type: "action", - label: "label", - output_parameter: { - key: "key", - output_parameter_id: "output_parameter_id", - workflow_id: "workflow_id", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - }, - ], - finally_block_label: "finally_block_label", - error_code_mapping: {}, - workflow_system_prompt: "workflow_system_prompt", - }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - persist_browser_session: true, - browser_profile_id: "browser_profile_id", - model: { key: "value" }, - status: "published", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - extra_http_headers: { key: "value" }, - cdp_connect_headers: { key: "value" }, - run_with: "run_with", - ai_fallback: true, - cache_key: "cache_key", - adaptive_caching: true, - code_version: 1, - generate_script_on_terminal: true, - run_sequentially: true, - sequential_key: "sequential_key", - folder_id: "folder_id", - import_error: "import_error", - created_by: "created_by", - edited_by: "edited_by", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - deleted_at: "2024-01-15T09:30:00Z", - }, - ]; - server - .mockEndpoint() - .get("/v1/workflows/workflow_permanent_id/versions") - .respondWith() - .statusCode(200) - .jsonBody(rawResponseBody) - .build(); - - const response = await client.getWorkflowVersions("workflow_permanent_id", { - template: true, - }); - expect(response).toEqual([ - { - workflow_id: "workflow_id", - organization_id: "organization_id", - title: "title", - workflow_permanent_id: "workflow_permanent_id", - version: 1, - is_saved_task: true, - is_template: true, - description: "description", - workflow_definition: { - version: 1, - parameters: [ - { - parameter_type: "aws_secret", - key: "key", - aws_secret_parameter_id: "aws_secret_parameter_id", - workflow_id: "workflow_id", - aws_key: "aws_key", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - ], - blocks: [ - { - block_type: "action", - label: "label", - output_parameter: { - key: "key", - output_parameter_id: "output_parameter_id", - workflow_id: "workflow_id", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - }, - }, - ], - finally_block_label: "finally_block_label", - error_code_mapping: {}, - workflow_system_prompt: "workflow_system_prompt", - }, - proxy_location: "RESIDENTIAL", - webhook_callback_url: "webhook_callback_url", - totp_verification_url: "totp_verification_url", - totp_identifier: "totp_identifier", - persist_browser_session: true, - browser_profile_id: "browser_profile_id", - model: { - key: "value", - }, - status: "published", - max_screenshot_scrolls: 1, - max_elapsed_time_minutes: 1, - extra_http_headers: { - key: "value", - }, - cdp_connect_headers: { - key: "value", - }, - run_with: "run_with", - ai_fallback: true, - cache_key: "cache_key", - adaptive_caching: true, - code_version: 1, - generate_script_on_terminal: true, - run_sequentially: true, - sequential_key: "sequential_key", - folder_id: "folder_id", - import_error: "import_error", - created_by: "created_by", - edited_by: "edited_by", - created_at: "2024-01-15T09:30:00Z", - modified_at: "2024-01-15T09:30:00Z", - deleted_at: "2024-01-15T09:30:00Z", - }, - ]); - }); - - test("get_workflow_versions (2)", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { key: "value" }; - server - .mockEndpoint() - .get("/v1/workflows/workflow_permanent_id/versions") - .respondWith() - .statusCode(422) - .jsonBody(rawResponseBody) - .build(); - - await expect(async () => { - return await client.getWorkflowVersions("workflow_permanent_id"); - }).rejects.toThrow(Skyvern.UnprocessableEntityError); - }); - test("list_browser_profiles (1)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); @@ -3011,6 +2238,11 @@ describe("SkyvernClient", () => { name: "name", description: "description", source_browser_type: "source_browser_type", + proxy_location: "RESIDENTIAL", + proxy_session_id: "proxy_session_id", + is_managed: true, + workflow_permanent_id: "workflow_permanent_id", + browser_profile_key_digest: "browser_profile_key_digest", created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", @@ -3037,6 +2269,11 @@ describe("SkyvernClient", () => { name: "name", description: "description", source_browser_type: "source_browser_type", + proxy_location: "RESIDENTIAL", + proxy_session_id: "proxy_session_id", + is_managed: true, + workflow_permanent_id: "workflow_permanent_id", + browser_profile_key_digest: "browser_profile_key_digest", created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", @@ -3072,6 +2309,11 @@ describe("SkyvernClient", () => { name: "name", description: "description", source_browser_type: "source_browser_type", + proxy_location: "RESIDENTIAL", + proxy_session_id: "proxy_session_id", + is_managed: true, + workflow_permanent_id: "workflow_permanent_id", + browser_profile_key_digest: "browser_profile_key_digest", created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", @@ -3094,6 +2336,11 @@ describe("SkyvernClient", () => { name: "name", description: "description", source_browser_type: "source_browser_type", + proxy_location: "RESIDENTIAL", + proxy_session_id: "proxy_session_id", + is_managed: true, + workflow_permanent_id: "workflow_permanent_id", + browser_profile_key_digest: "browser_profile_key_digest", created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", @@ -3173,6 +2420,11 @@ describe("SkyvernClient", () => { name: "name", description: "description", source_browser_type: "source_browser_type", + proxy_location: "RESIDENTIAL", + proxy_session_id: "proxy_session_id", + is_managed: true, + workflow_permanent_id: "workflow_permanent_id", + browser_profile_key_digest: "browser_profile_key_digest", created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", @@ -3192,6 +2444,11 @@ describe("SkyvernClient", () => { name: "name", description: "description", source_browser_type: "source_browser_type", + proxy_location: "RESIDENTIAL", + proxy_session_id: "proxy_session_id", + is_managed: true, + workflow_permanent_id: "workflow_permanent_id", + browser_profile_key_digest: "browser_profile_key_digest", created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", @@ -3290,6 +2547,11 @@ describe("SkyvernClient", () => { name: "name", description: "description", source_browser_type: "source_browser_type", + proxy_location: "RESIDENTIAL", + proxy_session_id: "proxy_session_id", + is_managed: true, + workflow_permanent_id: "workflow_permanent_id", + browser_profile_key_digest: "browser_profile_key_digest", created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", @@ -3310,6 +2572,11 @@ describe("SkyvernClient", () => { name: "name", description: "description", source_browser_type: "source_browser_type", + proxy_location: "RESIDENTIAL", + proxy_session_id: "proxy_session_id", + is_managed: true, + workflow_permanent_id: "workflow_permanent_id", + browser_profile_key_digest: "browser_profile_key_digest", created_at: "2024-01-15T09:30:00Z", modified_at: "2024-01-15T09:30:00Z", deleted_at: "2024-01-15T09:30:00Z", @@ -3390,6 +2657,7 @@ describe("SkyvernClient", () => { extensions: ["ad-blocker"], browser_type: "msedge", browser_profile_id: "browser_profile_id", + generate_browser_profile: true, vnc_streaming_supported: true, download_path: "download_path", downloaded_files: [{ url: "url" }], @@ -3423,6 +2691,7 @@ describe("SkyvernClient", () => { extensions: ["ad-blocker"], browser_type: "msedge", browser_profile_id: "browser_profile_id", + generate_browser_profile: true, vnc_streaming_supported: true, download_path: "download_path", downloaded_files: [ @@ -3496,6 +2765,7 @@ describe("SkyvernClient", () => { extensions: ["ad-blocker"], browser_type: "msedge", browser_profile_id: "browser_profile_id", + generate_browser_profile: true, vnc_streaming_supported: true, download_path: "download_path", downloaded_files: [ @@ -3546,6 +2816,7 @@ describe("SkyvernClient", () => { extensions: ["ad-blocker"], browser_type: "msedge", browser_profile_id: "browser_profile_id", + generate_browser_profile: true, vnc_streaming_supported: true, download_path: "download_path", downloaded_files: [ @@ -3704,6 +2975,7 @@ describe("SkyvernClient", () => { extensions: ["ad-blocker"], browser_type: "msedge", browser_profile_id: "browser_profile_id", + generate_browser_profile: true, vnc_streaming_supported: true, download_path: "download_path", downloaded_files: [ @@ -3753,6 +3025,7 @@ describe("SkyvernClient", () => { extensions: ["ad-blocker"], browser_type: "msedge", browser_profile_id: "browser_profile_id", + generate_browser_profile: true, vnc_streaming_supported: true, download_path: "download_path", downloaded_files: [ @@ -3837,6 +3110,190 @@ describe("SkyvernClient", () => { }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); + test("update_browser_session (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { generate_browser_profile: true }; + const rawResponseBody = { + browser_session_id: "pbs_123456", + organization_id: "organization_id", + status: "status", + runnable_type: "runnable_type", + runnable_id: "runnable_id", + timeout: 1, + browser_address: "browser_address", + app_url: "app_url", + extensions: ["ad-blocker"], + browser_type: "msedge", + browser_profile_id: "browser_profile_id", + generate_browser_profile: true, + vnc_streaming_supported: true, + download_path: "download_path", + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + file_size: 1, + modified_at: "2024-01-15T09:30:00Z", + artifact_id: "artifact_id", + }, + ], + recordings: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + file_size: 1, + modified_at: "2024-01-15T09:30:00Z", + artifact_id: "artifact_id", + }, + ], + started_at: "2024-01-15T09:30:00Z", + completed_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .patch("/v1/browser_sessions/pbs_123456") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.updateBrowserSession("pbs_123456", { + generate_browser_profile: true, + }); + expect(response).toEqual({ + browser_session_id: "pbs_123456", + organization_id: "organization_id", + status: "status", + runnable_type: "runnable_type", + runnable_id: "runnable_id", + timeout: 1, + browser_address: "browser_address", + app_url: "app_url", + extensions: ["ad-blocker"], + browser_type: "msedge", + browser_profile_id: "browser_profile_id", + generate_browser_profile: true, + vnc_streaming_supported: true, + download_path: "download_path", + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + file_size: 1, + modified_at: "2024-01-15T09:30:00Z", + artifact_id: "artifact_id", + }, + ], + recordings: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + file_size: 1, + modified_at: "2024-01-15T09:30:00Z", + artifact_id: "artifact_id", + }, + ], + started_at: "2024-01-15T09:30:00Z", + completed_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }); + }); + + test("update_browser_session (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { generate_browser_profile: true }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .patch("/v1/browser_sessions/browser_session_id") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.updateBrowserSession("browser_session_id", { + generate_browser_profile: true, + }); + }).rejects.toThrow(Skyvern.ForbiddenError); + }); + + test("update_browser_session (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { generate_browser_profile: true }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .patch("/v1/browser_sessions/browser_session_id") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.updateBrowserSession("browser_session_id", { + generate_browser_profile: true, + }); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("update_browser_session (4)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { generate_browser_profile: true }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .patch("/v1/browser_sessions/browser_session_id") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(409) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.updateBrowserSession("browser_session_id", { + generate_browser_profile: true, + }); + }).rejects.toThrow(Skyvern.ConflictError); + }); + + test("update_browser_session (5)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { generate_browser_profile: true }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .patch("/v1/browser_sessions/browser_session_id") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.updateBrowserSession("browser_session_id", { + generate_browser_profile: true, + }); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + test("send_totp_code (1)", async () => { const server = mockServerPool.createServer(); const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); @@ -3927,11 +3384,12 @@ describe("SkyvernClient", () => { }, credential_type: "password", name: "Amazon Login", - vault_type: "bitwarden", + vault_type: "skyvern", browser_profile_id: "browser_profile_id", tested_url: "tested_url", user_context: "user_context", save_browser_session_intent: true, + folder_id: "folder_id", }, ]; server.mockEndpoint().get("/v1/credentials").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); @@ -3939,7 +3397,9 @@ describe("SkyvernClient", () => { const response = await client.getCredentials({ page: 1, page_size: 10, - vault_type: "bitwarden", + vault_type: "skyvern", + credential_type: "password", + search: "search", }); expect(response).toEqual([ { @@ -3951,11 +3411,12 @@ describe("SkyvernClient", () => { }, credential_type: "password", name: "Amazon Login", - vault_type: "bitwarden", + vault_type: "skyvern", browser_profile_id: "browser_profile_id", tested_url: "tested_url", user_context: "user_context", save_browser_session_intent: true, + folder_id: "folder_id", }, ]); }); @@ -3989,11 +3450,12 @@ describe("SkyvernClient", () => { }, credential_type: "password", name: "Amazon Login", - vault_type: "bitwarden", + vault_type: "skyvern", browser_profile_id: "browser_profile_id", tested_url: "tested_url", user_context: "user_context", save_browser_session_intent: true, + folder_id: "folder_id", }; server .mockEndpoint() @@ -4021,11 +3483,12 @@ describe("SkyvernClient", () => { }, credential_type: "password", name: "Amazon Login", - vault_type: "bitwarden", + vault_type: "skyvern", browser_profile_id: "browser_profile_id", tested_url: "tested_url", user_context: "user_context", save_browser_session_intent: true, + folder_id: "folder_id", }); }); @@ -4076,11 +3539,12 @@ describe("SkyvernClient", () => { }, credential_type: "password", name: "Amazon Login", - vault_type: "bitwarden", + vault_type: "skyvern", browser_profile_id: "browser_profile_id", tested_url: "tested_url", user_context: "user_context", save_browser_session_intent: true, + folder_id: "folder_id", }; server .mockEndpoint() @@ -4108,11 +3572,12 @@ describe("SkyvernClient", () => { }, credential_type: "password", name: "Amazon Login", - vault_type: "bitwarden", + vault_type: "skyvern", browser_profile_id: "browser_profile_id", tested_url: "tested_url", user_context: "user_context", save_browser_session_intent: true, + folder_id: "folder_id", }); }); @@ -4187,11 +3652,12 @@ describe("SkyvernClient", () => { }, credential_type: "password", name: "Amazon Login", - vault_type: "bitwarden", + vault_type: "skyvern", browser_profile_id: "browser_profile_id", tested_url: "tested_url", user_context: "user_context", save_browser_session_intent: true, + folder_id: "folder_id", }; server .mockEndpoint() @@ -4211,11 +3677,12 @@ describe("SkyvernClient", () => { }, credential_type: "password", name: "Amazon Login", - vault_type: "bitwarden", + vault_type: "skyvern", browser_profile_id: "browser_profile_id", tested_url: "tested_url", user_context: "user_context", save_browser_session_intent: true, + folder_id: "folder_id", }); }); @@ -4888,4 +4355,1345 @@ describe("SkyvernClient", () => { }); }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); + + test("update_workflow_folder (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + is_template: true, + description: "description", + workflow_definition: { + version: 1, + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + finally_block_label: "finally_block_label", + error_code_mapping: { key: "value" }, + workflow_system_prompt: "workflow_system_prompt", + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + browser_profile_id: "browser_profile_id", + model: { key: "value" }, + status: "published", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + extra_http_headers: { key: "value" }, + cdp_connect_headers: { key: "value" }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + adaptive_caching: true, + code_version: 1, + generate_script_on_terminal: true, + run_sequentially: true, + sequential_key: "sequential_key", + folder_id: "folder_id", + import_error: "import_error", + created_by: "created_by", + edited_by: "edited_by", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", + }; + server + .mockEndpoint() + .put("/v1/agents/wpid_123/folder") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.updateWorkflowFolder("wpid_123"); + expect(response).toEqual({ + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + is_template: true, + description: "description", + workflow_definition: { + version: 1, + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + finally_block_label: "finally_block_label", + error_code_mapping: { + key: "value", + }, + workflow_system_prompt: "workflow_system_prompt", + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + browser_profile_id: "browser_profile_id", + model: { + key: "value", + }, + status: "published", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + extra_http_headers: { + key: "value", + }, + cdp_connect_headers: { + key: "value", + }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + adaptive_caching: true, + code_version: 1, + generate_script_on_terminal: true, + run_sequentially: true, + sequential_key: "sequential_key", + folder_id: "folder_id", + import_error: "import_error", + created_by: "created_by", + edited_by: "edited_by", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", + }); + }); + + test("update_workflow_folder (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .put("/v1/agents/workflow_permanent_id/folder") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.updateWorkflowFolder("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.BadRequestError); + }); + + test("update_workflow_folder (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .put("/v1/agents/workflow_permanent_id/folder") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.updateWorkflowFolder("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("update_workflow_folder (4)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .put("/v1/agents/workflow_permanent_id/folder") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.updateWorkflowFolder("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_workflow_tags (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + workflow_permanent_id: "workflow_permanent_id", + tags: [{ key: "key", value: "value", source: "source", set_at: "2024-01-15T09:30:00Z", set_by: "set_by" }], + }; + server + .mockEndpoint() + .get("/v1/agents/wpid_123/tags") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getWorkflowTags("wpid_123"); + expect(response).toEqual({ + workflow_permanent_id: "workflow_permanent_id", + tags: [ + { + key: "key", + value: "value", + source: "source", + set_at: "2024-01-15T09:30:00Z", + set_by: "set_by", + }, + ], + }); + }); + + test("get_workflow_tags (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/agents/workflow_permanent_id/tags") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getWorkflowTags("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("get_workflow_tags (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/agents/workflow_permanent_id/tags") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getWorkflowTags("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("apply_workflow_tags (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { + workflow_permanent_id: "workflow_permanent_id", + tags: [{ key: "key", value: "value", source: "source", set_at: "2024-01-15T09:30:00Z", set_by: "set_by" }], + }; + server + .mockEndpoint() + .post("/v1/agents/wpid_123/tags") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.applyWorkflowTags("wpid_123"); + expect(response).toEqual({ + workflow_permanent_id: "workflow_permanent_id", + tags: [ + { + key: "key", + value: "value", + source: "source", + set_at: "2024-01-15T09:30:00Z", + set_by: "set_by", + }, + ], + }); + }); + + test("apply_workflow_tags (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/agents/workflow_permanent_id/tags") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.applyWorkflowTags("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("apply_workflow_tags (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/agents/workflow_permanent_id/tags") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.applyWorkflowTags("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("delete_workflow_tag (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + workflow_permanent_id: "workflow_permanent_id", + tags: [{ key: "key", value: "value", source: "source", set_at: "2024-01-15T09:30:00Z", set_by: "set_by" }], + }; + server + .mockEndpoint() + .delete("/v1/agents/wpid_123/tags/env") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.deleteWorkflowTag("wpid_123", "env"); + expect(response).toEqual({ + workflow_permanent_id: "workflow_permanent_id", + tags: [ + { + key: "key", + value: "value", + source: "source", + set_at: "2024-01-15T09:30:00Z", + set_by: "set_by", + }, + ], + }); + }); + + test("delete_workflow_tag (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/agents/workflow_permanent_id/tags/key") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deleteWorkflowTag("workflow_permanent_id", "key"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("delete_workflow_tag (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/agents/workflow_permanent_id/tags/key") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deleteWorkflowTag("workflow_permanent_id", "key"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_workflow_tag_history (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + workflow_permanent_id: "workflow_permanent_id", + events: [ + { + tag_event_id: "tag_event_id", + key: "key", + value: "value", + event_type: "event_type", + source: "source", + set_at: "2024-01-15T09:30:00Z", + set_by: "set_by", + superseded_at: "2024-01-15T09:30:00Z", + }, + ], + }; + server + .mockEndpoint() + .get("/v1/agents/wpid_123/tags/history") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getWorkflowTagHistory("wpid_123", { + limit: 1, + since: "2024-01-15T09:30:00Z", + key: "key", + }); + expect(response).toEqual({ + workflow_permanent_id: "workflow_permanent_id", + events: [ + { + tag_event_id: "tag_event_id", + key: "key", + value: "value", + event_type: "event_type", + source: "source", + set_at: "2024-01-15T09:30:00Z", + set_by: "set_by", + superseded_at: "2024-01-15T09:30:00Z", + }, + ], + }); + }); + + test("get_workflow_tag_history (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/agents/workflow_permanent_id/tags/history") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getWorkflowTagHistory("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("get_workflow_tag_history (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/agents/workflow_permanent_id/tags/history") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getWorkflowTagHistory("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("retry_workflow_run (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + run_id: "tsk_123", + status: "created", + output: { key: "value" }, + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + file_size: 1, + modified_at: "2024-01-15T09:30:00Z", + artifact_id: "artifact_id", + }, + ], + recording_url: "recording_url", + recording_archived: true, + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", + max_screenshot_scrolls: 1, + script_run: { + ai_fallback_triggered: true, + script_id: "script_id", + script_revision_id: "script_revision_id", + }, + errors: [{ key: "value" }], + step_count: 1, + run_with: "agent", + ai_fallback: true, + script_id: "script_id", + run_request: { + workflow_id: "wpid_123", + parameters: { key: "value" }, + title: "title", + proxy_location: "RESIDENTIAL", + webhook_url: "webhook_url", + totp_url: "totp_url", + totp_identifier: "totp_identifier", + browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + extra_http_headers: { key: "value" }, + cdp_connect_headers: { key: "value" }, + browser_address: "browser_address", + ai_fallback: true, + run_with: "run_with", + run_metadata: { key: "value" }, + }, + }; + server + .mockEndpoint() + .post("/v1/agents/runs/wr_123/retry") + .header("x-max-steps-override", "1") + .header("x-user-agent", "x-user-agent") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.retryWorkflowRun("wr_123", { + "x-max-steps-override": 1, + "x-user-agent": "x-user-agent", + }); + expect(response).toEqual({ + run_id: "tsk_123", + status: "created", + output: { + key: "value", + }, + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + file_size: 1, + modified_at: "2024-01-15T09:30:00Z", + artifact_id: "artifact_id", + }, + ], + recording_url: "recording_url", + recording_archived: true, + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", + max_screenshot_scrolls: 1, + script_run: { + ai_fallback_triggered: true, + script_id: "script_id", + script_revision_id: "script_revision_id", + }, + errors: [ + { + key: "value", + }, + ], + step_count: 1, + run_with: "agent", + ai_fallback: true, + script_id: "script_id", + run_request: { + workflow_id: "wpid_123", + parameters: { + key: "value", + }, + title: "title", + proxy_location: "RESIDENTIAL", + webhook_url: "webhook_url", + totp_url: "totp_url", + totp_identifier: "totp_identifier", + browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + extra_http_headers: { + key: "value", + }, + cdp_connect_headers: { + key: "value", + }, + browser_address: "browser_address", + ai_fallback: true, + run_with: "run_with", + run_metadata: { + key: "value", + }, + }, + }); + }); + + test("retry_workflow_run (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/agents/runs/workflow_run_id/retry") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.retryWorkflowRun("workflow_run_id"); + }).rejects.toThrow(Skyvern.BadRequestError); + }); + + test("retry_workflow_run (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/agents/runs/workflow_run_id/retry") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.retryWorkflowRun("workflow_run_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("retry_workflow_run (4)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/agents/runs/workflow_run_id/retry") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.retryWorkflowRun("workflow_run_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_workflow_runs (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + workflow_run_id: "workflow_run_id", + workflow_id: "workflow_id", + workflow_permanent_id: "workflow_permanent_id", + organization_id: "organization_id", + browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", + debug_session_id: "debug_session_id", + status: "created", + extra_http_headers: { key: "value" }, + cdp_connect_headers: { key: "value" }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + webhook_failure_reason: "webhook_failure_reason", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + failure_reason: "failure_reason", + failure_category: [{ key: "value" }], + parent_workflow_run_id: "parent_workflow_run_id", + workflow_title: "workflow_title", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + browser_address: "browser_address", + run_with: "run_with", + script_run: { + ai_fallback_triggered: true, + script_id: "script_id", + script_revision_id: "script_revision_id", + }, + job_id: "job_id", + depends_on_workflow_run_id: "depends_on_workflow_run_id", + sequential_key: "sequential_key", + ai_fallback: true, + code_gen: true, + trigger_type: "manual", + workflow_schedule_id: "workflow_schedule_id", + ignore_inherited_workflow_system_prompt: true, + copilot_session_id: "copilot_session_id", + credits_used: 1, + cached_credits_used: 1, + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ]; + server.mockEndpoint().get("/v1/agents/runs").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.getWorkflowRuns({ + page: 1, + page_size: 1, + search_key: "search_key", + error_code: "error_code", + }); + expect(response).toEqual([ + { + workflow_run_id: "workflow_run_id", + workflow_id: "workflow_id", + workflow_permanent_id: "workflow_permanent_id", + organization_id: "organization_id", + browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", + debug_session_id: "debug_session_id", + status: "created", + extra_http_headers: { + key: "value", + }, + cdp_connect_headers: { + key: "value", + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + webhook_failure_reason: "webhook_failure_reason", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + failure_reason: "failure_reason", + failure_category: [ + { + key: "value", + }, + ], + parent_workflow_run_id: "parent_workflow_run_id", + workflow_title: "workflow_title", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + browser_address: "browser_address", + run_with: "run_with", + script_run: { + ai_fallback_triggered: true, + script_id: "script_id", + script_revision_id: "script_revision_id", + }, + job_id: "job_id", + depends_on_workflow_run_id: "depends_on_workflow_run_id", + sequential_key: "sequential_key", + ai_fallback: true, + code_gen: true, + trigger_type: "manual", + workflow_schedule_id: "workflow_schedule_id", + ignore_inherited_workflow_system_prompt: true, + copilot_session_id: "copilot_session_id", + credits_used: 1, + cached_credits_used: 1, + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ]); + }); + + test("get_workflow_runs (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/agents/runs").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.getWorkflowRuns(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_workflow_runs_by_id (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + workflow_run_id: "workflow_run_id", + workflow_id: "workflow_id", + workflow_permanent_id: "workflow_permanent_id", + organization_id: "organization_id", + browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", + debug_session_id: "debug_session_id", + status: "created", + extra_http_headers: { key: "value" }, + cdp_connect_headers: { key: "value" }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + webhook_failure_reason: "webhook_failure_reason", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + failure_reason: "failure_reason", + failure_category: [{ key: "value" }], + parent_workflow_run_id: "parent_workflow_run_id", + workflow_title: "workflow_title", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + browser_address: "browser_address", + run_with: "run_with", + script_run: { + ai_fallback_triggered: true, + script_id: "script_id", + script_revision_id: "script_revision_id", + }, + job_id: "job_id", + depends_on_workflow_run_id: "depends_on_workflow_run_id", + sequential_key: "sequential_key", + ai_fallback: true, + code_gen: true, + trigger_type: "manual", + workflow_schedule_id: "workflow_schedule_id", + ignore_inherited_workflow_system_prompt: true, + copilot_session_id: "copilot_session_id", + credits_used: 1, + cached_credits_used: 1, + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ]; + server + .mockEndpoint() + .get("/v1/agents/workflow_id/runs") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getWorkflowRunsById("workflow_id", { + page: 1, + page_size: 1, + search_key: "search_key", + error_code: "error_code", + }); + expect(response).toEqual([ + { + workflow_run_id: "workflow_run_id", + workflow_id: "workflow_id", + workflow_permanent_id: "workflow_permanent_id", + organization_id: "organization_id", + browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", + debug_session_id: "debug_session_id", + status: "created", + extra_http_headers: { + key: "value", + }, + cdp_connect_headers: { + key: "value", + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + webhook_failure_reason: "webhook_failure_reason", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + failure_reason: "failure_reason", + failure_category: [ + { + key: "value", + }, + ], + parent_workflow_run_id: "parent_workflow_run_id", + workflow_title: "workflow_title", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + browser_address: "browser_address", + run_with: "run_with", + script_run: { + ai_fallback_triggered: true, + script_id: "script_id", + script_revision_id: "script_revision_id", + }, + job_id: "job_id", + depends_on_workflow_run_id: "depends_on_workflow_run_id", + sequential_key: "sequential_key", + ai_fallback: true, + code_gen: true, + trigger_type: "manual", + workflow_schedule_id: "workflow_schedule_id", + ignore_inherited_workflow_system_prompt: true, + copilot_session_id: "copilot_session_id", + credits_used: 1, + cached_credits_used: 1, + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ]); + }); + + test("get_workflow_runs_by_id (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/agents/workflow_id/runs") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getWorkflowRunsById("workflow_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_workflow (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + is_template: true, + description: "description", + workflow_definition: { + version: 1, + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + finally_block_label: "finally_block_label", + error_code_mapping: { key: "value" }, + workflow_system_prompt: "workflow_system_prompt", + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + browser_profile_id: "browser_profile_id", + model: { key: "value" }, + status: "published", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + extra_http_headers: { key: "value" }, + cdp_connect_headers: { key: "value" }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + adaptive_caching: true, + code_version: 1, + generate_script_on_terminal: true, + run_sequentially: true, + sequential_key: "sequential_key", + folder_id: "folder_id", + import_error: "import_error", + created_by: "created_by", + edited_by: "edited_by", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", + }; + server + .mockEndpoint() + .get("/v1/agents/workflow_permanent_id") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getWorkflow("workflow_permanent_id", { + version: 1, + template: true, + }); + expect(response).toEqual({ + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + is_template: true, + description: "description", + workflow_definition: { + version: 1, + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + finally_block_label: "finally_block_label", + error_code_mapping: { + key: "value", + }, + workflow_system_prompt: "workflow_system_prompt", + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + browser_profile_id: "browser_profile_id", + model: { + key: "value", + }, + status: "published", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + extra_http_headers: { + key: "value", + }, + cdp_connect_headers: { + key: "value", + }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + adaptive_caching: true, + code_version: 1, + generate_script_on_terminal: true, + run_sequentially: true, + sequential_key: "sequential_key", + folder_id: "folder_id", + import_error: "import_error", + created_by: "created_by", + edited_by: "edited_by", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", + }); + }); + + test("get_workflow (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/agents/workflow_permanent_id") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getWorkflow("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_workflow_versions (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + is_template: true, + description: "description", + workflow_definition: { + version: 1, + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + finally_block_label: "finally_block_label", + error_code_mapping: {}, + workflow_system_prompt: "workflow_system_prompt", + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + browser_profile_id: "browser_profile_id", + model: { key: "value" }, + status: "published", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + extra_http_headers: { key: "value" }, + cdp_connect_headers: { key: "value" }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + adaptive_caching: true, + code_version: 1, + generate_script_on_terminal: true, + run_sequentially: true, + sequential_key: "sequential_key", + folder_id: "folder_id", + import_error: "import_error", + created_by: "created_by", + edited_by: "edited_by", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", + }, + ]; + server + .mockEndpoint() + .get("/v1/agents/workflow_permanent_id/versions") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getWorkflowVersions("workflow_permanent_id", { + template: true, + }); + expect(response).toEqual([ + { + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + is_template: true, + description: "description", + workflow_definition: { + version: 1, + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + finally_block_label: "finally_block_label", + error_code_mapping: {}, + workflow_system_prompt: "workflow_system_prompt", + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + browser_profile_id: "browser_profile_id", + model: { + key: "value", + }, + status: "published", + max_screenshot_scrolls: 1, + max_elapsed_time_minutes: 1, + extra_http_headers: { + key: "value", + }, + cdp_connect_headers: { + key: "value", + }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + adaptive_caching: true, + code_version: 1, + generate_script_on_terminal: true, + run_sequentially: true, + sequential_key: "sequential_key", + folder_id: "folder_id", + import_error: "import_error", + created_by: "created_by", + edited_by: "edited_by", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + agent_id: "agent_id", + }, + ]); + }); + + test("get_workflow_versions (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/agents/workflow_permanent_id/versions") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getWorkflowVersions("workflow_permanent_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); }); diff --git a/skyvern-ts/client/tests/wire/schedules.test.ts b/skyvern-ts/client/tests/wire/schedules.test.ts index 4dac0160e..b295b43ce 100644 --- a/skyvern-ts/client/tests/wire/schedules.test.ts +++ b/skyvern-ts/client/tests/wire/schedules.test.ts @@ -102,7 +102,7 @@ describe("Schedules", () => { }; server .mockEndpoint() - .get("/v1/workflows/workflow_permanent_id/schedules") + .get("/v1/agents/workflow_permanent_id/schedules") .respondWith() .statusCode(200) .jsonBody(rawResponseBody) @@ -139,7 +139,7 @@ describe("Schedules", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .get("/v1/workflows/workflow_permanent_id/schedules") + .get("/v1/agents/workflow_permanent_id/schedules") .respondWith() .statusCode(422) .jsonBody(rawResponseBody) @@ -174,7 +174,7 @@ describe("Schedules", () => { }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/schedules") + .post("/v1/agents/workflow_permanent_id/schedules") .jsonBody(rawRequestBody) .respondWith() .statusCode(200) @@ -214,7 +214,7 @@ describe("Schedules", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/schedules") + .post("/v1/agents/workflow_permanent_id/schedules") .jsonBody(rawRequestBody) .respondWith() .statusCode(422) @@ -253,7 +253,7 @@ describe("Schedules", () => { }; server .mockEndpoint() - .get("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id") + .get("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id") .respondWith() .statusCode(200) .jsonBody(rawResponseBody) @@ -289,7 +289,7 @@ describe("Schedules", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .get("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id") + .get("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id") .respondWith() .statusCode(422) .jsonBody(rawResponseBody) @@ -324,7 +324,7 @@ describe("Schedules", () => { }; server .mockEndpoint() - .put("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id") + .put("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id") .jsonBody(rawRequestBody) .respondWith() .statusCode(200) @@ -364,7 +364,7 @@ describe("Schedules", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .put("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id") + .put("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id") .jsonBody(rawRequestBody) .respondWith() .statusCode(422) @@ -386,7 +386,7 @@ describe("Schedules", () => { const rawResponseBody = { ok: true }; server .mockEndpoint() - .delete("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id") + .delete("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id") .respondWith() .statusCode(200) .jsonBody(rawResponseBody) @@ -405,7 +405,7 @@ describe("Schedules", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .delete("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id") + .delete("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id") .respondWith() .statusCode(422) .jsonBody(rawResponseBody) @@ -440,7 +440,7 @@ describe("Schedules", () => { }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id/enable") + .post("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id/enable") .respondWith() .statusCode(200) .jsonBody(rawResponseBody) @@ -476,7 +476,7 @@ describe("Schedules", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id/enable") + .post("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id/enable") .respondWith() .statusCode(422) .jsonBody(rawResponseBody) @@ -511,7 +511,7 @@ describe("Schedules", () => { }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id/disable") + .post("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id/disable") .respondWith() .statusCode(200) .jsonBody(rawResponseBody) @@ -547,7 +547,7 @@ describe("Schedules", () => { const rawResponseBody = { key: "value" }; server .mockEndpoint() - .post("/v1/workflows/workflow_permanent_id/schedules/workflow_schedule_id/disable") + .post("/v1/agents/workflow_permanent_id/schedules/workflow_schedule_id/disable") .respondWith() .statusCode(422) .jsonBody(rawResponseBody) diff --git a/skyvern-ts/client/tests/wire/server.test.ts b/skyvern-ts/client/tests/wire/server.test.ts deleted file mode 100644 index 8af278b6b..000000000 --- a/skyvern-ts/client/tests/wire/server.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -// This file was auto-generated by Fern from our API Definition. - -import { SkyvernClient } from "../../src/Client"; -import { mockServerPool } from "../mock-server/MockServerPool"; - -describe("Server", () => { - test("getVersion", async () => { - const server = mockServerPool.createServer(); - const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); - - const rawResponseBody = { key: "value" }; - server.mockEndpoint().get("/v1/version").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); - - const response = await client.server.getVersion(); - expect(response).toEqual({ - key: "value", - }); - }); -}); diff --git a/skyvern/client/__init__.py b/skyvern/client/__init__.py index 8d8ce2300..add7d0b01 100644 --- a/skyvern/client/__init__.py +++ b/skyvern/client/__init__.py @@ -28,6 +28,7 @@ if typing.TYPE_CHECKING: ActionOutput, ActionStatus, ActionType, + AiFallbackMode, Artifact, ArtifactType, AwsSecretParameter, @@ -50,6 +51,7 @@ if typing.TYPE_CHECKING: BranchCriteriaYaml, BranchCriteriaYamlCriteriaType, BrowserProfile, + BrowserProfileProxyLocation, BrowserSessionResponse, BulkCancelRunsResponse, ClickAction, @@ -86,9 +88,11 @@ if typing.TYPE_CHECKING: ContextParameterSource_Workflow, ContextParameterValue, ContextParameterYaml, + CreateBrowserProfileRequestProxyLocation, CreateBrowserSessionRequestProxyLocation, CreateCredentialRequest, CreateCredentialRequestCredential, + CreateCredentialRequestProxyLocation, CreateScriptResponse, CredentialParameter, CredentialParameterYaml, @@ -379,6 +383,15 @@ if typing.TYPE_CHECKING: SendEmailBlockYaml, SkyvernForgeSdkSchemasCredentialsCredentialType, SkyvernSchemasCredentialTypeCredentialType, + TagDeleteInput, + TagHistoryItem, + TagHistoryResponse, + TagInput, + TagItem, + TagKey, + TagKeyDeleteResponse, + TagResponse, + TagsResponse, TaskBlock, TaskBlockDataSchema, TaskBlockParametersItem, @@ -424,6 +437,7 @@ if typing.TYPE_CHECKING: ThoughtType, TotpCode, TotpType, + UpdateBrowserProfileRequestProxyLocation, UploadFileAction, UploadFileActionData, UploadFileResponse, @@ -649,6 +663,7 @@ if typing.TYPE_CHECKING: WorkflowScheduleResponse, WorkflowScheduleUpsertRequest, WorkflowStatus, + WorkflowTagsBatchResponse, WorkflowTriggerBlock, WorkflowTriggerBlockParametersItem, WorkflowTriggerBlockParametersItem_AwsSecret, @@ -673,7 +688,7 @@ if typing.TYPE_CHECKING: RangeNotSatisfiableError, UnprocessableEntityError, ) - from . import artifacts, schedules, scripts, server, workflows + from . import agents, artifacts, schedules, scripts from .client import AsyncSkyvern, Skyvern from .environment import SkyvernEnvironment from .schedules import SchedulesListAllRequestStatus @@ -700,6 +715,7 @@ _dynamic_imports: typing.Dict[str, str] = { "ActionOutput": ".types", "ActionStatus": ".types", "ActionType": ".types", + "AiFallbackMode": ".types", "Artifact": ".types", "ArtifactType": ".types", "AsyncSkyvern": ".client", @@ -724,6 +740,7 @@ _dynamic_imports: typing.Dict[str, str] = { "BranchCriteriaYaml": ".types", "BranchCriteriaYamlCriteriaType": ".types", "BrowserProfile": ".types", + "BrowserProfileProxyLocation": ".types", "BrowserSessionResponse": ".types", "BulkCancelRunsResponse": ".types", "ClickAction": ".types", @@ -761,9 +778,11 @@ _dynamic_imports: typing.Dict[str, str] = { "ContextParameterSource_Workflow": ".types", "ContextParameterValue": ".types", "ContextParameterYaml": ".types", + "CreateBrowserProfileRequestProxyLocation": ".types", "CreateBrowserSessionRequestProxyLocation": ".types", "CreateCredentialRequest": ".types", "CreateCredentialRequestCredential": ".types", + "CreateCredentialRequestProxyLocation": ".types", "CreateScriptResponse": ".types", "CredentialParameter": ".types", "CredentialParameterYaml": ".types", @@ -1061,6 +1080,15 @@ _dynamic_imports: typing.Dict[str, str] = { "SkyvernEnvironment": ".environment", "SkyvernForgeSdkSchemasCredentialsCredentialType": ".types", "SkyvernSchemasCredentialTypeCredentialType": ".types", + "TagDeleteInput": ".types", + "TagHistoryItem": ".types", + "TagHistoryResponse": ".types", + "TagInput": ".types", + "TagItem": ".types", + "TagKey": ".types", + "TagKeyDeleteResponse": ".types", + "TagResponse": ".types", + "TagsResponse": ".types", "TaskBlock": ".types", "TaskBlockDataSchema": ".types", "TaskBlockParametersItem": ".types", @@ -1107,6 +1135,7 @@ _dynamic_imports: typing.Dict[str, str] = { "TotpCode": ".types", "TotpType": ".types", "UnprocessableEntityError": ".errors", + "UpdateBrowserProfileRequestProxyLocation": ".types", "UploadFileAction": ".types", "UploadFileActionData": ".types", "UploadFileResponse": ".types", @@ -1332,6 +1361,7 @@ _dynamic_imports: typing.Dict[str, str] = { "WorkflowScheduleResponse": ".types", "WorkflowScheduleUpsertRequest": ".types", "WorkflowStatus": ".types", + "WorkflowTagsBatchResponse": ".types", "WorkflowTriggerBlock": ".types", "WorkflowTriggerBlockParametersItem": ".types", "WorkflowTriggerBlockParametersItem_AwsSecret": ".types", @@ -1347,11 +1377,10 @@ _dynamic_imports: typing.Dict[str, str] = { "WorkflowTriggerBlockParametersItem_Workflow": ".types", "WorkflowTriggerBlockYaml": ".types", "__version__": ".version", + "agents": ".agents", "artifacts": ".artifacts", "schedules": ".schedules", "scripts": ".scripts", - "server": ".server", - "workflows": ".workflows", } @@ -1398,6 +1427,7 @@ __all__ = [ "ActionOutput", "ActionStatus", "ActionType", + "AiFallbackMode", "Artifact", "ArtifactType", "AsyncSkyvern", @@ -1422,6 +1452,7 @@ __all__ = [ "BranchCriteriaYaml", "BranchCriteriaYamlCriteriaType", "BrowserProfile", + "BrowserProfileProxyLocation", "BrowserSessionResponse", "BulkCancelRunsResponse", "ClickAction", @@ -1459,9 +1490,11 @@ __all__ = [ "ContextParameterSource_Workflow", "ContextParameterValue", "ContextParameterYaml", + "CreateBrowserProfileRequestProxyLocation", "CreateBrowserSessionRequestProxyLocation", "CreateCredentialRequest", "CreateCredentialRequestCredential", + "CreateCredentialRequestProxyLocation", "CreateScriptResponse", "CredentialParameter", "CredentialParameterYaml", @@ -1759,6 +1792,15 @@ __all__ = [ "SkyvernEnvironment", "SkyvernForgeSdkSchemasCredentialsCredentialType", "SkyvernSchemasCredentialTypeCredentialType", + "TagDeleteInput", + "TagHistoryItem", + "TagHistoryResponse", + "TagInput", + "TagItem", + "TagKey", + "TagKeyDeleteResponse", + "TagResponse", + "TagsResponse", "TaskBlock", "TaskBlockDataSchema", "TaskBlockParametersItem", @@ -1805,6 +1847,7 @@ __all__ = [ "TotpCode", "TotpType", "UnprocessableEntityError", + "UpdateBrowserProfileRequestProxyLocation", "UploadFileAction", "UploadFileActionData", "UploadFileResponse", @@ -2030,6 +2073,7 @@ __all__ = [ "WorkflowScheduleResponse", "WorkflowScheduleUpsertRequest", "WorkflowStatus", + "WorkflowTagsBatchResponse", "WorkflowTriggerBlock", "WorkflowTriggerBlockParametersItem", "WorkflowTriggerBlockParametersItem_AwsSecret", @@ -2045,9 +2089,8 @@ __all__ = [ "WorkflowTriggerBlockParametersItem_Workflow", "WorkflowTriggerBlockYaml", "__version__", + "agents", "artifacts", "schedules", "scripts", - "server", - "workflows", ] diff --git a/skyvern/client/server/__init__.py b/skyvern/client/agents/__init__.py similarity index 100% rename from skyvern/client/server/__init__.py rename to skyvern/client/agents/__init__.py diff --git a/skyvern/client/workflows/client.py b/skyvern/client/agents/client.py similarity index 83% rename from skyvern/client/workflows/client.py rename to skyvern/client/agents/client.py index ce7c2c376..e3689780f 100644 --- a/skyvern/client/workflows/client.py +++ b/skyvern/client/agents/client.py @@ -4,21 +4,21 @@ import typing from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions -from .raw_client import AsyncRawWorkflowsClient, RawWorkflowsClient +from .raw_client import AsyncRawAgentsClient, RawAgentsClient -class WorkflowsClient: +class AgentsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): - self._raw_client = RawWorkflowsClient(client_wrapper=client_wrapper) + self._raw_client = RawAgentsClient(client_wrapper=client_wrapper) @property - def with_raw_response(self) -> RawWorkflowsClient: + def with_raw_response(self) -> RawAgentsClient: """ Retrieves a raw implementation of this client that returns raw responses. Returns ------- - RawWorkflowsClient + RawAgentsClient """ return self._raw_client @@ -47,7 +47,7 @@ class WorkflowsClient: client = Skyvern( api_key="YOUR_API_KEY", ) - client.workflows.reset_workflow_browser_profile( + client.agents.reset_workflow_browser_profile( workflow_permanent_id="wpid_123", ) """ @@ -57,18 +57,18 @@ class WorkflowsClient: return _response.data -class AsyncWorkflowsClient: +class AsyncAgentsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): - self._raw_client = AsyncRawWorkflowsClient(client_wrapper=client_wrapper) + self._raw_client = AsyncRawAgentsClient(client_wrapper=client_wrapper) @property - def with_raw_response(self) -> AsyncRawWorkflowsClient: + def with_raw_response(self) -> AsyncRawAgentsClient: """ Retrieves a raw implementation of this client that returns raw responses. Returns ------- - AsyncRawWorkflowsClient + AsyncRawAgentsClient """ return self._raw_client @@ -102,7 +102,7 @@ class AsyncWorkflowsClient: async def main() -> None: - await client.workflows.reset_workflow_browser_profile( + await client.agents.reset_workflow_browser_profile( workflow_permanent_id="wpid_123", ) diff --git a/skyvern/client/workflows/raw_client.py b/skyvern/client/agents/raw_client.py similarity index 96% rename from skyvern/client/workflows/raw_client.py rename to skyvern/client/agents/raw_client.py index 75aa6b882..628ce08ae 100644 --- a/skyvern/client/workflows/raw_client.py +++ b/skyvern/client/agents/raw_client.py @@ -14,7 +14,7 @@ from ..errors.not_found_error import NotFoundError from ..errors.unprocessable_entity_error import UnprocessableEntityError -class RawWorkflowsClient: +class RawAgentsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper @@ -37,7 +37,7 @@ class RawWorkflowsClient: HttpResponse[None] """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/browser_session/reset_profile", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/browser_session/reset_profile", method="POST", request_options=request_options, ) @@ -83,7 +83,7 @@ class RawWorkflowsClient: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) -class AsyncRawWorkflowsClient: +class AsyncRawAgentsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper @@ -106,7 +106,7 @@ class AsyncRawWorkflowsClient: AsyncHttpResponse[None] """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/browser_session/reset_profile", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/browser_session/reset_profile", method="POST", request_options=request_options, ) diff --git a/skyvern/client/client.py b/skyvern/client/client.py index 814047c73..ccf9194e2 100644 --- a/skyvern/client/client.py +++ b/skyvern/client/client.py @@ -15,8 +15,10 @@ from .types.artifact_type import ArtifactType from .types.browser_profile import BrowserProfile from .types.browser_session_response import BrowserSessionResponse from .types.bulk_cancel_runs_response import BulkCancelRunsResponse +from .types.create_browser_profile_request_proxy_location import CreateBrowserProfileRequestProxyLocation from .types.create_browser_session_request_proxy_location import CreateBrowserSessionRequestProxyLocation from .types.create_credential_request_credential import CreateCredentialRequestCredential +from .types.create_credential_request_proxy_location import CreateCredentialRequestProxyLocation from .types.create_script_response import CreateScriptResponse from .types.credential_response import CredentialResponse from .types.credential_vault_type import CredentialVaultType @@ -36,11 +38,18 @@ from .types.script import Script from .types.script_file_create import ScriptFileCreate from .types.skyvern_forge_sdk_schemas_credentials_credential_type import SkyvernForgeSdkSchemasCredentialsCredentialType from .types.skyvern_schemas_credential_type_credential_type import SkyvernSchemasCredentialTypeCredentialType +from .types.tag_delete_input import TagDeleteInput +from .types.tag_history_response import TagHistoryResponse +from .types.tag_input import TagInput +from .types.tag_key import TagKey +from .types.tag_key_delete_response import TagKeyDeleteResponse +from .types.tags_response import TagsResponse from .types.task_run_list_item import TaskRunListItem from .types.task_run_request_input_data_extraction_schema import TaskRunRequestInputDataExtractionSchema from .types.task_run_request_input_proxy_location import TaskRunRequestInputProxyLocation from .types.task_run_response import TaskRunResponse from .types.totp_code import TotpCode +from .types.update_browser_profile_request_proxy_location import UpdateBrowserProfileRequestProxyLocation from .types.upload_file_response import UploadFileResponse from .types.workflow import Workflow from .types.workflow_create_yaml_request import WorkflowCreateYamlRequest @@ -50,13 +59,13 @@ from .types.workflow_run_response import WorkflowRunResponse from .types.workflow_run_status import WorkflowRunStatus from .types.workflow_run_timeline import WorkflowRunTimeline from .types.workflow_status import WorkflowStatus +from .types.workflow_tags_batch_response import WorkflowTagsBatchResponse if typing.TYPE_CHECKING: + from .agents.client import AgentsClient, AsyncAgentsClient from .artifacts.client import ArtifactsClient, AsyncArtifactsClient from .schedules.client import AsyncSchedulesClient, SchedulesClient from .scripts.client import AsyncScriptsClient, ScriptsClient - from .server.client import AsyncServerClient, ServerClient - from .workflows.client import AsyncWorkflowsClient, WorkflowsClient # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -128,10 +137,9 @@ class Skyvern: ) self._raw_client = RawSkyvern(client_wrapper=self._client_wrapper) self._artifacts: typing.Optional[ArtifactsClient] = None - self._server: typing.Optional[ServerClient] = None - self._workflows: typing.Optional[WorkflowsClient] = None self._scripts: typing.Optional[ScriptsClient] = None self._schedules: typing.Optional[SchedulesClient] = None + self._agents: typing.Optional[AgentsClient] = None @property def with_raw_response(self) -> RawSkyvern: @@ -331,7 +339,7 @@ class Skyvern: def run_workflow( self, *, - workflow_id: str, + agent_id: str, template: typing.Optional[bool] = None, max_steps_override: typing.Optional[int] = None, user_agent: typing.Optional[str] = None, @@ -354,12 +362,12 @@ class Skyvern: request_options: typing.Optional[RequestOptions] = None, ) -> WorkflowRunResponse: """ - Run a workflow + Run an agent Parameters ---------- - workflow_id : str - ID of the workflow to run. Workflow ID starts with `wpid_`. + agent_id : str + ID of the agent to run. Starts with `wpid_`. `workflow_id` is accepted as an alias. template : typing.Optional[bool] @@ -457,7 +465,7 @@ class Skyvern: Returns ------- WorkflowRunResponse - Successfully run workflow + Successfully ran agent Examples -------- @@ -470,11 +478,11 @@ class Skyvern: max_steps_override=1, user_agent="x-user-agent", template=True, - workflow_id="wpid_123", + agent_id="wpid_123", ) """ _response = self._raw_client.run_workflow( - workflow_id=workflow_id, + agent_id=agent_id, template=template, max_steps_override=max_steps_override, user_agent=user_agent, @@ -607,6 +615,7 @@ class Skyvern: title: typing.Optional[str] = None, folder_id: typing.Optional[str] = None, status: typing.Optional[typing.Union[WorkflowStatus, typing.Sequence[WorkflowStatus]]] = None, + tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, template: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> typing.List[Workflow]: @@ -643,6 +652,9 @@ class Skyvern: status : typing.Optional[typing.Union[WorkflowStatus, typing.Sequence[WorkflowStatus]]] + tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] + Filter by tags. Each term is a label (`production`), a group (`env:*`), or a group:label (`env:prod`). Repeat the param or comma-separate (`?tags=env:prod,env:staging`). AND across distinct terms, OR within a group's labels (`?tags=customer:acme,env:prod,env:staging` -> customer=acme AND env in (prod, staging)). A label term matches the value across any/no group. Matches current tag values only. Not supported with `template=true`. + template : typing.Optional[bool] request_options : typing.Optional[RequestOptions] @@ -682,6 +694,7 @@ class Skyvern: title=title, folder_id=folder_id, status=status, + tags=tags, template=template, request_options=request_options, ) @@ -696,7 +709,7 @@ class Skyvern: request_options: typing.Optional[RequestOptions] = None, ) -> Workflow: """ - Create a new workflow + Create a new agent Parameters ---------- @@ -715,7 +728,7 @@ class Skyvern: Returns ------- Workflow - Successfully created workflow + Successfully created agent Examples -------- @@ -745,12 +758,12 @@ class Skyvern: request_options: typing.Optional[RequestOptions] = None, ) -> Workflow: """ - Update a workflow + Update an agent Parameters ---------- workflow_id : str - The ID of the workflow to update. Workflow ID starts with `wpid_`. + The ID of the agent to update. Starts with `wpid_`. json_definition : typing.Optional[WorkflowCreateYamlRequest] Workflow definition in JSON format @@ -764,7 +777,7 @@ class Skyvern: Returns ------- Workflow - Successfully updated workflow + Successfully updated agent Examples -------- @@ -789,12 +802,12 @@ class Skyvern: self, workflow_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> typing.Optional[typing.Any]: """ - Delete a workflow + Delete an agent Parameters ---------- workflow_id : str - The ID of the workflow to delete. Workflow ID starts with `wpid_`. + The ID of the agent to delete. Starts with `wpid_`. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -802,7 +815,7 @@ class Skyvern: Returns ------- typing.Optional[typing.Any] - Successfully deleted workflow + Successfully deleted agent Examples -------- @@ -1028,31 +1041,19 @@ class Skyvern: ) return _response.data - def update_workflow_folder( - self, - workflow_permanent_id: str, - *, - folder_id: typing.Optional[str] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> Workflow: + def list_tag_keys(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[TagKey]: """ - Update a workflow's folder assignment for the latest version + List all tag keys registered for the organization with their descriptions. Parameters ---------- - workflow_permanent_id : str - Workflow permanent ID - - folder_id : typing.Optional[str] - Folder ID to assign workflow to. Set to null to remove from folder. - request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Workflow - Successfully updated workflow folder + typing.List[TagKey] + Successfully retrieved tag keys Examples -------- @@ -1061,12 +1062,155 @@ class Skyvern: client = Skyvern( api_key="YOUR_API_KEY", ) - client.update_workflow_folder( - workflow_permanent_id="wpid_123", + client.list_tag_keys() + """ + _response = self._raw_client.list_tag_keys(request_options=request_options) + return _response.data + + def delete_tag_key( + self, key: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TagKeyDeleteResponse: + """ + Delete a tag key from the organization registry and remove that tag from every workflow that currently has it (cascade). Returns how many workflows the tag was removed from. + + Parameters + ---------- + key : str + Tag key to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagKeyDeleteResponse + Successfully deleted tag key + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.delete_tag_key( + key="env", ) """ - _response = self._raw_client.update_workflow_folder( - workflow_permanent_id, folder_id=folder_id, request_options=request_options + _response = self._raw_client.delete_tag_key(key, request_options=request_options) + return _response.data + + def update_tag_key( + self, + key: str, + *, + description: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> TagKey: + """ + Update the description for a tag key. + + Parameters + ---------- + key : str + Tag key to update + + description : typing.Optional[str] + Free-form description (max 500 chars). Pass null to clear. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagKey + Successfully updated tag key + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.update_tag_key( + key="key", + ) + """ + _response = self._raw_client.update_tag_key(key, description=description, request_options=request_options) + return _response.data + + def batch_get_workflow_tags( + self, + *, + workflow_permanent_ids: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> WorkflowTagsBatchResponse: + """ + Batch fetch current tags for many workflows. Avoids N+1 on the workflows-list page. + + Parameters + ---------- + workflow_permanent_ids : typing.Optional[str] + Comma-separated workflow permanent IDs + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + WorkflowTagsBatchResponse + Successfully retrieved tags + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.batch_get_workflow_tags( + workflow_permanent_ids="workflow_permanent_ids", + ) + """ + _response = self._raw_client.batch_get_workflow_tags( + workflow_permanent_ids=workflow_permanent_ids, request_options=request_options + ) + return _response.data + + def batch_get_workflow_tags_post( + self, + *, + workflow_permanent_ids: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> WorkflowTagsBatchResponse: + """ + Batch fetch current tags for many workflows (POST variant for id lists exceeding URL length). + + Parameters + ---------- + workflow_permanent_ids : typing.Optional[typing.Sequence[str]] + Workflow permanent IDs to fetch tags for. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + WorkflowTagsBatchResponse + Successfully retrieved tags + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.batch_get_workflow_tags_post() + """ + _response = self._raw_client.batch_get_workflow_tags_post( + workflow_permanent_ids=workflow_permanent_ids, request_options=request_options ) return _response.data @@ -1184,33 +1328,19 @@ class Skyvern: _response = self._raw_client.get_run_timeline(run_id, request_options=request_options) return _response.data - def retry_workflow_run( - self, - workflow_run_id: str, - *, - max_steps_override: typing.Optional[int] = None, - user_agent: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> WorkflowRunResponse: + def get_version(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.Dict[str, str]: """ - Retry a workflow run using the original run parameters. + Returns the current Skyvern server version (git SHA for official builds). Parameters ---------- - workflow_run_id : str - The id of the workflow run to retry. - - max_steps_override : typing.Optional[int] - - user_agent : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - WorkflowRunResponse - Successfully retried workflow run + typing.Dict[str, str] + Current server version Examples -------- @@ -1219,18 +1349,9 @@ class Skyvern: client = Skyvern( api_key="YOUR_API_KEY", ) - client.retry_workflow_run( - workflow_run_id="wr_123", - max_steps_override=1, - user_agent="x-user-agent", - ) + client.get_version() """ - _response = self._raw_client.retry_workflow_run( - workflow_run_id, - max_steps_override=max_steps_override, - user_agent=user_agent, - request_options=request_options, - ) + _response = self._raw_client.get_version(request_options=request_options) return _response.data def get_runs_v2( @@ -1280,256 +1401,6 @@ class Skyvern: ) return _response.data - def get_workflow_runs( - self, - *, - page: typing.Optional[int] = None, - page_size: typing.Optional[int] = None, - status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, - search_key: typing.Optional[str] = None, - error_code: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[WorkflowRun]: - """ - List workflow runs across all workflows for the current organization. - - Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. - - ### search_key - - A case-insensitive substring search that matches against **any** of the following fields: - - | Searched field | Description | - |---|---| - | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | - | Parameter **key** | The `key` of any workflow parameter definition associated with the run | - | Parameter **description** | The `description` of any workflow parameter definition | - | Run parameter **value** | The actual value supplied for any parameter when the run was created | - | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | - - Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. - - ### error_code - - An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). - - ### Combining filters - - All query parameters use AND logic: - - `?status=failed` — only failed runs - - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error - - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match - - Parameters - ---------- - page : typing.Optional[int] - Page number for pagination. - - page_size : typing.Optional[int] - Number of runs to return per page. - - status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] - Filter by one or more run statuses. - - search_key : typing.Optional[str] - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. - - error_code : typing.Optional[str] - Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - typing.List[WorkflowRun] - Successful Response - - Examples - -------- - from skyvern import Skyvern - - client = Skyvern( - api_key="YOUR_API_KEY", - ) - client.get_workflow_runs( - page=1, - page_size=1, - search_key="search_key", - error_code="error_code", - ) - """ - _response = self._raw_client.get_workflow_runs( - page=page, - page_size=page_size, - status=status, - search_key=search_key, - error_code=error_code, - request_options=request_options, - ) - return _response.data - - def get_workflow_runs_by_id( - self, - workflow_id: str, - *, - page: typing.Optional[int] = None, - page_size: typing.Optional[int] = None, - status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, - search_key: typing.Optional[str] = None, - error_code: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[WorkflowRun]: - """ - List runs for a specific workflow. - - Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. - - ### search_key - - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. - - ### error_code - - Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. - - Parameters - ---------- - workflow_id : str - - page : typing.Optional[int] - Page number for pagination. - - page_size : typing.Optional[int] - Number of runs to return per page. - - status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] - Filter by one or more run statuses. - - search_key : typing.Optional[str] - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. - - error_code : typing.Optional[str] - Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - typing.List[WorkflowRun] - Successful Response - - Examples - -------- - from skyvern import Skyvern - - client = Skyvern( - api_key="YOUR_API_KEY", - ) - client.get_workflow_runs_by_id( - workflow_id="workflow_id", - page=1, - page_size=1, - search_key="search_key", - error_code="error_code", - ) - """ - _response = self._raw_client.get_workflow_runs_by_id( - workflow_id, - page=page, - page_size=page_size, - status=status, - search_key=search_key, - error_code=error_code, - request_options=request_options, - ) - return _response.data - - def get_workflow( - self, - workflow_permanent_id: str, - *, - version: typing.Optional[int] = None, - template: typing.Optional[bool] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> Workflow: - """ - Parameters - ---------- - workflow_permanent_id : str - - version : typing.Optional[int] - - template : typing.Optional[bool] - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - Workflow - Successful Response - - Examples - -------- - from skyvern import Skyvern - - client = Skyvern( - api_key="YOUR_API_KEY", - ) - client.get_workflow( - workflow_permanent_id="workflow_permanent_id", - version=1, - template=True, - ) - """ - _response = self._raw_client.get_workflow( - workflow_permanent_id, version=version, template=template, request_options=request_options - ) - return _response.data - - def get_workflow_versions( - self, - workflow_permanent_id: str, - *, - template: typing.Optional[bool] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[Workflow]: - """ - Get all versions of a workflow by its permanent ID. - - Parameters - ---------- - workflow_permanent_id : str - - template : typing.Optional[bool] - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - typing.List[Workflow] - Successful Response - - Examples - -------- - from skyvern import Skyvern - - client = Skyvern( - api_key="YOUR_API_KEY", - ) - client.get_workflow_versions( - workflow_permanent_id="workflow_permanent_id", - template=True, - ) - """ - _response = self._raw_client.get_workflow_versions( - workflow_permanent_id, template=template, request_options=request_options - ) - return _response.data - def upload_file(self, *, file: str, request_options: typing.Optional[RequestOptions] = None) -> UploadFileResponse: """ Parameters @@ -1620,7 +1491,7 @@ class Skyvern: description: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, workflow_run_id: typing.Optional[str] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateBrowserProfileRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> BrowserProfile: @@ -1641,6 +1512,12 @@ class Skyvern: workflow_run_id : typing.Optional[str] Workflow run whose persisted session should be captured. Omit for a blank profile. + proxy_location : typing.Optional[CreateBrowserProfileRequestProxyLocation] + Optional proxy location for this profile's pinned proxy identity. + + proxy_session_id : typing.Optional[str] + Explicit sticky-session id for this profile's pinned proxy identity. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1742,7 +1619,7 @@ class Skyvern: *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[UpdateBrowserProfileRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -1761,8 +1638,14 @@ class Skyvern: description : typing.Optional[str] New description for the browser profile + proxy_location : typing.Optional[UpdateBrowserProfileRequestProxyLocation] + Optional proxy location for this profile's pinned proxy identity. + + proxy_session_id : typing.Optional[str] + Opaque Skyvern-managed proxy sticky-session id. + rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this browser profile. + Rotate the Skyvern-managed proxy sticky-session id for this profile. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1827,10 +1710,10 @@ class Skyvern: *, timeout: typing.Optional[int] = OMIT, proxy_location: typing.Optional[CreateBrowserSessionRequestProxyLocation] = OMIT, - proxy_session_id: typing.Optional[str] = OMIT, extensions: typing.Optional[typing.Sequence[Extensions]] = OMIT, browser_type: typing.Optional[PersistentBrowserType] = OMIT, browser_profile_id: typing.Optional[str] = OMIT, + generate_browser_profile: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> BrowserSessionResponse: """ @@ -1878,9 +1761,6 @@ class Skyvern: For self-hosted deployments, you can pass a custom proxy URL as a dict: {"url": "http://user:password@proxy.example.com:8080"}. This routes the browser through your own proxy server and takes precedence over any globally configured proxy pool. Can also be a GeoTarget object for granular city/state targeting: {"country": "US", "subdivision": "CA", "city": "San Francisco"}, or a custom proxy URL dict for self-hosted deployments: {"url": "http://user:password@proxy.example.com:8080"} - proxy_session_id : typing.Optional[str] - Opaque Skyvern-managed proxy sticky-session id for pinned Residential ISP sessions. - extensions : typing.Optional[typing.Sequence[Extensions]] A list of extensions to install in the browser session. @@ -1890,6 +1770,9 @@ class Skyvern: browser_profile_id : typing.Optional[str] ID of a browser profile to load into this session (restores cookies, localStorage, etc.). browser_profile_id starts with `bp_`. + generate_browser_profile : typing.Optional[bool] + When true, the session's browser profile (cookies, localStorage, etc.) is saved to storage when the session ends so it can be turned into a reusable browser profile. Defaults to false to avoid storing profiles for sessions that never need them. Sessions started with a browser_profile_id always persist their profile regardless of this flag. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1910,10 +1793,10 @@ class Skyvern: _response = self._raw_client.create_browser_session( timeout=timeout, proxy_location=proxy_location, - proxy_session_id=proxy_session_id, extensions=extensions, browser_type=browser_type, browser_profile_id=browser_profile_id, + generate_browser_profile=generate_browser_profile, request_options=request_options, ) return _response.data @@ -1984,6 +1867,49 @@ class Skyvern: _response = self._raw_client.get_browser_session(browser_session_id, request_options=request_options) return _response.data + def update_browser_session( + self, + browser_session_id: str, + *, + generate_browser_profile: bool, + request_options: typing.Optional[RequestOptions] = None, + ) -> BrowserSessionResponse: + """ + Update a live browser session. Currently supports toggling generate_browser_profile, which is read when the session ends to decide whether to save its browser profile. + + Parameters + ---------- + browser_session_id : str + The ID of the browser session. browser_session_id starts with `pbs_` + + generate_browser_profile : bool + Enable or disable saving this session's browser profile when it ends. Can be toggled while the session is still alive; the value is read at session teardown. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BrowserSessionResponse + Successfully updated browser session + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.update_browser_session( + browser_session_id="pbs_123456", + generate_browser_profile=True, + ) + """ + _response = self._raw_client.update_browser_session( + browser_session_id, generate_browser_profile=generate_browser_profile, request_options=request_options + ) + return _response.data + def send_totp_code( self, *, @@ -2065,6 +1991,8 @@ class Skyvern: page: typing.Optional[int] = None, page_size: typing.Optional[int] = None, vault_type: typing.Optional[CredentialVaultType] = None, + credential_type: typing.Optional[SkyvernForgeSdkSchemasCredentialsCredentialType] = None, + search: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> typing.List[CredentialResponse]: """ @@ -2081,6 +2009,12 @@ class Skyvern: vault_type : typing.Optional[CredentialVaultType] Filter credentials by vault type (e.g. 'skyvern', 'custom', 'bitwarden', 'azure_vault') + credential_type : typing.Optional[SkyvernForgeSdkSchemasCredentialsCredentialType] + Filter credentials by type (e.g. 'password', 'credit_card', 'secret') + + search : typing.Optional[str] + Case-insensitive search across credential name, username, secret label, and card details + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2099,11 +2033,18 @@ class Skyvern: client.get_credentials( page=1, page_size=10, - vault_type="bitwarden", + vault_type="skyvern", + credential_type="password", + search="search", ) """ _response = self._raw_client.get_credentials( - page=page, page_size=page_size, vault_type=vault_type, request_options=request_options + page=page, + page_size=page_size, + vault_type=vault_type, + credential_type=credential_type, + search=search, + request_options=request_options, ) return _response.data @@ -2114,7 +2055,7 @@ class Skyvern: credential_type: SkyvernForgeSdkSchemasCredentialsCredentialType, credential: CreateCredentialRequestCredential, vault_type: typing.Optional[CredentialVaultType] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -2136,8 +2077,14 @@ class Skyvern: vault_type : typing.Optional[CredentialVaultType] Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. + proxy_location : typing.Optional[CreateCredentialRequestProxyLocation] + Optional proxy location for this credential's pinned proxy identity. + + proxy_session_id : typing.Optional[str] + Optional advanced reuse key for this credential's pinned proxy identity. + rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this credential. + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2183,7 +2130,7 @@ class Skyvern: credential_type: SkyvernForgeSdkSchemasCredentialsCredentialType, credential: CreateCredentialRequestCredential, vault_type: typing.Optional[CredentialVaultType] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -2208,8 +2155,14 @@ class Skyvern: vault_type : typing.Optional[CredentialVaultType] Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. + proxy_location : typing.Optional[CreateCredentialRequestProxyLocation] + Optional proxy location for this credential's pinned proxy identity. + + proxy_session_id : typing.Optional[str] + Optional advanced reuse key for this credential's pinned proxy identity. + rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this credential. + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2797,6 +2750,520 @@ class Skyvern: ) return _response.data + def update_workflow_folder( + self, + workflow_permanent_id: str, + *, + folder_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Workflow: + """ + Update a workflow's folder assignment for the latest version + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + folder_id : typing.Optional[str] + Folder ID to assign workflow to. Set to null to remove from folder. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Workflow + Successfully updated workflow folder + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.update_workflow_folder( + workflow_permanent_id="wpid_123", + ) + """ + _response = self._raw_client.update_workflow_folder( + workflow_permanent_id, folder_id=folder_id, request_options=request_options + ) + return _response.data + + def get_workflow_tags( + self, workflow_permanent_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TagsResponse: + """ + Get the current tag state for a workflow. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagsResponse + Successfully retrieved tags + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.get_workflow_tags( + workflow_permanent_id="wpid_123", + ) + """ + _response = self._raw_client.get_workflow_tags(workflow_permanent_id, request_options=request_options) + return _response.data + + def apply_workflow_tags( + self, + workflow_permanent_id: str, + *, + tags: typing.Optional[typing.Sequence[TagInput]] = OMIT, + tags_to_delete: typing.Optional[typing.Sequence[TagDeleteInput]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> TagsResponse: + """ + Atomically apply tag changes to a workflow. Sets and deletes happen in one transaction; same-key collisions resolve set-wins. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + tags : typing.Optional[typing.Sequence[TagInput]] + Tags to set (overwrite). List of {key?, value} objects. + + tags_to_delete : typing.Optional[typing.Sequence[TagDeleteInput]] + Tags to soft-delete. List of {key?, value?} targets. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagsResponse + Successfully applied tag changes + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.apply_workflow_tags( + workflow_permanent_id="wpid_123", + ) + """ + _response = self._raw_client.apply_workflow_tags( + workflow_permanent_id, tags=tags, tags_to_delete=tags_to_delete, request_options=request_options + ) + return _response.data + + def delete_workflow_tag( + self, workflow_permanent_id: str, key: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TagsResponse: + """ + Soft-delete a single tag from a workflow. Writes a DELETE event row. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + key : str + Tag key to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagsResponse + Successfully deleted tag (or no-op if absent) + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.delete_workflow_tag( + workflow_permanent_id="wpid_123", + key="env", + ) + """ + _response = self._raw_client.delete_workflow_tag(workflow_permanent_id, key, request_options=request_options) + return _response.data + + def get_workflow_tag_history( + self, + workflow_permanent_id: str, + *, + limit: typing.Optional[int] = None, + since: typing.Optional[dt.datetime] = None, + key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TagHistoryResponse: + """ + Chronological tag-event log for a workflow (newest first). Includes SET and DELETE events. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + limit : typing.Optional[int] + Max events to return + + since : typing.Optional[dt.datetime] + Only return events at or after this timestamp + + key : typing.Optional[str] + Filter to events for a single tag key + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagHistoryResponse + Successfully retrieved tag history + + Examples + -------- + import datetime + + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.get_workflow_tag_history( + workflow_permanent_id="wpid_123", + limit=1, + since=datetime.datetime.fromisoformat( + "2024-01-15 09:30:00+00:00", + ), + key="key", + ) + """ + _response = self._raw_client.get_workflow_tag_history( + workflow_permanent_id, limit=limit, since=since, key=key, request_options=request_options + ) + return _response.data + + def retry_workflow_run( + self, + workflow_run_id: str, + *, + max_steps_override: typing.Optional[int] = None, + user_agent: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> WorkflowRunResponse: + """ + Retry a workflow run using the original run parameters. + + Parameters + ---------- + workflow_run_id : str + The id of the workflow run to retry. + + max_steps_override : typing.Optional[int] + + user_agent : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + WorkflowRunResponse + Successfully retried workflow run + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.retry_workflow_run( + workflow_run_id="wr_123", + max_steps_override=1, + user_agent="x-user-agent", + ) + """ + _response = self._raw_client.retry_workflow_run( + workflow_run_id, + max_steps_override=max_steps_override, + user_agent=user_agent, + request_options=request_options, + ) + return _response.data + + def get_workflow_runs( + self, + *, + page: typing.Optional[int] = None, + page_size: typing.Optional[int] = None, + status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, + search_key: typing.Optional[str] = None, + error_code: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.List[WorkflowRun]: + """ + List workflow runs across all workflows for the current organization. + + Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. + + ### search_key + + A case-insensitive substring search that matches against **any** of the following fields: + + | Searched field | Description | + |---|---| + | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | + | Parameter **key** | The `key` of any workflow parameter definition associated with the run | + | Parameter **description** | The `description` of any workflow parameter definition | + | Run parameter **value** | The actual value supplied for any parameter when the run was created | + | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | + + Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. + + ### error_code + + An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). + + ### Combining filters + + All query parameters use AND logic: + - `?status=failed` — only failed runs + - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error + - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match + + Parameters + ---------- + page : typing.Optional[int] + Page number for pagination. + + page_size : typing.Optional[int] + Number of runs to return per page. + + status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] + Filter by one or more run statuses. + + search_key : typing.Optional[str] + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. + + error_code : typing.Optional[str] + Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[WorkflowRun] + Successful Response + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.get_workflow_runs( + page=1, + page_size=1, + search_key="search_key", + error_code="error_code", + ) + """ + _response = self._raw_client.get_workflow_runs( + page=page, + page_size=page_size, + status=status, + search_key=search_key, + error_code=error_code, + request_options=request_options, + ) + return _response.data + + def get_workflow_runs_by_id( + self, + workflow_id: str, + *, + page: typing.Optional[int] = None, + page_size: typing.Optional[int] = None, + status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, + search_key: typing.Optional[str] = None, + error_code: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.List[WorkflowRun]: + """ + List runs for a specific workflow. + + Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. + + ### search_key + + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. + + ### error_code + + Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. + + Parameters + ---------- + workflow_id : str + + page : typing.Optional[int] + Page number for pagination. + + page_size : typing.Optional[int] + Number of runs to return per page. + + status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] + Filter by one or more run statuses. + + search_key : typing.Optional[str] + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. + + error_code : typing.Optional[str] + Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[WorkflowRun] + Successful Response + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.get_workflow_runs_by_id( + workflow_id="workflow_id", + page=1, + page_size=1, + search_key="search_key", + error_code="error_code", + ) + """ + _response = self._raw_client.get_workflow_runs_by_id( + workflow_id, + page=page, + page_size=page_size, + status=status, + search_key=search_key, + error_code=error_code, + request_options=request_options, + ) + return _response.data + + def get_workflow( + self, + workflow_permanent_id: str, + *, + version: typing.Optional[int] = None, + template: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Workflow: + """ + Parameters + ---------- + workflow_permanent_id : str + + version : typing.Optional[int] + + template : typing.Optional[bool] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Workflow + Successful Response + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.get_workflow( + workflow_permanent_id="workflow_permanent_id", + version=1, + template=True, + ) + """ + _response = self._raw_client.get_workflow( + workflow_permanent_id, version=version, template=template, request_options=request_options + ) + return _response.data + + def get_workflow_versions( + self, + workflow_permanent_id: str, + *, + template: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.List[Workflow]: + """ + Get all versions of a workflow by its permanent ID. + + Parameters + ---------- + workflow_permanent_id : str + + template : typing.Optional[bool] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[Workflow] + Successful Response + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.get_workflow_versions( + workflow_permanent_id="workflow_permanent_id", + template=True, + ) + """ + _response = self._raw_client.get_workflow_versions( + workflow_permanent_id, template=template, request_options=request_options + ) + return _response.data + @property def artifacts(self): if self._artifacts is None: @@ -2805,22 +3272,6 @@ class Skyvern: self._artifacts = ArtifactsClient(client_wrapper=self._client_wrapper) return self._artifacts - @property - def server(self): - if self._server is None: - from .server.client import ServerClient # noqa: E402 - - self._server = ServerClient(client_wrapper=self._client_wrapper) - return self._server - - @property - def workflows(self): - if self._workflows is None: - from .workflows.client import WorkflowsClient # noqa: E402 - - self._workflows = WorkflowsClient(client_wrapper=self._client_wrapper) - return self._workflows - @property def scripts(self): if self._scripts is None: @@ -2837,6 +3288,14 @@ class Skyvern: self._schedules = SchedulesClient(client_wrapper=self._client_wrapper) return self._schedules + @property + def agents(self): + if self._agents is None: + from .agents.client import AgentsClient # noqa: E402 + + self._agents = AgentsClient(client_wrapper=self._client_wrapper) + return self._agents + class AsyncSkyvern: """ @@ -2905,10 +3364,9 @@ class AsyncSkyvern: ) self._raw_client = AsyncRawSkyvern(client_wrapper=self._client_wrapper) self._artifacts: typing.Optional[AsyncArtifactsClient] = None - self._server: typing.Optional[AsyncServerClient] = None - self._workflows: typing.Optional[AsyncWorkflowsClient] = None self._scripts: typing.Optional[AsyncScriptsClient] = None self._schedules: typing.Optional[AsyncSchedulesClient] = None + self._agents: typing.Optional[AsyncAgentsClient] = None @property def with_raw_response(self) -> AsyncRawSkyvern: @@ -3116,7 +3574,7 @@ class AsyncSkyvern: async def run_workflow( self, *, - workflow_id: str, + agent_id: str, template: typing.Optional[bool] = None, max_steps_override: typing.Optional[int] = None, user_agent: typing.Optional[str] = None, @@ -3139,12 +3597,12 @@ class AsyncSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> WorkflowRunResponse: """ - Run a workflow + Run an agent Parameters ---------- - workflow_id : str - ID of the workflow to run. Workflow ID starts with `wpid_`. + agent_id : str + ID of the agent to run. Starts with `wpid_`. `workflow_id` is accepted as an alias. template : typing.Optional[bool] @@ -3242,7 +3700,7 @@ class AsyncSkyvern: Returns ------- WorkflowRunResponse - Successfully run workflow + Successfully ran agent Examples -------- @@ -3260,14 +3718,14 @@ class AsyncSkyvern: max_steps_override=1, user_agent="x-user-agent", template=True, - workflow_id="wpid_123", + agent_id="wpid_123", ) asyncio.run(main()) """ _response = await self._raw_client.run_workflow( - workflow_id=workflow_id, + agent_id=agent_id, template=template, max_steps_override=max_steps_override, user_agent=user_agent, @@ -3424,6 +3882,7 @@ class AsyncSkyvern: title: typing.Optional[str] = None, folder_id: typing.Optional[str] = None, status: typing.Optional[typing.Union[WorkflowStatus, typing.Sequence[WorkflowStatus]]] = None, + tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, template: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> typing.List[Workflow]: @@ -3460,6 +3919,9 @@ class AsyncSkyvern: status : typing.Optional[typing.Union[WorkflowStatus, typing.Sequence[WorkflowStatus]]] + tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] + Filter by tags. Each term is a label (`production`), a group (`env:*`), or a group:label (`env:prod`). Repeat the param or comma-separate (`?tags=env:prod,env:staging`). AND across distinct terms, OR within a group's labels (`?tags=customer:acme,env:prod,env:staging` -> customer=acme AND env in (prod, staging)). A label term matches the value across any/no group. Matches current tag values only. Not supported with `template=true`. + template : typing.Optional[bool] request_options : typing.Optional[RequestOptions] @@ -3507,6 +3969,7 @@ class AsyncSkyvern: title=title, folder_id=folder_id, status=status, + tags=tags, template=template, request_options=request_options, ) @@ -3521,7 +3984,7 @@ class AsyncSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> Workflow: """ - Create a new workflow + Create a new agent Parameters ---------- @@ -3540,7 +4003,7 @@ class AsyncSkyvern: Returns ------- Workflow - Successfully created workflow + Successfully created agent Examples -------- @@ -3578,12 +4041,12 @@ class AsyncSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> Workflow: """ - Update a workflow + Update an agent Parameters ---------- workflow_id : str - The ID of the workflow to update. Workflow ID starts with `wpid_`. + The ID of the agent to update. Starts with `wpid_`. json_definition : typing.Optional[WorkflowCreateYamlRequest] Workflow definition in JSON format @@ -3597,7 +4060,7 @@ class AsyncSkyvern: Returns ------- Workflow - Successfully updated workflow + Successfully updated agent Examples -------- @@ -3630,12 +4093,12 @@ class AsyncSkyvern: self, workflow_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> typing.Optional[typing.Any]: """ - Delete a workflow + Delete an agent Parameters ---------- workflow_id : str - The ID of the workflow to delete. Workflow ID starts with `wpid_`. + The ID of the agent to delete. Starts with `wpid_`. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -3643,7 +4106,7 @@ class AsyncSkyvern: Returns ------- typing.Optional[typing.Any] - Successfully deleted workflow + Successfully deleted agent Examples -------- @@ -3917,31 +4380,19 @@ class AsyncSkyvern: ) return _response.data - async def update_workflow_folder( - self, - workflow_permanent_id: str, - *, - folder_id: typing.Optional[str] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> Workflow: + async def list_tag_keys(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.List[TagKey]: """ - Update a workflow's folder assignment for the latest version + List all tag keys registered for the organization with their descriptions. Parameters ---------- - workflow_permanent_id : str - Workflow permanent ID - - folder_id : typing.Optional[str] - Folder ID to assign workflow to. Set to null to remove from folder. - request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Workflow - Successfully updated workflow folder + typing.List[TagKey] + Successfully retrieved tag keys Examples -------- @@ -3955,15 +4406,190 @@ class AsyncSkyvern: async def main() -> None: - await client.update_workflow_folder( - workflow_permanent_id="wpid_123", + await client.list_tag_keys() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_tag_keys(request_options=request_options) + return _response.data + + async def delete_tag_key( + self, key: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TagKeyDeleteResponse: + """ + Delete a tag key from the organization registry and remove that tag from every workflow that currently has it (cascade). Returns how many workflows the tag was removed from. + + Parameters + ---------- + key : str + Tag key to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagKeyDeleteResponse + Successfully deleted tag key + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.delete_tag_key( + key="env", ) asyncio.run(main()) """ - _response = await self._raw_client.update_workflow_folder( - workflow_permanent_id, folder_id=folder_id, request_options=request_options + _response = await self._raw_client.delete_tag_key(key, request_options=request_options) + return _response.data + + async def update_tag_key( + self, + key: str, + *, + description: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> TagKey: + """ + Update the description for a tag key. + + Parameters + ---------- + key : str + Tag key to update + + description : typing.Optional[str] + Free-form description (max 500 chars). Pass null to clear. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagKey + Successfully updated tag key + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.update_tag_key( + key="key", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update_tag_key(key, description=description, request_options=request_options) + return _response.data + + async def batch_get_workflow_tags( + self, + *, + workflow_permanent_ids: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> WorkflowTagsBatchResponse: + """ + Batch fetch current tags for many workflows. Avoids N+1 on the workflows-list page. + + Parameters + ---------- + workflow_permanent_ids : typing.Optional[str] + Comma-separated workflow permanent IDs + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + WorkflowTagsBatchResponse + Successfully retrieved tags + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.batch_get_workflow_tags( + workflow_permanent_ids="workflow_permanent_ids", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.batch_get_workflow_tags( + workflow_permanent_ids=workflow_permanent_ids, request_options=request_options + ) + return _response.data + + async def batch_get_workflow_tags_post( + self, + *, + workflow_permanent_ids: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> WorkflowTagsBatchResponse: + """ + Batch fetch current tags for many workflows (POST variant for id lists exceeding URL length). + + Parameters + ---------- + workflow_permanent_ids : typing.Optional[typing.Sequence[str]] + Workflow permanent IDs to fetch tags for. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + WorkflowTagsBatchResponse + Successfully retrieved tags + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.batch_get_workflow_tags_post() + + + asyncio.run(main()) + """ + _response = await self._raw_client.batch_get_workflow_tags_post( + workflow_permanent_ids=workflow_permanent_ids, request_options=request_options ) return _response.data @@ -4105,33 +4731,19 @@ class AsyncSkyvern: _response = await self._raw_client.get_run_timeline(run_id, request_options=request_options) return _response.data - async def retry_workflow_run( - self, - workflow_run_id: str, - *, - max_steps_override: typing.Optional[int] = None, - user_agent: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> WorkflowRunResponse: + async def get_version(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.Dict[str, str]: """ - Retry a workflow run using the original run parameters. + Returns the current Skyvern server version (git SHA for official builds). Parameters ---------- - workflow_run_id : str - The id of the workflow run to retry. - - max_steps_override : typing.Optional[int] - - user_agent : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - WorkflowRunResponse - Successfully retried workflow run + typing.Dict[str, str] + Current server version Examples -------- @@ -4145,21 +4757,12 @@ class AsyncSkyvern: async def main() -> None: - await client.retry_workflow_run( - workflow_run_id="wr_123", - max_steps_override=1, - user_agent="x-user-agent", - ) + await client.get_version() asyncio.run(main()) """ - _response = await self._raw_client.retry_workflow_run( - workflow_run_id, - max_steps_override=max_steps_override, - user_agent=user_agent, - request_options=request_options, - ) + _response = await self._raw_client.get_version(request_options=request_options) return _response.data async def get_runs_v2( @@ -4217,288 +4820,6 @@ class AsyncSkyvern: ) return _response.data - async def get_workflow_runs( - self, - *, - page: typing.Optional[int] = None, - page_size: typing.Optional[int] = None, - status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, - search_key: typing.Optional[str] = None, - error_code: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[WorkflowRun]: - """ - List workflow runs across all workflows for the current organization. - - Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. - - ### search_key - - A case-insensitive substring search that matches against **any** of the following fields: - - | Searched field | Description | - |---|---| - | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | - | Parameter **key** | The `key` of any workflow parameter definition associated with the run | - | Parameter **description** | The `description` of any workflow parameter definition | - | Run parameter **value** | The actual value supplied for any parameter when the run was created | - | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | - - Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. - - ### error_code - - An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). - - ### Combining filters - - All query parameters use AND logic: - - `?status=failed` — only failed runs - - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error - - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match - - Parameters - ---------- - page : typing.Optional[int] - Page number for pagination. - - page_size : typing.Optional[int] - Number of runs to return per page. - - status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] - Filter by one or more run statuses. - - search_key : typing.Optional[str] - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. - - error_code : typing.Optional[str] - Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - typing.List[WorkflowRun] - Successful Response - - Examples - -------- - import asyncio - - from skyvern import AsyncSkyvern - - client = AsyncSkyvern( - api_key="YOUR_API_KEY", - ) - - - async def main() -> None: - await client.get_workflow_runs( - page=1, - page_size=1, - search_key="search_key", - error_code="error_code", - ) - - - asyncio.run(main()) - """ - _response = await self._raw_client.get_workflow_runs( - page=page, - page_size=page_size, - status=status, - search_key=search_key, - error_code=error_code, - request_options=request_options, - ) - return _response.data - - async def get_workflow_runs_by_id( - self, - workflow_id: str, - *, - page: typing.Optional[int] = None, - page_size: typing.Optional[int] = None, - status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, - search_key: typing.Optional[str] = None, - error_code: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[WorkflowRun]: - """ - List runs for a specific workflow. - - Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. - - ### search_key - - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. - - ### error_code - - Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. - - Parameters - ---------- - workflow_id : str - - page : typing.Optional[int] - Page number for pagination. - - page_size : typing.Optional[int] - Number of runs to return per page. - - status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] - Filter by one or more run statuses. - - search_key : typing.Optional[str] - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. - - error_code : typing.Optional[str] - Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - typing.List[WorkflowRun] - Successful Response - - Examples - -------- - import asyncio - - from skyvern import AsyncSkyvern - - client = AsyncSkyvern( - api_key="YOUR_API_KEY", - ) - - - async def main() -> None: - await client.get_workflow_runs_by_id( - workflow_id="workflow_id", - page=1, - page_size=1, - search_key="search_key", - error_code="error_code", - ) - - - asyncio.run(main()) - """ - _response = await self._raw_client.get_workflow_runs_by_id( - workflow_id, - page=page, - page_size=page_size, - status=status, - search_key=search_key, - error_code=error_code, - request_options=request_options, - ) - return _response.data - - async def get_workflow( - self, - workflow_permanent_id: str, - *, - version: typing.Optional[int] = None, - template: typing.Optional[bool] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> Workflow: - """ - Parameters - ---------- - workflow_permanent_id : str - - version : typing.Optional[int] - - template : typing.Optional[bool] - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - Workflow - Successful Response - - Examples - -------- - import asyncio - - from skyvern import AsyncSkyvern - - client = AsyncSkyvern( - api_key="YOUR_API_KEY", - ) - - - async def main() -> None: - await client.get_workflow( - workflow_permanent_id="workflow_permanent_id", - version=1, - template=True, - ) - - - asyncio.run(main()) - """ - _response = await self._raw_client.get_workflow( - workflow_permanent_id, version=version, template=template, request_options=request_options - ) - return _response.data - - async def get_workflow_versions( - self, - workflow_permanent_id: str, - *, - template: typing.Optional[bool] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> typing.List[Workflow]: - """ - Get all versions of a workflow by its permanent ID. - - Parameters - ---------- - workflow_permanent_id : str - - template : typing.Optional[bool] - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - typing.List[Workflow] - Successful Response - - Examples - -------- - import asyncio - - from skyvern import AsyncSkyvern - - client = AsyncSkyvern( - api_key="YOUR_API_KEY", - ) - - - async def main() -> None: - await client.get_workflow_versions( - workflow_permanent_id="workflow_permanent_id", - template=True, - ) - - - asyncio.run(main()) - """ - _response = await self._raw_client.get_workflow_versions( - workflow_permanent_id, template=template, request_options=request_options - ) - return _response.data - async def upload_file( self, *, file: str, request_options: typing.Optional[RequestOptions] = None ) -> UploadFileResponse: @@ -4607,7 +4928,7 @@ class AsyncSkyvern: description: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, workflow_run_id: typing.Optional[str] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateBrowserProfileRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> BrowserProfile: @@ -4628,6 +4949,12 @@ class AsyncSkyvern: workflow_run_id : typing.Optional[str] Workflow run whose persisted session should be captured. Omit for a blank profile. + proxy_location : typing.Optional[CreateBrowserProfileRequestProxyLocation] + Optional proxy location for this profile's pinned proxy identity. + + proxy_session_id : typing.Optional[str] + Explicit sticky-session id for this profile's pinned proxy identity. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4753,7 +5080,7 @@ class AsyncSkyvern: *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[UpdateBrowserProfileRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -4772,8 +5099,14 @@ class AsyncSkyvern: description : typing.Optional[str] New description for the browser profile + proxy_location : typing.Optional[UpdateBrowserProfileRequestProxyLocation] + Optional proxy location for this profile's pinned proxy identity. + + proxy_session_id : typing.Optional[str] + Opaque Skyvern-managed proxy sticky-session id. + rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this browser profile. + Rotate the Skyvern-managed proxy sticky-session id for this profile. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4854,10 +5187,10 @@ class AsyncSkyvern: *, timeout: typing.Optional[int] = OMIT, proxy_location: typing.Optional[CreateBrowserSessionRequestProxyLocation] = OMIT, - proxy_session_id: typing.Optional[str] = OMIT, extensions: typing.Optional[typing.Sequence[Extensions]] = OMIT, browser_type: typing.Optional[PersistentBrowserType] = OMIT, browser_profile_id: typing.Optional[str] = OMIT, + generate_browser_profile: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> BrowserSessionResponse: """ @@ -4905,9 +5238,6 @@ class AsyncSkyvern: For self-hosted deployments, you can pass a custom proxy URL as a dict: {"url": "http://user:password@proxy.example.com:8080"}. This routes the browser through your own proxy server and takes precedence over any globally configured proxy pool. Can also be a GeoTarget object for granular city/state targeting: {"country": "US", "subdivision": "CA", "city": "San Francisco"}, or a custom proxy URL dict for self-hosted deployments: {"url": "http://user:password@proxy.example.com:8080"} - proxy_session_id : typing.Optional[str] - Opaque Skyvern-managed proxy sticky-session id for pinned Residential ISP sessions. - extensions : typing.Optional[typing.Sequence[Extensions]] A list of extensions to install in the browser session. @@ -4917,6 +5247,9 @@ class AsyncSkyvern: browser_profile_id : typing.Optional[str] ID of a browser profile to load into this session (restores cookies, localStorage, etc.). browser_profile_id starts with `bp_`. + generate_browser_profile : typing.Optional[bool] + When true, the session's browser profile (cookies, localStorage, etc.) is saved to storage when the session ends so it can be turned into a reusable browser profile. Defaults to false to avoid storing profiles for sessions that never need them. Sessions started with a browser_profile_id always persist their profile regardless of this flag. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4945,10 +5278,10 @@ class AsyncSkyvern: _response = await self._raw_client.create_browser_session( timeout=timeout, proxy_location=proxy_location, - proxy_session_id=proxy_session_id, extensions=extensions, browser_type=browser_type, browser_profile_id=browser_profile_id, + generate_browser_profile=generate_browser_profile, request_options=request_options, ) return _response.data @@ -5035,6 +5368,57 @@ class AsyncSkyvern: _response = await self._raw_client.get_browser_session(browser_session_id, request_options=request_options) return _response.data + async def update_browser_session( + self, + browser_session_id: str, + *, + generate_browser_profile: bool, + request_options: typing.Optional[RequestOptions] = None, + ) -> BrowserSessionResponse: + """ + Update a live browser session. Currently supports toggling generate_browser_profile, which is read when the session ends to decide whether to save its browser profile. + + Parameters + ---------- + browser_session_id : str + The ID of the browser session. browser_session_id starts with `pbs_` + + generate_browser_profile : bool + Enable or disable saving this session's browser profile when it ends. Can be toggled while the session is still alive; the value is read at session teardown. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BrowserSessionResponse + Successfully updated browser session + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.update_browser_session( + browser_session_id="pbs_123456", + generate_browser_profile=True, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update_browser_session( + browser_session_id, generate_browser_profile=generate_browser_profile, request_options=request_options + ) + return _response.data + async def send_totp_code( self, *, @@ -5124,6 +5508,8 @@ class AsyncSkyvern: page: typing.Optional[int] = None, page_size: typing.Optional[int] = None, vault_type: typing.Optional[CredentialVaultType] = None, + credential_type: typing.Optional[SkyvernForgeSdkSchemasCredentialsCredentialType] = None, + search: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> typing.List[CredentialResponse]: """ @@ -5140,6 +5526,12 @@ class AsyncSkyvern: vault_type : typing.Optional[CredentialVaultType] Filter credentials by vault type (e.g. 'skyvern', 'custom', 'bitwarden', 'azure_vault') + credential_type : typing.Optional[SkyvernForgeSdkSchemasCredentialsCredentialType] + Filter credentials by type (e.g. 'password', 'credit_card', 'secret') + + search : typing.Optional[str] + Case-insensitive search across credential name, username, secret label, and card details + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -5163,14 +5555,21 @@ class AsyncSkyvern: await client.get_credentials( page=1, page_size=10, - vault_type="bitwarden", + vault_type="skyvern", + credential_type="password", + search="search", ) asyncio.run(main()) """ _response = await self._raw_client.get_credentials( - page=page, page_size=page_size, vault_type=vault_type, request_options=request_options + page=page, + page_size=page_size, + vault_type=vault_type, + credential_type=credential_type, + search=search, + request_options=request_options, ) return _response.data @@ -5181,7 +5580,7 @@ class AsyncSkyvern: credential_type: SkyvernForgeSdkSchemasCredentialsCredentialType, credential: CreateCredentialRequestCredential, vault_type: typing.Optional[CredentialVaultType] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -5203,8 +5602,14 @@ class AsyncSkyvern: vault_type : typing.Optional[CredentialVaultType] Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. + proxy_location : typing.Optional[CreateCredentialRequestProxyLocation] + Optional proxy location for this credential's pinned proxy identity. + + proxy_session_id : typing.Optional[str] + Optional advanced reuse key for this credential's pinned proxy identity. + rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this credential. + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -5258,7 +5663,7 @@ class AsyncSkyvern: credential_type: SkyvernForgeSdkSchemasCredentialsCredentialType, credential: CreateCredentialRequestCredential, vault_type: typing.Optional[CredentialVaultType] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -5283,8 +5688,14 @@ class AsyncSkyvern: vault_type : typing.Optional[CredentialVaultType] Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. + proxy_location : typing.Optional[CreateCredentialRequestProxyLocation] + Optional proxy location for this credential's pinned proxy identity. + + proxy_session_id : typing.Optional[str] + Optional advanced reuse key for this credential's pinned proxy identity. + rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this credential. + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -5954,6 +6365,601 @@ class AsyncSkyvern: ) return _response.data + async def update_workflow_folder( + self, + workflow_permanent_id: str, + *, + folder_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Workflow: + """ + Update a workflow's folder assignment for the latest version + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + folder_id : typing.Optional[str] + Folder ID to assign workflow to. Set to null to remove from folder. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Workflow + Successfully updated workflow folder + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.update_workflow_folder( + workflow_permanent_id="wpid_123", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update_workflow_folder( + workflow_permanent_id, folder_id=folder_id, request_options=request_options + ) + return _response.data + + async def get_workflow_tags( + self, workflow_permanent_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TagsResponse: + """ + Get the current tag state for a workflow. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagsResponse + Successfully retrieved tags + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.get_workflow_tags( + workflow_permanent_id="wpid_123", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_workflow_tags(workflow_permanent_id, request_options=request_options) + return _response.data + + async def apply_workflow_tags( + self, + workflow_permanent_id: str, + *, + tags: typing.Optional[typing.Sequence[TagInput]] = OMIT, + tags_to_delete: typing.Optional[typing.Sequence[TagDeleteInput]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> TagsResponse: + """ + Atomically apply tag changes to a workflow. Sets and deletes happen in one transaction; same-key collisions resolve set-wins. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + tags : typing.Optional[typing.Sequence[TagInput]] + Tags to set (overwrite). List of {key?, value} objects. + + tags_to_delete : typing.Optional[typing.Sequence[TagDeleteInput]] + Tags to soft-delete. List of {key?, value?} targets. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagsResponse + Successfully applied tag changes + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.apply_workflow_tags( + workflow_permanent_id="wpid_123", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.apply_workflow_tags( + workflow_permanent_id, tags=tags, tags_to_delete=tags_to_delete, request_options=request_options + ) + return _response.data + + async def delete_workflow_tag( + self, workflow_permanent_id: str, key: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> TagsResponse: + """ + Soft-delete a single tag from a workflow. Writes a DELETE event row. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + key : str + Tag key to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagsResponse + Successfully deleted tag (or no-op if absent) + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.delete_workflow_tag( + workflow_permanent_id="wpid_123", + key="env", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_workflow_tag( + workflow_permanent_id, key, request_options=request_options + ) + return _response.data + + async def get_workflow_tag_history( + self, + workflow_permanent_id: str, + *, + limit: typing.Optional[int] = None, + since: typing.Optional[dt.datetime] = None, + key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> TagHistoryResponse: + """ + Chronological tag-event log for a workflow (newest first). Includes SET and DELETE events. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + limit : typing.Optional[int] + Max events to return + + since : typing.Optional[dt.datetime] + Only return events at or after this timestamp + + key : typing.Optional[str] + Filter to events for a single tag key + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TagHistoryResponse + Successfully retrieved tag history + + Examples + -------- + import asyncio + import datetime + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.get_workflow_tag_history( + workflow_permanent_id="wpid_123", + limit=1, + since=datetime.datetime.fromisoformat( + "2024-01-15 09:30:00+00:00", + ), + key="key", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_workflow_tag_history( + workflow_permanent_id, limit=limit, since=since, key=key, request_options=request_options + ) + return _response.data + + async def retry_workflow_run( + self, + workflow_run_id: str, + *, + max_steps_override: typing.Optional[int] = None, + user_agent: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> WorkflowRunResponse: + """ + Retry a workflow run using the original run parameters. + + Parameters + ---------- + workflow_run_id : str + The id of the workflow run to retry. + + max_steps_override : typing.Optional[int] + + user_agent : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + WorkflowRunResponse + Successfully retried workflow run + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.retry_workflow_run( + workflow_run_id="wr_123", + max_steps_override=1, + user_agent="x-user-agent", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.retry_workflow_run( + workflow_run_id, + max_steps_override=max_steps_override, + user_agent=user_agent, + request_options=request_options, + ) + return _response.data + + async def get_workflow_runs( + self, + *, + page: typing.Optional[int] = None, + page_size: typing.Optional[int] = None, + status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, + search_key: typing.Optional[str] = None, + error_code: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.List[WorkflowRun]: + """ + List workflow runs across all workflows for the current organization. + + Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. + + ### search_key + + A case-insensitive substring search that matches against **any** of the following fields: + + | Searched field | Description | + |---|---| + | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | + | Parameter **key** | The `key` of any workflow parameter definition associated with the run | + | Parameter **description** | The `description` of any workflow parameter definition | + | Run parameter **value** | The actual value supplied for any parameter when the run was created | + | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | + + Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. + + ### error_code + + An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). + + ### Combining filters + + All query parameters use AND logic: + - `?status=failed` — only failed runs + - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error + - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match + + Parameters + ---------- + page : typing.Optional[int] + Page number for pagination. + + page_size : typing.Optional[int] + Number of runs to return per page. + + status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] + Filter by one or more run statuses. + + search_key : typing.Optional[str] + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. + + error_code : typing.Optional[str] + Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[WorkflowRun] + Successful Response + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.get_workflow_runs( + page=1, + page_size=1, + search_key="search_key", + error_code="error_code", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_workflow_runs( + page=page, + page_size=page_size, + status=status, + search_key=search_key, + error_code=error_code, + request_options=request_options, + ) + return _response.data + + async def get_workflow_runs_by_id( + self, + workflow_id: str, + *, + page: typing.Optional[int] = None, + page_size: typing.Optional[int] = None, + status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, + search_key: typing.Optional[str] = None, + error_code: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.List[WorkflowRun]: + """ + List runs for a specific workflow. + + Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. + + ### search_key + + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. + + ### error_code + + Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. + + Parameters + ---------- + workflow_id : str + + page : typing.Optional[int] + Page number for pagination. + + page_size : typing.Optional[int] + Number of runs to return per page. + + status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] + Filter by one or more run statuses. + + search_key : typing.Optional[str] + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. + + error_code : typing.Optional[str] + Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[WorkflowRun] + Successful Response + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.get_workflow_runs_by_id( + workflow_id="workflow_id", + page=1, + page_size=1, + search_key="search_key", + error_code="error_code", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_workflow_runs_by_id( + workflow_id, + page=page, + page_size=page_size, + status=status, + search_key=search_key, + error_code=error_code, + request_options=request_options, + ) + return _response.data + + async def get_workflow( + self, + workflow_permanent_id: str, + *, + version: typing.Optional[int] = None, + template: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> Workflow: + """ + Parameters + ---------- + workflow_permanent_id : str + + version : typing.Optional[int] + + template : typing.Optional[bool] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Workflow + Successful Response + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.get_workflow( + workflow_permanent_id="workflow_permanent_id", + version=1, + template=True, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_workflow( + workflow_permanent_id, version=version, template=template, request_options=request_options + ) + return _response.data + + async def get_workflow_versions( + self, + workflow_permanent_id: str, + *, + template: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.List[Workflow]: + """ + Get all versions of a workflow by its permanent ID. + + Parameters + ---------- + workflow_permanent_id : str + + template : typing.Optional[bool] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[Workflow] + Successful Response + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.get_workflow_versions( + workflow_permanent_id="workflow_permanent_id", + template=True, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_workflow_versions( + workflow_permanent_id, template=template, request_options=request_options + ) + return _response.data + @property def artifacts(self): if self._artifacts is None: @@ -5962,22 +6968,6 @@ class AsyncSkyvern: self._artifacts = AsyncArtifactsClient(client_wrapper=self._client_wrapper) return self._artifacts - @property - def server(self): - if self._server is None: - from .server.client import AsyncServerClient # noqa: E402 - - self._server = AsyncServerClient(client_wrapper=self._client_wrapper) - return self._server - - @property - def workflows(self): - if self._workflows is None: - from .workflows.client import AsyncWorkflowsClient # noqa: E402 - - self._workflows = AsyncWorkflowsClient(client_wrapper=self._client_wrapper) - return self._workflows - @property def scripts(self): if self._scripts is None: @@ -5994,6 +6984,14 @@ class AsyncSkyvern: self._schedules = AsyncSchedulesClient(client_wrapper=self._client_wrapper) return self._schedules + @property + def agents(self): + if self._agents is None: + from .agents.client import AsyncAgentsClient # noqa: E402 + + self._agents = AsyncAgentsClient(client_wrapper=self._client_wrapper) + return self._agents + def _get_base_url(*, base_url: typing.Optional[str] = None, environment: SkyvernEnvironment) -> str: if base_url is not None: diff --git a/skyvern/client/core/client_wrapper.py b/skyvern/client/core/client_wrapper.py index bd630dbf0..0e89bf1e6 100644 --- a/skyvern/client/core/client_wrapper.py +++ b/skyvern/client/core/client_wrapper.py @@ -22,10 +22,10 @@ class BaseClientWrapper: def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { - "User-Agent": "skyvern/1.0.37", + "User-Agent": "skyvern/1.0.45", "X-Fern-Language": "Python", "X-Fern-SDK-Name": "skyvern", - "X-Fern-SDK-Version": "1.0.37", + "X-Fern-SDK-Version": "1.0.45", **(self.get_custom_headers() or {}), } if self._api_key is not None: diff --git a/skyvern/client/core/pydantic_utilities.py b/skyvern/client/core/pydantic_utilities.py index b92e0b67a..80f1156f0 100644 --- a/skyvern/client/core/pydantic_utilities.py +++ b/skyvern/client/core/pydantic_utilities.py @@ -209,6 +209,7 @@ def update_forward_refs(model: Type["Model"], **localns: Any) -> None: try: model.model_rebuild(raise_errors=False) # type: ignore[attr-defined] except KeyError as exc: + # Manual patch (reapplied by scripts/patch_generated_client.py): # Pydantic v2 can still raise internal schema-gathering KeyErrors # for Fern-generated recursive unions even with raise_errors=False. # Match on the "definitions" key rather than the exact args tuple so a diff --git a/skyvern/client/raw_client.py b/skyvern/client/raw_client.py index d3693789d..7938c1c57 100644 --- a/skyvern/client/raw_client.py +++ b/skyvern/client/raw_client.py @@ -6,6 +6,7 @@ from json.decoder import JSONDecodeError from .core.api_error import ApiError from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from .core.datetime_utils import serialize_datetime from .core.http_response import AsyncHttpResponse, HttpResponse from .core.jsonable_encoder import jsonable_encoder from .core.pydantic_utilities import parse_obj_as @@ -21,8 +22,10 @@ from .types.artifact_type import ArtifactType from .types.browser_profile import BrowserProfile from .types.browser_session_response import BrowserSessionResponse from .types.bulk_cancel_runs_response import BulkCancelRunsResponse +from .types.create_browser_profile_request_proxy_location import CreateBrowserProfileRequestProxyLocation from .types.create_browser_session_request_proxy_location import CreateBrowserSessionRequestProxyLocation from .types.create_credential_request_credential import CreateCredentialRequestCredential +from .types.create_credential_request_proxy_location import CreateCredentialRequestProxyLocation from .types.create_script_response import CreateScriptResponse from .types.credential_response import CredentialResponse from .types.credential_vault_type import CredentialVaultType @@ -42,11 +45,18 @@ from .types.script import Script from .types.script_file_create import ScriptFileCreate from .types.skyvern_forge_sdk_schemas_credentials_credential_type import SkyvernForgeSdkSchemasCredentialsCredentialType from .types.skyvern_schemas_credential_type_credential_type import SkyvernSchemasCredentialTypeCredentialType +from .types.tag_delete_input import TagDeleteInput +from .types.tag_history_response import TagHistoryResponse +from .types.tag_input import TagInput +from .types.tag_key import TagKey +from .types.tag_key_delete_response import TagKeyDeleteResponse +from .types.tags_response import TagsResponse from .types.task_run_list_item import TaskRunListItem from .types.task_run_request_input_data_extraction_schema import TaskRunRequestInputDataExtractionSchema from .types.task_run_request_input_proxy_location import TaskRunRequestInputProxyLocation from .types.task_run_response import TaskRunResponse from .types.totp_code import TotpCode +from .types.update_browser_profile_request_proxy_location import UpdateBrowserProfileRequestProxyLocation from .types.upload_file_response import UploadFileResponse from .types.workflow import Workflow from .types.workflow_create_yaml_request import WorkflowCreateYamlRequest @@ -56,6 +66,7 @@ from .types.workflow_run_response import WorkflowRunResponse from .types.workflow_run_status import WorkflowRunStatus from .types.workflow_run_timeline import WorkflowRunTimeline from .types.workflow_status import WorkflowStatus +from .types.workflow_tags_batch_response import WorkflowTagsBatchResponse # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -289,7 +300,7 @@ class RawSkyvern: def run_workflow( self, *, - workflow_id: str, + agent_id: str, template: typing.Optional[bool] = None, max_steps_override: typing.Optional[int] = None, user_agent: typing.Optional[str] = None, @@ -312,12 +323,12 @@ class RawSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[WorkflowRunResponse]: """ - Run a workflow + Run an agent Parameters ---------- - workflow_id : str - ID of the workflow to run. Workflow ID starts with `wpid_`. + agent_id : str + ID of the agent to run. Starts with `wpid_`. `workflow_id` is accepted as an alias. template : typing.Optional[bool] @@ -415,16 +426,16 @@ class RawSkyvern: Returns ------- HttpResponse[WorkflowRunResponse] - Successfully run workflow + Successfully ran agent """ _response = self._client_wrapper.httpx_client.request( - "v1/run/workflows", + "v1/run/agents", method="POST", params={ "template": template, }, json={ - "workflow_id": workflow_id, + "agent_id": agent_id, "parameters": parameters, "title": title, "proxy_location": convert_and_respect_annotation_metadata( @@ -671,6 +682,7 @@ class RawSkyvern: title: typing.Optional[str] = None, folder_id: typing.Optional[str] = None, status: typing.Optional[typing.Union[WorkflowStatus, typing.Sequence[WorkflowStatus]]] = None, + tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, template: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[typing.List[Workflow]]: @@ -707,6 +719,9 @@ class RawSkyvern: status : typing.Optional[typing.Union[WorkflowStatus, typing.Sequence[WorkflowStatus]]] + tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] + Filter by tags. Each term is a label (`production`), a group (`env:*`), or a group:label (`env:prod`). Repeat the param or comma-separate (`?tags=env:prod,env:staging`). AND across distinct terms, OR within a group's labels (`?tags=customer:acme,env:prod,env:staging` -> customer=acme AND env in (prod, staging)). A label term matches the value across any/no group. Matches current tag values only. Not supported with `template=true`. + template : typing.Optional[bool] request_options : typing.Optional[RequestOptions] @@ -718,7 +733,7 @@ class RawSkyvern: Successful Response """ _response = self._client_wrapper.httpx_client.request( - "v1/workflows", + "v1/agents", method="GET", params={ "page": page, @@ -730,6 +745,7 @@ class RawSkyvern: "title": title, "folder_id": folder_id, "status": status, + "tags": tags, "template": template, }, request_options=request_options, @@ -769,7 +785,7 @@ class RawSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Workflow]: """ - Create a new workflow + Create a new agent Parameters ---------- @@ -788,10 +804,10 @@ class RawSkyvern: Returns ------- HttpResponse[Workflow] - Successfully created workflow + Successfully created agent """ _response = self._client_wrapper.httpx_client.request( - "v1/workflows", + "v1/agents", method="POST", params={ "folder_id": folder_id, @@ -843,12 +859,12 @@ class RawSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Workflow]: """ - Update a workflow + Update an agent Parameters ---------- workflow_id : str - The ID of the workflow to update. Workflow ID starts with `wpid_`. + The ID of the agent to update. Starts with `wpid_`. json_definition : typing.Optional[WorkflowCreateYamlRequest] Workflow definition in JSON format @@ -862,10 +878,10 @@ class RawSkyvern: Returns ------- HttpResponse[Workflow] - Successfully updated workflow + Successfully updated agent """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_id)}", + f"v1/agents/{jsonable_encoder(workflow_id)}", method="POST", json={ "json_definition": convert_and_respect_annotation_metadata( @@ -909,12 +925,12 @@ class RawSkyvern: self, workflow_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[typing.Optional[typing.Any]]: """ - Delete a workflow + Delete an agent Parameters ---------- workflow_id : str - The ID of the workflow to delete. Workflow ID starts with `wpid_`. + The ID of the agent to delete. Starts with `wpid_`. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -922,10 +938,10 @@ class RawSkyvern: Returns ------- HttpResponse[typing.Optional[typing.Any]] - Successfully deleted workflow + Successfully deleted agent """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_id)}/delete", + f"v1/agents/{jsonable_encoder(workflow_id)}/delete", method="POST", request_options=request_options, ) @@ -1311,37 +1327,145 @@ class RawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def update_workflow_folder( - self, - workflow_permanent_id: str, - *, - folder_id: typing.Optional[str] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Workflow]: + def list_tag_keys( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.List[TagKey]]: """ - Update a workflow's folder assignment for the latest version + List all tag keys registered for the organization with their descriptions. Parameters ---------- - workflow_permanent_id : str - Workflow permanent ID + request_options : typing.Optional[RequestOptions] + Request-specific configuration. - folder_id : typing.Optional[str] - Folder ID to assign workflow to. Set to null to remove from folder. + Returns + ------- + HttpResponse[typing.List[TagKey]] + Successfully retrieved tag keys + """ + _response = self._client_wrapper.httpx_client.request( + "v1/tag-keys", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[TagKey], + parse_obj_as( + type_=typing.List[TagKey], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_tag_key( + self, key: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[TagKeyDeleteResponse]: + """ + Delete a tag key from the organization registry and remove that tag from every workflow that currently has it (cascade). Returns how many workflows the tag was removed from. + + Parameters + ---------- + key : str + Tag key to delete request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[Workflow] - Successfully updated workflow folder + HttpResponse[TagKeyDeleteResponse] + Successfully deleted tag key """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/folder", - method="PUT", + f"v1/tag-keys/{jsonable_encoder(key)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagKeyDeleteResponse, + parse_obj_as( + type_=TagKeyDeleteResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def update_tag_key( + self, + key: str, + *, + description: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TagKey]: + """ + Update the description for a tag key. + + Parameters + ---------- + key : str + Tag key to update + + description : typing.Optional[str] + Free-form description (max 500 chars). Pass null to clear. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TagKey] + Successfully updated tag key + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/tag-keys/{jsonable_encoder(key)}", + method="PATCH", json={ - "folder_id": folder_id, + "description": description, }, headers={ "content-type": "application/json", @@ -1352,9 +1476,76 @@ class RawSkyvern: try: if 200 <= _response.status_code < 300: _data = typing.cast( - Workflow, + TagKey, parse_obj_as( - type_=Workflow, # type: ignore + type_=TagKey, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def batch_get_workflow_tags( + self, + *, + workflow_permanent_ids: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[WorkflowTagsBatchResponse]: + """ + Batch fetch current tags for many workflows. Avoids N+1 on the workflows-list page. + + Parameters + ---------- + workflow_permanent_ids : typing.Optional[str] + Comma-separated workflow permanent IDs + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[WorkflowTagsBatchResponse] + Successfully retrieved tags + """ + _response = self._client_wrapper.httpx_client.request( + "v1/workflow-tags", + method="GET", + params={ + "workflow_permanent_ids": workflow_permanent_ids, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + WorkflowTagsBatchResponse, + parse_obj_as( + type_=WorkflowTagsBatchResponse, # type: ignore object_=_response.json(), ), ) @@ -1370,8 +1561,68 @@ class RawSkyvern: ), ), ) - if _response.status_code == 404: - raise NotFoundError( + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def batch_get_workflow_tags_post( + self, + *, + workflow_permanent_ids: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[WorkflowTagsBatchResponse]: + """ + Batch fetch current tags for many workflows (POST variant for id lists exceeding URL length). + + Parameters + ---------- + workflow_permanent_ids : typing.Optional[typing.Sequence[str]] + Workflow permanent IDs to fetch tags for. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[WorkflowTagsBatchResponse] + Successfully retrieved tags + """ + _response = self._client_wrapper.httpx_client.request( + "v1/workflow-tags", + method="POST", + json={ + "workflow_permanent_ids": workflow_permanent_ids, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + WorkflowTagsBatchResponse, + parse_obj_as( + type_=WorkflowTagsBatchResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( headers=dict(_response.headers), body=typing.cast( typing.Optional[typing.Any], @@ -1591,86 +1842,37 @@ class RawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def retry_workflow_run( - self, - workflow_run_id: str, - *, - max_steps_override: typing.Optional[int] = None, - user_agent: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[WorkflowRunResponse]: + def get_version( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.Dict[str, str]]: """ - Retry a workflow run using the original run parameters. + Returns the current Skyvern server version (git SHA for official builds). Parameters ---------- - workflow_run_id : str - The id of the workflow run to retry. - - max_steps_override : typing.Optional[int] - - user_agent : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[WorkflowRunResponse] - Successfully retried workflow run + HttpResponse[typing.Dict[str, str]] + Current server version """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/runs/{jsonable_encoder(workflow_run_id)}/retry", - method="POST", - headers={ - "x-max-steps-override": str(max_steps_override) if max_steps_override is not None else None, - "x-user-agent": str(user_agent) if user_agent is not None else None, - }, + "v1/version", + method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - WorkflowRunResponse, + typing.Dict[str, str], parse_obj_as( - type_=WorkflowRunResponse, # type: ignore + type_=typing.Dict[str, str], # type: ignore object_=_response.json(), ), ) return HttpResponse(response=_response, data=_data) - if _response.status_code == 400: - raise BadRequestError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 404: - raise NotFoundError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) _response_json = _response.json() except JSONDecodeError: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) @@ -1742,316 +1944,6 @@ class RawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def get_workflow_runs( - self, - *, - page: typing.Optional[int] = None, - page_size: typing.Optional[int] = None, - status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, - search_key: typing.Optional[str] = None, - error_code: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[typing.List[WorkflowRun]]: - """ - List workflow runs across all workflows for the current organization. - - Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. - - ### search_key - - A case-insensitive substring search that matches against **any** of the following fields: - - | Searched field | Description | - |---|---| - | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | - | Parameter **key** | The `key` of any workflow parameter definition associated with the run | - | Parameter **description** | The `description` of any workflow parameter definition | - | Run parameter **value** | The actual value supplied for any parameter when the run was created | - | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | - - Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. - - ### error_code - - An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). - - ### Combining filters - - All query parameters use AND logic: - - `?status=failed` — only failed runs - - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error - - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match - - Parameters - ---------- - page : typing.Optional[int] - Page number for pagination. - - page_size : typing.Optional[int] - Number of runs to return per page. - - status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] - Filter by one or more run statuses. - - search_key : typing.Optional[str] - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. - - error_code : typing.Optional[str] - Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - HttpResponse[typing.List[WorkflowRun]] - Successful Response - """ - _response = self._client_wrapper.httpx_client.request( - "v1/workflows/runs", - method="GET", - params={ - "page": page, - "page_size": page_size, - "status": status, - "search_key": search_key, - "error_code": error_code, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - typing.List[WorkflowRun], - parse_obj_as( - type_=typing.List[WorkflowRun], # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - - def get_workflow_runs_by_id( - self, - workflow_id: str, - *, - page: typing.Optional[int] = None, - page_size: typing.Optional[int] = None, - status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, - search_key: typing.Optional[str] = None, - error_code: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[typing.List[WorkflowRun]]: - """ - List runs for a specific workflow. - - Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. - - ### search_key - - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. - - ### error_code - - Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. - - Parameters - ---------- - workflow_id : str - - page : typing.Optional[int] - Page number for pagination. - - page_size : typing.Optional[int] - Number of runs to return per page. - - status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] - Filter by one or more run statuses. - - search_key : typing.Optional[str] - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. - - error_code : typing.Optional[str] - Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - HttpResponse[typing.List[WorkflowRun]] - Successful Response - """ - _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_id)}/runs", - method="GET", - params={ - "page": page, - "page_size": page_size, - "status": status, - "search_key": search_key, - "error_code": error_code, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - typing.List[WorkflowRun], - parse_obj_as( - type_=typing.List[WorkflowRun], # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - - def get_workflow( - self, - workflow_permanent_id: str, - *, - version: typing.Optional[int] = None, - template: typing.Optional[bool] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Workflow]: - """ - Parameters - ---------- - workflow_permanent_id : str - - version : typing.Optional[int] - - template : typing.Optional[bool] - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - HttpResponse[Workflow] - Successful Response - """ - _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}", - method="GET", - params={ - "version": version, - "template": template, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - Workflow, - parse_obj_as( - type_=Workflow, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - - def get_workflow_versions( - self, - workflow_permanent_id: str, - *, - template: typing.Optional[bool] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[typing.List[Workflow]]: - """ - Get all versions of a workflow by its permanent ID. - - Parameters - ---------- - workflow_permanent_id : str - - template : typing.Optional[bool] - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - HttpResponse[typing.List[Workflow]] - Successful Response - """ - _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/versions", - method="GET", - params={ - "template": template, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - typing.List[Workflow], - parse_obj_as( - type_=typing.List[Workflow], # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def upload_file( self, *, file: str, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[UploadFileResponse]: @@ -2181,7 +2073,7 @@ class RawSkyvern: description: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, workflow_run_id: typing.Optional[str] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateBrowserProfileRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[BrowserProfile]: @@ -2202,11 +2094,11 @@ class RawSkyvern: workflow_run_id : typing.Optional[str] Workflow run whose persisted session should be captured. Omit for a blank profile. - proxy_location : typing.Optional[ProxyLocation] - Optional proxy location for this browser profile's pinned proxy identity. + proxy_location : typing.Optional[CreateBrowserProfileRequestProxyLocation] + Optional proxy location for this profile's pinned proxy identity. proxy_session_id : typing.Optional[str] - Optional advanced reuse key for this browser profile's pinned proxy identity. + Explicit sticky-session id for this profile's pinned proxy identity. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2224,7 +2116,9 @@ class RawSkyvern: "description": description, "browser_session_id": browser_session_id, "workflow_run_id": workflow_run_id, - "proxy_location": proxy_location, + "proxy_location": convert_and_respect_annotation_metadata( + object_=proxy_location, annotation=CreateBrowserProfileRequestProxyLocation, direction="write" + ), "proxy_session_id": proxy_session_id, }, headers={ @@ -2401,7 +2295,7 @@ class RawSkyvern: *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[UpdateBrowserProfileRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -2420,14 +2314,14 @@ class RawSkyvern: description : typing.Optional[str] New description for the browser profile - proxy_location : typing.Optional[ProxyLocation] - Optional proxy location for this browser profile's pinned proxy identity. + proxy_location : typing.Optional[UpdateBrowserProfileRequestProxyLocation] + Optional proxy location for this profile's pinned proxy identity. proxy_session_id : typing.Optional[str] - Optional advanced reuse key for this browser profile's pinned proxy identity. + Opaque Skyvern-managed proxy sticky-session id. rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this browser profile. + Rotate the Skyvern-managed proxy sticky-session id for this profile. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2443,7 +2337,9 @@ class RawSkyvern: json={ "name": name, "description": description, - "proxy_location": proxy_location, + "proxy_location": convert_and_respect_annotation_metadata( + object_=proxy_location, annotation=UpdateBrowserProfileRequestProxyLocation, direction="write" + ), "proxy_session_id": proxy_session_id, "rotate_proxy_session_id": rotate_proxy_session_id, }, @@ -2564,10 +2460,10 @@ class RawSkyvern: *, timeout: typing.Optional[int] = OMIT, proxy_location: typing.Optional[CreateBrowserSessionRequestProxyLocation] = OMIT, - proxy_session_id: typing.Optional[str] = OMIT, extensions: typing.Optional[typing.Sequence[Extensions]] = OMIT, browser_type: typing.Optional[PersistentBrowserType] = OMIT, browser_profile_id: typing.Optional[str] = OMIT, + generate_browser_profile: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[BrowserSessionResponse]: """ @@ -2615,9 +2511,6 @@ class RawSkyvern: For self-hosted deployments, you can pass a custom proxy URL as a dict: {"url": "http://user:password@proxy.example.com:8080"}. This routes the browser through your own proxy server and takes precedence over any globally configured proxy pool. Can also be a GeoTarget object for granular city/state targeting: {"country": "US", "subdivision": "CA", "city": "San Francisco"}, or a custom proxy URL dict for self-hosted deployments: {"url": "http://user:password@proxy.example.com:8080"} - proxy_session_id : typing.Optional[str] - Opaque Skyvern-managed proxy sticky-session id for pinned Residential ISP sessions. - extensions : typing.Optional[typing.Sequence[Extensions]] A list of extensions to install in the browser session. @@ -2627,6 +2520,9 @@ class RawSkyvern: browser_profile_id : typing.Optional[str] ID of a browser profile to load into this session (restores cookies, localStorage, etc.). browser_profile_id starts with `bp_`. + generate_browser_profile : typing.Optional[bool] + When true, the session's browser profile (cookies, localStorage, etc.) is saved to storage when the session ends so it can be turned into a reusable browser profile. Defaults to false to avoid storing profiles for sessions that never need them. Sessions started with a browser_profile_id always persist their profile regardless of this flag. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2643,10 +2539,10 @@ class RawSkyvern: "proxy_location": convert_and_respect_annotation_metadata( object_=proxy_location, annotation=CreateBrowserSessionRequestProxyLocation, direction="write" ), - "proxy_session_id": proxy_session_id, "extensions": extensions, "browser_type": browser_type, "browser_profile_id": browser_profile_id, + "generate_browser_profile": generate_browser_profile, }, headers={ "content-type": "application/json", @@ -2837,6 +2733,103 @@ class RawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def update_browser_session( + self, + browser_session_id: str, + *, + generate_browser_profile: bool, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[BrowserSessionResponse]: + """ + Update a live browser session. Currently supports toggling generate_browser_profile, which is read when the session ends to decide whether to save its browser profile. + + Parameters + ---------- + browser_session_id : str + The ID of the browser session. browser_session_id starts with `pbs_` + + generate_browser_profile : bool + Enable or disable saving this session's browser profile when it ends. Can be toggled while the session is still alive; the value is read at session teardown. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[BrowserSessionResponse] + Successfully updated browser session + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/browser_sessions/{jsonable_encoder(browser_session_id)}", + method="PATCH", + json={ + "generate_browser_profile": generate_browser_profile, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BrowserSessionResponse, + parse_obj_as( + type_=BrowserSessionResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def send_totp_code( self, *, @@ -2938,6 +2931,8 @@ class RawSkyvern: page: typing.Optional[int] = None, page_size: typing.Optional[int] = None, vault_type: typing.Optional[CredentialVaultType] = None, + credential_type: typing.Optional[SkyvernForgeSdkSchemasCredentialsCredentialType] = None, + search: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[typing.List[CredentialResponse]]: """ @@ -2954,6 +2949,12 @@ class RawSkyvern: vault_type : typing.Optional[CredentialVaultType] Filter credentials by vault type (e.g. 'skyvern', 'custom', 'bitwarden', 'azure_vault') + credential_type : typing.Optional[SkyvernForgeSdkSchemasCredentialsCredentialType] + Filter credentials by type (e.g. 'password', 'credit_card', 'secret') + + search : typing.Optional[str] + Case-insensitive search across credential name, username, secret label, and card details + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2969,6 +2970,8 @@ class RawSkyvern: "page": page, "page_size": page_size, "vault_type": vault_type, + "credential_type": credential_type, + "search": search, }, request_options=request_options, ) @@ -3005,7 +3008,7 @@ class RawSkyvern: credential_type: SkyvernForgeSdkSchemasCredentialsCredentialType, credential: CreateCredentialRequestCredential, vault_type: typing.Optional[CredentialVaultType] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -3027,14 +3030,14 @@ class RawSkyvern: vault_type : typing.Optional[CredentialVaultType] Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. - proxy_location : typing.Optional[ProxyLocation] + proxy_location : typing.Optional[CreateCredentialRequestProxyLocation] Optional proxy location for this credential's pinned proxy identity. proxy_session_id : typing.Optional[str] Optional advanced reuse key for this credential's pinned proxy identity. rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this credential. + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -3054,7 +3057,9 @@ class RawSkyvern: object_=credential, annotation=CreateCredentialRequestCredential, direction="write" ), "vault_type": vault_type, - "proxy_location": proxy_location, + "proxy_location": convert_and_respect_annotation_metadata( + object_=proxy_location, annotation=CreateCredentialRequestProxyLocation, direction="write" + ), "proxy_session_id": proxy_session_id, "rotate_proxy_session_id": rotate_proxy_session_id, }, @@ -3098,7 +3103,7 @@ class RawSkyvern: credential_type: SkyvernForgeSdkSchemasCredentialsCredentialType, credential: CreateCredentialRequestCredential, vault_type: typing.Optional[CredentialVaultType] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -3123,14 +3128,14 @@ class RawSkyvern: vault_type : typing.Optional[CredentialVaultType] Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. - proxy_location : typing.Optional[ProxyLocation] + proxy_location : typing.Optional[CreateCredentialRequestProxyLocation] Optional proxy location for this credential's pinned proxy identity. proxy_session_id : typing.Optional[str] Optional advanced reuse key for this credential's pinned proxy identity. rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this credential. + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -3150,7 +3155,9 @@ class RawSkyvern: object_=credential, annotation=CreateCredentialRequestCredential, direction="write" ), "vault_type": vault_type, - "proxy_location": proxy_location, + "proxy_location": convert_and_respect_annotation_metadata( + object_=proxy_location, annotation=CreateCredentialRequestProxyLocation, direction="write" + ), "proxy_session_id": proxy_session_id, "rotate_proxy_session_id": rotate_proxy_session_id, }, @@ -3912,6 +3919,777 @@ class RawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def update_workflow_folder( + self, + workflow_permanent_id: str, + *, + folder_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Workflow]: + """ + Update a workflow's folder assignment for the latest version + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + folder_id : typing.Optional[str] + Folder ID to assign workflow to. Set to null to remove from folder. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Workflow] + Successfully updated workflow folder + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/folder", + method="PUT", + json={ + "folder_id": folder_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Workflow, + parse_obj_as( + type_=Workflow, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_workflow_tags( + self, workflow_permanent_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[TagsResponse]: + """ + Get the current tag state for a workflow. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TagsResponse] + Successfully retrieved tags + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/tags", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagsResponse, + parse_obj_as( + type_=TagsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def apply_workflow_tags( + self, + workflow_permanent_id: str, + *, + tags: typing.Optional[typing.Sequence[TagInput]] = OMIT, + tags_to_delete: typing.Optional[typing.Sequence[TagDeleteInput]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TagsResponse]: + """ + Atomically apply tag changes to a workflow. Sets and deletes happen in one transaction; same-key collisions resolve set-wins. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + tags : typing.Optional[typing.Sequence[TagInput]] + Tags to set (overwrite). List of {key?, value} objects. + + tags_to_delete : typing.Optional[typing.Sequence[TagDeleteInput]] + Tags to soft-delete. List of {key?, value?} targets. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TagsResponse] + Successfully applied tag changes + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/tags", + method="POST", + json={ + "tags": convert_and_respect_annotation_metadata( + object_=tags, annotation=typing.Sequence[TagInput], direction="write" + ), + "tags_to_delete": convert_and_respect_annotation_metadata( + object_=tags_to_delete, annotation=typing.Sequence[TagDeleteInput], direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagsResponse, + parse_obj_as( + type_=TagsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_workflow_tag( + self, workflow_permanent_id: str, key: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[TagsResponse]: + """ + Soft-delete a single tag from a workflow. Writes a DELETE event row. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + key : str + Tag key to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TagsResponse] + Successfully deleted tag (or no-op if absent) + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/tags/{jsonable_encoder(key)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagsResponse, + parse_obj_as( + type_=TagsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_workflow_tag_history( + self, + workflow_permanent_id: str, + *, + limit: typing.Optional[int] = None, + since: typing.Optional[dt.datetime] = None, + key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[TagHistoryResponse]: + """ + Chronological tag-event log for a workflow (newest first). Includes SET and DELETE events. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + limit : typing.Optional[int] + Max events to return + + since : typing.Optional[dt.datetime] + Only return events at or after this timestamp + + key : typing.Optional[str] + Filter to events for a single tag key + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TagHistoryResponse] + Successfully retrieved tag history + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/tags/history", + method="GET", + params={ + "limit": limit, + "since": serialize_datetime(since) if since is not None else None, + "key": key, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagHistoryResponse, + parse_obj_as( + type_=TagHistoryResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def retry_workflow_run( + self, + workflow_run_id: str, + *, + max_steps_override: typing.Optional[int] = None, + user_agent: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[WorkflowRunResponse]: + """ + Retry a workflow run using the original run parameters. + + Parameters + ---------- + workflow_run_id : str + The id of the workflow run to retry. + + max_steps_override : typing.Optional[int] + + user_agent : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[WorkflowRunResponse] + Successfully retried workflow run + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/runs/{jsonable_encoder(workflow_run_id)}/retry", + method="POST", + headers={ + "x-max-steps-override": str(max_steps_override) if max_steps_override is not None else None, + "x-user-agent": str(user_agent) if user_agent is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + WorkflowRunResponse, + parse_obj_as( + type_=WorkflowRunResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_workflow_runs( + self, + *, + page: typing.Optional[int] = None, + page_size: typing.Optional[int] = None, + status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, + search_key: typing.Optional[str] = None, + error_code: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[typing.List[WorkflowRun]]: + """ + List workflow runs across all workflows for the current organization. + + Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. + + ### search_key + + A case-insensitive substring search that matches against **any** of the following fields: + + | Searched field | Description | + |---|---| + | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | + | Parameter **key** | The `key` of any workflow parameter definition associated with the run | + | Parameter **description** | The `description` of any workflow parameter definition | + | Run parameter **value** | The actual value supplied for any parameter when the run was created | + | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | + + Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. + + ### error_code + + An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). + + ### Combining filters + + All query parameters use AND logic: + - `?status=failed` — only failed runs + - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error + - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match + + Parameters + ---------- + page : typing.Optional[int] + Page number for pagination. + + page_size : typing.Optional[int] + Number of runs to return per page. + + status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] + Filter by one or more run statuses. + + search_key : typing.Optional[str] + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. + + error_code : typing.Optional[str] + Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.List[WorkflowRun]] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + "v1/agents/runs", + method="GET", + params={ + "page": page, + "page_size": page_size, + "status": status, + "search_key": search_key, + "error_code": error_code, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[WorkflowRun], + parse_obj_as( + type_=typing.List[WorkflowRun], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_workflow_runs_by_id( + self, + workflow_id: str, + *, + page: typing.Optional[int] = None, + page_size: typing.Optional[int] = None, + status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, + search_key: typing.Optional[str] = None, + error_code: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[typing.List[WorkflowRun]]: + """ + List runs for a specific workflow. + + Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. + + ### search_key + + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. + + ### error_code + + Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. + + Parameters + ---------- + workflow_id : str + + page : typing.Optional[int] + Page number for pagination. + + page_size : typing.Optional[int] + Number of runs to return per page. + + status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] + Filter by one or more run statuses. + + search_key : typing.Optional[str] + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. + + error_code : typing.Optional[str] + Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.List[WorkflowRun]] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_id)}/runs", + method="GET", + params={ + "page": page, + "page_size": page_size, + "status": status, + "search_key": search_key, + "error_code": error_code, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[WorkflowRun], + parse_obj_as( + type_=typing.List[WorkflowRun], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_workflow( + self, + workflow_permanent_id: str, + *, + version: typing.Optional[int] = None, + template: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Workflow]: + """ + Parameters + ---------- + workflow_permanent_id : str + + version : typing.Optional[int] + + template : typing.Optional[bool] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Workflow] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}", + method="GET", + params={ + "version": version, + "template": template, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Workflow, + parse_obj_as( + type_=Workflow, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_workflow_versions( + self, + workflow_permanent_id: str, + *, + template: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[typing.List[Workflow]]: + """ + Get all versions of a workflow by its permanent ID. + + Parameters + ---------- + workflow_permanent_id : str + + template : typing.Optional[bool] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.List[Workflow]] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/versions", + method="GET", + params={ + "template": template, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[Workflow], + parse_obj_as( + type_=typing.List[Workflow], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + class AsyncRawSkyvern: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -4141,7 +4919,7 @@ class AsyncRawSkyvern: async def run_workflow( self, *, - workflow_id: str, + agent_id: str, template: typing.Optional[bool] = None, max_steps_override: typing.Optional[int] = None, user_agent: typing.Optional[str] = None, @@ -4164,12 +4942,12 @@ class AsyncRawSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[WorkflowRunResponse]: """ - Run a workflow + Run an agent Parameters ---------- - workflow_id : str - ID of the workflow to run. Workflow ID starts with `wpid_`. + agent_id : str + ID of the agent to run. Starts with `wpid_`. `workflow_id` is accepted as an alias. template : typing.Optional[bool] @@ -4267,16 +5045,16 @@ class AsyncRawSkyvern: Returns ------- AsyncHttpResponse[WorkflowRunResponse] - Successfully run workflow + Successfully ran agent """ _response = await self._client_wrapper.httpx_client.request( - "v1/run/workflows", + "v1/run/agents", method="POST", params={ "template": template, }, json={ - "workflow_id": workflow_id, + "agent_id": agent_id, "parameters": parameters, "title": title, "proxy_location": convert_and_respect_annotation_metadata( @@ -4523,6 +5301,7 @@ class AsyncRawSkyvern: title: typing.Optional[str] = None, folder_id: typing.Optional[str] = None, status: typing.Optional[typing.Union[WorkflowStatus, typing.Sequence[WorkflowStatus]]] = None, + tags: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, template: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[typing.List[Workflow]]: @@ -4559,6 +5338,9 @@ class AsyncRawSkyvern: status : typing.Optional[typing.Union[WorkflowStatus, typing.Sequence[WorkflowStatus]]] + tags : typing.Optional[typing.Union[str, typing.Sequence[str]]] + Filter by tags. Each term is a label (`production`), a group (`env:*`), or a group:label (`env:prod`). Repeat the param or comma-separate (`?tags=env:prod,env:staging`). AND across distinct terms, OR within a group's labels (`?tags=customer:acme,env:prod,env:staging` -> customer=acme AND env in (prod, staging)). A label term matches the value across any/no group. Matches current tag values only. Not supported with `template=true`. + template : typing.Optional[bool] request_options : typing.Optional[RequestOptions] @@ -4570,7 +5352,7 @@ class AsyncRawSkyvern: Successful Response """ _response = await self._client_wrapper.httpx_client.request( - "v1/workflows", + "v1/agents", method="GET", params={ "page": page, @@ -4582,6 +5364,7 @@ class AsyncRawSkyvern: "title": title, "folder_id": folder_id, "status": status, + "tags": tags, "template": template, }, request_options=request_options, @@ -4621,7 +5404,7 @@ class AsyncRawSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Workflow]: """ - Create a new workflow + Create a new agent Parameters ---------- @@ -4640,10 +5423,10 @@ class AsyncRawSkyvern: Returns ------- AsyncHttpResponse[Workflow] - Successfully created workflow + Successfully created agent """ _response = await self._client_wrapper.httpx_client.request( - "v1/workflows", + "v1/agents", method="POST", params={ "folder_id": folder_id, @@ -4695,12 +5478,12 @@ class AsyncRawSkyvern: request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Workflow]: """ - Update a workflow + Update an agent Parameters ---------- workflow_id : str - The ID of the workflow to update. Workflow ID starts with `wpid_`. + The ID of the agent to update. Starts with `wpid_`. json_definition : typing.Optional[WorkflowCreateYamlRequest] Workflow definition in JSON format @@ -4714,10 +5497,10 @@ class AsyncRawSkyvern: Returns ------- AsyncHttpResponse[Workflow] - Successfully updated workflow + Successfully updated agent """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_id)}", + f"v1/agents/{jsonable_encoder(workflow_id)}", method="POST", json={ "json_definition": convert_and_respect_annotation_metadata( @@ -4761,12 +5544,12 @@ class AsyncRawSkyvern: self, workflow_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[typing.Optional[typing.Any]]: """ - Delete a workflow + Delete an agent Parameters ---------- workflow_id : str - The ID of the workflow to delete. Workflow ID starts with `wpid_`. + The ID of the agent to delete. Starts with `wpid_`. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -4774,10 +5557,10 @@ class AsyncRawSkyvern: Returns ------- AsyncHttpResponse[typing.Optional[typing.Any]] - Successfully deleted workflow + Successfully deleted agent """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_id)}/delete", + f"v1/agents/{jsonable_encoder(workflow_id)}/delete", method="POST", request_options=request_options, ) @@ -5163,37 +5946,145 @@ class AsyncRawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - async def update_workflow_folder( - self, - workflow_permanent_id: str, - *, - folder_id: typing.Optional[str] = OMIT, - request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[Workflow]: + async def list_tag_keys( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[typing.List[TagKey]]: """ - Update a workflow's folder assignment for the latest version + List all tag keys registered for the organization with their descriptions. Parameters ---------- - workflow_permanent_id : str - Workflow permanent ID + request_options : typing.Optional[RequestOptions] + Request-specific configuration. - folder_id : typing.Optional[str] - Folder ID to assign workflow to. Set to null to remove from folder. + Returns + ------- + AsyncHttpResponse[typing.List[TagKey]] + Successfully retrieved tag keys + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/tag-keys", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[TagKey], + parse_obj_as( + type_=typing.List[TagKey], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_tag_key( + self, key: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[TagKeyDeleteResponse]: + """ + Delete a tag key from the organization registry and remove that tag from every workflow that currently has it (cascade). Returns how many workflows the tag was removed from. + + Parameters + ---------- + key : str + Tag key to delete request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[Workflow] - Successfully updated workflow folder + AsyncHttpResponse[TagKeyDeleteResponse] + Successfully deleted tag key """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/folder", - method="PUT", + f"v1/tag-keys/{jsonable_encoder(key)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagKeyDeleteResponse, + parse_obj_as( + type_=TagKeyDeleteResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def update_tag_key( + self, + key: str, + *, + description: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TagKey]: + """ + Update the description for a tag key. + + Parameters + ---------- + key : str + Tag key to update + + description : typing.Optional[str] + Free-form description (max 500 chars). Pass null to clear. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TagKey] + Successfully updated tag key + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/tag-keys/{jsonable_encoder(key)}", + method="PATCH", json={ - "folder_id": folder_id, + "description": description, }, headers={ "content-type": "application/json", @@ -5204,9 +6095,76 @@ class AsyncRawSkyvern: try: if 200 <= _response.status_code < 300: _data = typing.cast( - Workflow, + TagKey, parse_obj_as( - type_=Workflow, # type: ignore + type_=TagKey, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def batch_get_workflow_tags( + self, + *, + workflow_permanent_ids: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[WorkflowTagsBatchResponse]: + """ + Batch fetch current tags for many workflows. Avoids N+1 on the workflows-list page. + + Parameters + ---------- + workflow_permanent_ids : typing.Optional[str] + Comma-separated workflow permanent IDs + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[WorkflowTagsBatchResponse] + Successfully retrieved tags + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/workflow-tags", + method="GET", + params={ + "workflow_permanent_ids": workflow_permanent_ids, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + WorkflowTagsBatchResponse, + parse_obj_as( + type_=WorkflowTagsBatchResponse, # type: ignore object_=_response.json(), ), ) @@ -5222,8 +6180,68 @@ class AsyncRawSkyvern: ), ), ) - if _response.status_code == 404: - raise NotFoundError( + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def batch_get_workflow_tags_post( + self, + *, + workflow_permanent_ids: typing.Optional[typing.Sequence[str]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[WorkflowTagsBatchResponse]: + """ + Batch fetch current tags for many workflows (POST variant for id lists exceeding URL length). + + Parameters + ---------- + workflow_permanent_ids : typing.Optional[typing.Sequence[str]] + Workflow permanent IDs to fetch tags for. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[WorkflowTagsBatchResponse] + Successfully retrieved tags + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/workflow-tags", + method="POST", + json={ + "workflow_permanent_ids": workflow_permanent_ids, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + WorkflowTagsBatchResponse, + parse_obj_as( + type_=WorkflowTagsBatchResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( headers=dict(_response.headers), body=typing.cast( typing.Optional[typing.Any], @@ -5443,86 +6461,37 @@ class AsyncRawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - async def retry_workflow_run( - self, - workflow_run_id: str, - *, - max_steps_override: typing.Optional[int] = None, - user_agent: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[WorkflowRunResponse]: + async def get_version( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[typing.Dict[str, str]]: """ - Retry a workflow run using the original run parameters. + Returns the current Skyvern server version (git SHA for official builds). Parameters ---------- - workflow_run_id : str - The id of the workflow run to retry. - - max_steps_override : typing.Optional[int] - - user_agent : typing.Optional[str] - request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[WorkflowRunResponse] - Successfully retried workflow run + AsyncHttpResponse[typing.Dict[str, str]] + Current server version """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/runs/{jsonable_encoder(workflow_run_id)}/retry", - method="POST", - headers={ - "x-max-steps-override": str(max_steps_override) if max_steps_override is not None else None, - "x-user-agent": str(user_agent) if user_agent is not None else None, - }, + "v1/version", + method="GET", request_options=request_options, ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - WorkflowRunResponse, + typing.Dict[str, str], parse_obj_as( - type_=WorkflowRunResponse, # type: ignore + type_=typing.Dict[str, str], # type: ignore object_=_response.json(), ), ) return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 400: - raise BadRequestError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 404: - raise NotFoundError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) _response_json = _response.json() except JSONDecodeError: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) @@ -5594,316 +6563,6 @@ class AsyncRawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - async def get_workflow_runs( - self, - *, - page: typing.Optional[int] = None, - page_size: typing.Optional[int] = None, - status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, - search_key: typing.Optional[str] = None, - error_code: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[typing.List[WorkflowRun]]: - """ - List workflow runs across all workflows for the current organization. - - Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. - - ### search_key - - A case-insensitive substring search that matches against **any** of the following fields: - - | Searched field | Description | - |---|---| - | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | - | Parameter **key** | The `key` of any workflow parameter definition associated with the run | - | Parameter **description** | The `description` of any workflow parameter definition | - | Run parameter **value** | The actual value supplied for any parameter when the run was created | - | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | - - Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. - - ### error_code - - An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). - - ### Combining filters - - All query parameters use AND logic: - - `?status=failed` — only failed runs - - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error - - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match - - Parameters - ---------- - page : typing.Optional[int] - Page number for pagination. - - page_size : typing.Optional[int] - Number of runs to return per page. - - status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] - Filter by one or more run statuses. - - search_key : typing.Optional[str] - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. - - error_code : typing.Optional[str] - Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - AsyncHttpResponse[typing.List[WorkflowRun]] - Successful Response - """ - _response = await self._client_wrapper.httpx_client.request( - "v1/workflows/runs", - method="GET", - params={ - "page": page, - "page_size": page_size, - "status": status, - "search_key": search_key, - "error_code": error_code, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - typing.List[WorkflowRun], - parse_obj_as( - type_=typing.List[WorkflowRun], # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - - async def get_workflow_runs_by_id( - self, - workflow_id: str, - *, - page: typing.Optional[int] = None, - page_size: typing.Optional[int] = None, - status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, - search_key: typing.Optional[str] = None, - error_code: typing.Optional[str] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[typing.List[WorkflowRun]]: - """ - List runs for a specific workflow. - - Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. - - ### search_key - - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. - - ### error_code - - Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. - - Parameters - ---------- - workflow_id : str - - page : typing.Optional[int] - Page number for pagination. - - page_size : typing.Optional[int] - Number of runs to return per page. - - status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] - Filter by one or more run statuses. - - search_key : typing.Optional[str] - Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. - - error_code : typing.Optional[str] - Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - AsyncHttpResponse[typing.List[WorkflowRun]] - Successful Response - """ - _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_id)}/runs", - method="GET", - params={ - "page": page, - "page_size": page_size, - "status": status, - "search_key": search_key, - "error_code": error_code, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - typing.List[WorkflowRun], - parse_obj_as( - type_=typing.List[WorkflowRun], # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - - async def get_workflow( - self, - workflow_permanent_id: str, - *, - version: typing.Optional[int] = None, - template: typing.Optional[bool] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[Workflow]: - """ - Parameters - ---------- - workflow_permanent_id : str - - version : typing.Optional[int] - - template : typing.Optional[bool] - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - AsyncHttpResponse[Workflow] - Successful Response - """ - _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}", - method="GET", - params={ - "version": version, - "template": template, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - Workflow, - parse_obj_as( - type_=Workflow, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - - async def get_workflow_versions( - self, - workflow_permanent_id: str, - *, - template: typing.Optional[bool] = None, - request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[typing.List[Workflow]]: - """ - Get all versions of a workflow by its permanent ID. - - Parameters - ---------- - workflow_permanent_id : str - - template : typing.Optional[bool] - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - AsyncHttpResponse[typing.List[Workflow]] - Successful Response - """ - _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/versions", - method="GET", - params={ - "template": template, - }, - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - typing.List[Workflow], - parse_obj_as( - type_=typing.List[Workflow], # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 422: - raise UnprocessableEntityError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - async def upload_file( self, *, file: str, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[UploadFileResponse]: @@ -6033,7 +6692,7 @@ class AsyncRawSkyvern: description: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, workflow_run_id: typing.Optional[str] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateBrowserProfileRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[BrowserProfile]: @@ -6054,11 +6713,11 @@ class AsyncRawSkyvern: workflow_run_id : typing.Optional[str] Workflow run whose persisted session should be captured. Omit for a blank profile. - proxy_location : typing.Optional[ProxyLocation] - Optional proxy location for this browser profile's pinned proxy identity. + proxy_location : typing.Optional[CreateBrowserProfileRequestProxyLocation] + Optional proxy location for this profile's pinned proxy identity. proxy_session_id : typing.Optional[str] - Optional advanced reuse key for this browser profile's pinned proxy identity. + Explicit sticky-session id for this profile's pinned proxy identity. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -6076,7 +6735,9 @@ class AsyncRawSkyvern: "description": description, "browser_session_id": browser_session_id, "workflow_run_id": workflow_run_id, - "proxy_location": proxy_location, + "proxy_location": convert_and_respect_annotation_metadata( + object_=proxy_location, annotation=CreateBrowserProfileRequestProxyLocation, direction="write" + ), "proxy_session_id": proxy_session_id, }, headers={ @@ -6253,7 +6914,7 @@ class AsyncRawSkyvern: *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[UpdateBrowserProfileRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -6272,14 +6933,14 @@ class AsyncRawSkyvern: description : typing.Optional[str] New description for the browser profile - proxy_location : typing.Optional[ProxyLocation] - Optional proxy location for this browser profile's pinned proxy identity. + proxy_location : typing.Optional[UpdateBrowserProfileRequestProxyLocation] + Optional proxy location for this profile's pinned proxy identity. proxy_session_id : typing.Optional[str] - Optional advanced reuse key for this browser profile's pinned proxy identity. + Opaque Skyvern-managed proxy sticky-session id. rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this browser profile. + Rotate the Skyvern-managed proxy sticky-session id for this profile. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -6295,7 +6956,9 @@ class AsyncRawSkyvern: json={ "name": name, "description": description, - "proxy_location": proxy_location, + "proxy_location": convert_and_respect_annotation_metadata( + object_=proxy_location, annotation=UpdateBrowserProfileRequestProxyLocation, direction="write" + ), "proxy_session_id": proxy_session_id, "rotate_proxy_session_id": rotate_proxy_session_id, }, @@ -6416,10 +7079,10 @@ class AsyncRawSkyvern: *, timeout: typing.Optional[int] = OMIT, proxy_location: typing.Optional[CreateBrowserSessionRequestProxyLocation] = OMIT, - proxy_session_id: typing.Optional[str] = OMIT, extensions: typing.Optional[typing.Sequence[Extensions]] = OMIT, browser_type: typing.Optional[PersistentBrowserType] = OMIT, browser_profile_id: typing.Optional[str] = OMIT, + generate_browser_profile: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[BrowserSessionResponse]: """ @@ -6467,9 +7130,6 @@ class AsyncRawSkyvern: For self-hosted deployments, you can pass a custom proxy URL as a dict: {"url": "http://user:password@proxy.example.com:8080"}. This routes the browser through your own proxy server and takes precedence over any globally configured proxy pool. Can also be a GeoTarget object for granular city/state targeting: {"country": "US", "subdivision": "CA", "city": "San Francisco"}, or a custom proxy URL dict for self-hosted deployments: {"url": "http://user:password@proxy.example.com:8080"} - proxy_session_id : typing.Optional[str] - Opaque Skyvern-managed proxy sticky-session id for pinned Residential ISP sessions. - extensions : typing.Optional[typing.Sequence[Extensions]] A list of extensions to install in the browser session. @@ -6479,6 +7139,9 @@ class AsyncRawSkyvern: browser_profile_id : typing.Optional[str] ID of a browser profile to load into this session (restores cookies, localStorage, etc.). browser_profile_id starts with `bp_`. + generate_browser_profile : typing.Optional[bool] + When true, the session's browser profile (cookies, localStorage, etc.) is saved to storage when the session ends so it can be turned into a reusable browser profile. Defaults to false to avoid storing profiles for sessions that never need them. Sessions started with a browser_profile_id always persist their profile regardless of this flag. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -6495,10 +7158,10 @@ class AsyncRawSkyvern: "proxy_location": convert_and_respect_annotation_metadata( object_=proxy_location, annotation=CreateBrowserSessionRequestProxyLocation, direction="write" ), - "proxy_session_id": proxy_session_id, "extensions": extensions, "browser_type": browser_type, "browser_profile_id": browser_profile_id, + "generate_browser_profile": generate_browser_profile, }, headers={ "content-type": "application/json", @@ -6689,6 +7352,103 @@ class AsyncRawSkyvern: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def update_browser_session( + self, + browser_session_id: str, + *, + generate_browser_profile: bool, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[BrowserSessionResponse]: + """ + Update a live browser session. Currently supports toggling generate_browser_profile, which is read when the session ends to decide whether to save its browser profile. + + Parameters + ---------- + browser_session_id : str + The ID of the browser session. browser_session_id starts with `pbs_` + + generate_browser_profile : bool + Enable or disable saving this session's browser profile when it ends. Can be toggled while the session is still alive; the value is read at session teardown. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[BrowserSessionResponse] + Successfully updated browser session + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/browser_sessions/{jsonable_encoder(browser_session_id)}", + method="PATCH", + json={ + "generate_browser_profile": generate_browser_profile, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BrowserSessionResponse, + parse_obj_as( + type_=BrowserSessionResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 409: + raise ConflictError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def send_totp_code( self, *, @@ -6790,6 +7550,8 @@ class AsyncRawSkyvern: page: typing.Optional[int] = None, page_size: typing.Optional[int] = None, vault_type: typing.Optional[CredentialVaultType] = None, + credential_type: typing.Optional[SkyvernForgeSdkSchemasCredentialsCredentialType] = None, + search: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[typing.List[CredentialResponse]]: """ @@ -6806,6 +7568,12 @@ class AsyncRawSkyvern: vault_type : typing.Optional[CredentialVaultType] Filter credentials by vault type (e.g. 'skyvern', 'custom', 'bitwarden', 'azure_vault') + credential_type : typing.Optional[SkyvernForgeSdkSchemasCredentialsCredentialType] + Filter credentials by type (e.g. 'password', 'credit_card', 'secret') + + search : typing.Optional[str] + Case-insensitive search across credential name, username, secret label, and card details + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -6821,6 +7589,8 @@ class AsyncRawSkyvern: "page": page, "page_size": page_size, "vault_type": vault_type, + "credential_type": credential_type, + "search": search, }, request_options=request_options, ) @@ -6857,7 +7627,7 @@ class AsyncRawSkyvern: credential_type: SkyvernForgeSdkSchemasCredentialsCredentialType, credential: CreateCredentialRequestCredential, vault_type: typing.Optional[CredentialVaultType] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -6879,14 +7649,14 @@ class AsyncRawSkyvern: vault_type : typing.Optional[CredentialVaultType] Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. - proxy_location : typing.Optional[ProxyLocation] + proxy_location : typing.Optional[CreateCredentialRequestProxyLocation] Optional proxy location for this credential's pinned proxy identity. proxy_session_id : typing.Optional[str] Optional advanced reuse key for this credential's pinned proxy identity. rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this credential. + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -6906,7 +7676,9 @@ class AsyncRawSkyvern: object_=credential, annotation=CreateCredentialRequestCredential, direction="write" ), "vault_type": vault_type, - "proxy_location": proxy_location, + "proxy_location": convert_and_respect_annotation_metadata( + object_=proxy_location, annotation=CreateCredentialRequestProxyLocation, direction="write" + ), "proxy_session_id": proxy_session_id, "rotate_proxy_session_id": rotate_proxy_session_id, }, @@ -6950,7 +7722,7 @@ class AsyncRawSkyvern: credential_type: SkyvernForgeSdkSchemasCredentialsCredentialType, credential: CreateCredentialRequestCredential, vault_type: typing.Optional[CredentialVaultType] = OMIT, - proxy_location: typing.Optional[ProxyLocation] = OMIT, + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = OMIT, proxy_session_id: typing.Optional[str] = OMIT, rotate_proxy_session_id: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -6975,14 +7747,14 @@ class AsyncRawSkyvern: vault_type : typing.Optional[CredentialVaultType] Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. - proxy_location : typing.Optional[ProxyLocation] + proxy_location : typing.Optional[CreateCredentialRequestProxyLocation] Optional proxy location for this credential's pinned proxy identity. proxy_session_id : typing.Optional[str] Optional advanced reuse key for this credential's pinned proxy identity. rotate_proxy_session_id : typing.Optional[bool] - Rotate the Skyvern-managed proxy sticky-session id for this credential. + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -7002,7 +7774,9 @@ class AsyncRawSkyvern: object_=credential, annotation=CreateCredentialRequestCredential, direction="write" ), "vault_type": vault_type, - "proxy_location": proxy_location, + "proxy_location": convert_and_respect_annotation_metadata( + object_=proxy_location, annotation=CreateCredentialRequestProxyLocation, direction="write" + ), "proxy_session_id": proxy_session_id, "rotate_proxy_session_id": rotate_proxy_session_id, }, @@ -7763,3 +8537,774 @@ class AsyncRawSkyvern: except JSONDecodeError: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def update_workflow_folder( + self, + workflow_permanent_id: str, + *, + folder_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Workflow]: + """ + Update a workflow's folder assignment for the latest version + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + folder_id : typing.Optional[str] + Folder ID to assign workflow to. Set to null to remove from folder. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Workflow] + Successfully updated workflow folder + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/folder", + method="PUT", + json={ + "folder_id": folder_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Workflow, + parse_obj_as( + type_=Workflow, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_workflow_tags( + self, workflow_permanent_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[TagsResponse]: + """ + Get the current tag state for a workflow. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TagsResponse] + Successfully retrieved tags + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/tags", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagsResponse, + parse_obj_as( + type_=TagsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def apply_workflow_tags( + self, + workflow_permanent_id: str, + *, + tags: typing.Optional[typing.Sequence[TagInput]] = OMIT, + tags_to_delete: typing.Optional[typing.Sequence[TagDeleteInput]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TagsResponse]: + """ + Atomically apply tag changes to a workflow. Sets and deletes happen in one transaction; same-key collisions resolve set-wins. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + tags : typing.Optional[typing.Sequence[TagInput]] + Tags to set (overwrite). List of {key?, value} objects. + + tags_to_delete : typing.Optional[typing.Sequence[TagDeleteInput]] + Tags to soft-delete. List of {key?, value?} targets. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TagsResponse] + Successfully applied tag changes + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/tags", + method="POST", + json={ + "tags": convert_and_respect_annotation_metadata( + object_=tags, annotation=typing.Sequence[TagInput], direction="write" + ), + "tags_to_delete": convert_and_respect_annotation_metadata( + object_=tags_to_delete, annotation=typing.Sequence[TagDeleteInput], direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagsResponse, + parse_obj_as( + type_=TagsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_workflow_tag( + self, workflow_permanent_id: str, key: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[TagsResponse]: + """ + Soft-delete a single tag from a workflow. Writes a DELETE event row. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + key : str + Tag key to delete + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TagsResponse] + Successfully deleted tag (or no-op if absent) + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/tags/{jsonable_encoder(key)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagsResponse, + parse_obj_as( + type_=TagsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_workflow_tag_history( + self, + workflow_permanent_id: str, + *, + limit: typing.Optional[int] = None, + since: typing.Optional[dt.datetime] = None, + key: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[TagHistoryResponse]: + """ + Chronological tag-event log for a workflow (newest first). Includes SET and DELETE events. + + Parameters + ---------- + workflow_permanent_id : str + Workflow permanent ID + + limit : typing.Optional[int] + Max events to return + + since : typing.Optional[dt.datetime] + Only return events at or after this timestamp + + key : typing.Optional[str] + Filter to events for a single tag key + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TagHistoryResponse] + Successfully retrieved tag history + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/tags/history", + method="GET", + params={ + "limit": limit, + "since": serialize_datetime(since) if since is not None else None, + "key": key, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TagHistoryResponse, + parse_obj_as( + type_=TagHistoryResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def retry_workflow_run( + self, + workflow_run_id: str, + *, + max_steps_override: typing.Optional[int] = None, + user_agent: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[WorkflowRunResponse]: + """ + Retry a workflow run using the original run parameters. + + Parameters + ---------- + workflow_run_id : str + The id of the workflow run to retry. + + max_steps_override : typing.Optional[int] + + user_agent : typing.Optional[str] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[WorkflowRunResponse] + Successfully retried workflow run + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/runs/{jsonable_encoder(workflow_run_id)}/retry", + method="POST", + headers={ + "x-max-steps-override": str(max_steps_override) if max_steps_override is not None else None, + "x-user-agent": str(user_agent) if user_agent is not None else None, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + WorkflowRunResponse, + parse_obj_as( + type_=WorkflowRunResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_workflow_runs( + self, + *, + page: typing.Optional[int] = None, + page_size: typing.Optional[int] = None, + status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, + search_key: typing.Optional[str] = None, + error_code: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[typing.List[WorkflowRun]]: + """ + List workflow runs across all workflows for the current organization. + + Results are paginated and can be filtered by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic — a run must match every supplied filter to be returned. + + ### search_key + + A case-insensitive substring search that matches against **any** of the following fields: + + | Searched field | Description | + |---|---| + | `workflow_run_id` | The unique run identifier (e.g. `wr_123…`) | + | Parameter **key** | The `key` of any workflow parameter definition associated with the run | + | Parameter **description** | The `description` of any workflow parameter definition | + | Run parameter **value** | The actual value supplied for any parameter when the run was created | + | `extra_http_headers` | Extra HTTP headers attached to the run (searched as raw JSON text) | + + Soft-deleted parameter definitions are excluded from key/description matching. A run is returned if **any** of the fields above contain the search term. + + ### error_code + + An **exact-match** filter against the `error_code` field inside each task's `errors` JSON array. A run matches if **any** of its tasks contains an error object with a matching `error_code` value. Error codes are user-defined strings set during workflow execution (e.g. `INVALID_CREDENTIALS`, `LOGIN_FAILED`, `CAPTCHA_DETECTED`). + + ### Combining filters + + All query parameters use AND logic: + - `?status=failed` — only failed runs + - `?status=failed&error_code=LOGIN_FAILED` — failed runs **and** have a LOGIN_FAILED error + - `?status=failed&error_code=LOGIN_FAILED&search_key=prod_credential` — all three conditions must match + + Parameters + ---------- + page : typing.Optional[int] + Page number for pagination. + + page_size : typing.Optional[int] + Number of runs to return per page. + + status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] + Filter by one or more run statuses. + + search_key : typing.Optional[str] + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. + + error_code : typing.Optional[str] + Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.List[WorkflowRun]] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/agents/runs", + method="GET", + params={ + "page": page, + "page_size": page_size, + "status": status, + "search_key": search_key, + "error_code": error_code, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[WorkflowRun], + parse_obj_as( + type_=typing.List[WorkflowRun], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_workflow_runs_by_id( + self, + workflow_id: str, + *, + page: typing.Optional[int] = None, + page_size: typing.Optional[int] = None, + status: typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] = None, + search_key: typing.Optional[str] = None, + error_code: typing.Optional[str] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[typing.List[WorkflowRun]]: + """ + List runs for a specific workflow. + + Supports filtering by **status**, **search_key**, and **error_code**. All filters are combined with **AND** logic. + + ### search_key + + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. Soft-deleted parameter definitions are excluded. + + ### error_code + + Exact-match filter on the `error_code` field inside each task's `errors` JSON array. A run matches if any of its tasks contains an error with a matching `error_code`. + + Parameters + ---------- + workflow_id : str + + page : typing.Optional[int] + Page number for pagination. + + page_size : typing.Optional[int] + Number of runs to return per page. + + status : typing.Optional[typing.Union[WorkflowRunStatus, typing.Sequence[WorkflowRunStatus]]] + Filter by one or more run statuses. + + search_key : typing.Optional[str] + Case-insensitive substring search across: workflow run ID, parameter key, parameter description, run parameter value, and extra HTTP headers. A run is returned if any of these fields match. Soft-deleted parameter definitions are excluded from key/description matching. + + error_code : typing.Optional[str] + Exact-match filter on the error_code field inside each task's errors JSON array. A run matches if any of its tasks contains an error with a matching error_code. Error codes are user-defined strings set during workflow execution. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.List[WorkflowRun]] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_id)}/runs", + method="GET", + params={ + "page": page, + "page_size": page_size, + "status": status, + "search_key": search_key, + "error_code": error_code, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[WorkflowRun], + parse_obj_as( + type_=typing.List[WorkflowRun], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_workflow( + self, + workflow_permanent_id: str, + *, + version: typing.Optional[int] = None, + template: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Workflow]: + """ + Parameters + ---------- + workflow_permanent_id : str + + version : typing.Optional[int] + + template : typing.Optional[bool] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Workflow] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}", + method="GET", + params={ + "version": version, + "template": template, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Workflow, + parse_obj_as( + type_=Workflow, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_workflow_versions( + self, + workflow_permanent_id: str, + *, + template: typing.Optional[bool] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[typing.List[Workflow]]: + """ + Get all versions of a workflow by its permanent ID. + + Parameters + ---------- + workflow_permanent_id : str + + template : typing.Optional[bool] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.List[Workflow]] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/versions", + method="GET", + params={ + "template": template, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[Workflow], + parse_obj_as( + type_=typing.List[Workflow], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/skyvern/client/schedules/raw_client.py b/skyvern/client/schedules/raw_client.py index cf9ebfb29..f350a85b5 100644 --- a/skyvern/client/schedules/raw_client.py +++ b/skyvern/client/schedules/raw_client.py @@ -108,7 +108,7 @@ class RawSchedulesClient: Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules", method="GET", request_options=request_options, ) @@ -176,7 +176,7 @@ class RawSchedulesClient: Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules", method="POST", json={ "cron_expression": cron_expression, @@ -241,7 +241,7 @@ class RawSchedulesClient: Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", method="GET", request_options=request_options, ) @@ -312,7 +312,7 @@ class RawSchedulesClient: Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", method="PUT", json={ "cron_expression": cron_expression, @@ -377,7 +377,7 @@ class RawSchedulesClient: Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", method="DELETE", request_options=request_options, ) @@ -430,7 +430,7 @@ class RawSchedulesClient: Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}/enable", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}/enable", method="POST", request_options=request_options, ) @@ -483,7 +483,7 @@ class RawSchedulesClient: Successful Response """ _response = self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}/disable", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}/disable", method="POST", request_options=request_options, ) @@ -602,7 +602,7 @@ class AsyncRawSchedulesClient: Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules", method="GET", request_options=request_options, ) @@ -670,7 +670,7 @@ class AsyncRawSchedulesClient: Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules", method="POST", json={ "cron_expression": cron_expression, @@ -735,7 +735,7 @@ class AsyncRawSchedulesClient: Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", method="GET", request_options=request_options, ) @@ -806,7 +806,7 @@ class AsyncRawSchedulesClient: Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", method="PUT", json={ "cron_expression": cron_expression, @@ -871,7 +871,7 @@ class AsyncRawSchedulesClient: Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}", method="DELETE", request_options=request_options, ) @@ -924,7 +924,7 @@ class AsyncRawSchedulesClient: Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}/enable", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}/enable", method="POST", request_options=request_options, ) @@ -977,7 +977,7 @@ class AsyncRawSchedulesClient: Successful Response """ _response = await self._client_wrapper.httpx_client.request( - f"v1/workflows/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}/disable", + f"v1/agents/{jsonable_encoder(workflow_permanent_id)}/schedules/{jsonable_encoder(workflow_schedule_id)}/disable", method="POST", request_options=request_options, ) diff --git a/skyvern/client/server/client.py b/skyvern/client/server/client.py deleted file mode 100644 index 35ccce241..000000000 --- a/skyvern/client/server/client.py +++ /dev/null @@ -1,99 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper -from ..core.request_options import RequestOptions -from .raw_client import AsyncRawServerClient, RawServerClient - - -class ServerClient: - def __init__(self, *, client_wrapper: SyncClientWrapper): - self._raw_client = RawServerClient(client_wrapper=client_wrapper) - - @property - def with_raw_response(self) -> RawServerClient: - """ - Retrieves a raw implementation of this client that returns raw responses. - - Returns - ------- - RawServerClient - """ - return self._raw_client - - def get_version(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.Dict[str, str]: - """ - Returns the current Skyvern server version (git SHA for official builds). - - Parameters - ---------- - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - typing.Dict[str, str] - Current server version - - Examples - -------- - from skyvern import Skyvern - - client = Skyvern( - api_key="YOUR_API_KEY", - ) - client.server.get_version() - """ - _response = self._raw_client.get_version(request_options=request_options) - return _response.data - - -class AsyncServerClient: - def __init__(self, *, client_wrapper: AsyncClientWrapper): - self._raw_client = AsyncRawServerClient(client_wrapper=client_wrapper) - - @property - def with_raw_response(self) -> AsyncRawServerClient: - """ - Retrieves a raw implementation of this client that returns raw responses. - - Returns - ------- - AsyncRawServerClient - """ - return self._raw_client - - async def get_version(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.Dict[str, str]: - """ - Returns the current Skyvern server version (git SHA for official builds). - - Parameters - ---------- - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - typing.Dict[str, str] - Current server version - - Examples - -------- - import asyncio - - from skyvern import AsyncSkyvern - - client = AsyncSkyvern( - api_key="YOUR_API_KEY", - ) - - - async def main() -> None: - await client.server.get_version() - - - asyncio.run(main()) - """ - _response = await self._raw_client.get_version(request_options=request_options) - return _response.data diff --git a/skyvern/client/server/raw_client.py b/skyvern/client/server/raw_client.py deleted file mode 100644 index 333e6a5ca..000000000 --- a/skyvern/client/server/raw_client.py +++ /dev/null @@ -1,92 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing -from json.decoder import JSONDecodeError - -from ..core.api_error import ApiError -from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper -from ..core.http_response import AsyncHttpResponse, HttpResponse -from ..core.pydantic_utilities import parse_obj_as -from ..core.request_options import RequestOptions - - -class RawServerClient: - def __init__(self, *, client_wrapper: SyncClientWrapper): - self._client_wrapper = client_wrapper - - def get_version( - self, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[typing.Dict[str, str]]: - """ - Returns the current Skyvern server version (git SHA for official builds). - - Parameters - ---------- - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - HttpResponse[typing.Dict[str, str]] - Current server version - """ - _response = self._client_wrapper.httpx_client.request( - "v1/version", - method="GET", - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - typing.Dict[str, str], - parse_obj_as( - type_=typing.Dict[str, str], # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - - -class AsyncRawServerClient: - def __init__(self, *, client_wrapper: AsyncClientWrapper): - self._client_wrapper = client_wrapper - - async def get_version( - self, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[typing.Dict[str, str]]: - """ - Returns the current Skyvern server version (git SHA for official builds). - - Parameters - ---------- - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - AsyncHttpResponse[typing.Dict[str, str]] - Current server version - """ - _response = await self._client_wrapper.httpx_client.request( - "v1/version", - method="GET", - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - typing.Dict[str, str], - parse_obj_as( - type_=typing.Dict[str, str], # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/skyvern/client/types/__init__.py b/skyvern/client/types/__init__.py index 2a7111109..ae34a4694 100644 --- a/skyvern/client/types/__init__.py +++ b/skyvern/client/types/__init__.py @@ -29,6 +29,7 @@ if typing.TYPE_CHECKING: from .action_output import ActionOutput from .action_status import ActionStatus from .action_type import ActionType + from .ai_fallback_mode import AiFallbackMode from .artifact import Artifact from .artifact_type import ArtifactType from .aws_secret_parameter import AwsSecretParameter @@ -53,6 +54,7 @@ if typing.TYPE_CHECKING: from .branch_criteria_yaml import BranchCriteriaYaml from .branch_criteria_yaml_criteria_type import BranchCriteriaYamlCriteriaType from .browser_profile import BrowserProfile + from .browser_profile_proxy_location import BrowserProfileProxyLocation from .browser_session_response import BrowserSessionResponse from .bulk_cancel_runs_response import BulkCancelRunsResponse from .click_action import ClickAction @@ -93,9 +95,11 @@ if typing.TYPE_CHECKING: ) from .context_parameter_value import ContextParameterValue from .context_parameter_yaml import ContextParameterYaml + from .create_browser_profile_request_proxy_location import CreateBrowserProfileRequestProxyLocation from .create_browser_session_request_proxy_location import CreateBrowserSessionRequestProxyLocation from .create_credential_request import CreateCredentialRequest from .create_credential_request_credential import CreateCredentialRequestCredential + from .create_credential_request_proxy_location import CreateCredentialRequestProxyLocation from .create_script_response import CreateScriptResponse from .credential_parameter import CredentialParameter from .credential_parameter_yaml import CredentialParameterYaml @@ -414,6 +418,15 @@ if typing.TYPE_CHECKING: from .send_email_block_yaml import SendEmailBlockYaml from .skyvern_forge_sdk_schemas_credentials_credential_type import SkyvernForgeSdkSchemasCredentialsCredentialType from .skyvern_schemas_credential_type_credential_type import SkyvernSchemasCredentialTypeCredentialType + from .tag_delete_input import TagDeleteInput + from .tag_history_item import TagHistoryItem + from .tag_history_response import TagHistoryResponse + from .tag_input import TagInput + from .tag_item import TagItem + from .tag_key import TagKey + from .tag_key_delete_response import TagKeyDeleteResponse + from .tag_response import TagResponse + from .tags_response import TagsResponse from .task_block import TaskBlock from .task_block_data_schema import TaskBlockDataSchema from .task_block_parameters_item import ( @@ -463,6 +476,7 @@ if typing.TYPE_CHECKING: from .thought_type import ThoughtType from .totp_code import TotpCode from .totp_type import TotpType + from .update_browser_profile_request_proxy_location import UpdateBrowserProfileRequestProxyLocation from .upload_file_action import UploadFileAction from .upload_file_action_data import UploadFileActionData from .upload_file_response import UploadFileResponse @@ -708,6 +722,7 @@ if typing.TYPE_CHECKING: from .workflow_schedule_response import WorkflowScheduleResponse from .workflow_schedule_upsert_request import WorkflowScheduleUpsertRequest from .workflow_status import WorkflowStatus + from .workflow_tags_batch_response import WorkflowTagsBatchResponse from .workflow_trigger_block import WorkflowTriggerBlock from .workflow_trigger_block_parameters_item import ( WorkflowTriggerBlockParametersItem, @@ -746,6 +761,7 @@ _dynamic_imports: typing.Dict[str, str] = { "ActionOutput": ".action_output", "ActionStatus": ".action_status", "ActionType": ".action_type", + "AiFallbackMode": ".ai_fallback_mode", "Artifact": ".artifact", "ArtifactType": ".artifact_type", "AwsSecretParameter": ".aws_secret_parameter", @@ -768,6 +784,7 @@ _dynamic_imports: typing.Dict[str, str] = { "BranchCriteriaYaml": ".branch_criteria_yaml", "BranchCriteriaYamlCriteriaType": ".branch_criteria_yaml_criteria_type", "BrowserProfile": ".browser_profile", + "BrowserProfileProxyLocation": ".browser_profile_proxy_location", "BrowserSessionResponse": ".browser_session_response", "BulkCancelRunsResponse": ".bulk_cancel_runs_response", "ClickAction": ".click_action", @@ -804,9 +821,11 @@ _dynamic_imports: typing.Dict[str, str] = { "ContextParameterSource_Workflow": ".context_parameter_source", "ContextParameterValue": ".context_parameter_value", "ContextParameterYaml": ".context_parameter_yaml", + "CreateBrowserProfileRequestProxyLocation": ".create_browser_profile_request_proxy_location", "CreateBrowserSessionRequestProxyLocation": ".create_browser_session_request_proxy_location", "CreateCredentialRequest": ".create_credential_request", "CreateCredentialRequestCredential": ".create_credential_request_credential", + "CreateCredentialRequestProxyLocation": ".create_credential_request_proxy_location", "CreateScriptResponse": ".create_script_response", "CredentialParameter": ".credential_parameter", "CredentialParameterYaml": ".credential_parameter_yaml", @@ -1097,6 +1116,15 @@ _dynamic_imports: typing.Dict[str, str] = { "SendEmailBlockYaml": ".send_email_block_yaml", "SkyvernForgeSdkSchemasCredentialsCredentialType": ".skyvern_forge_sdk_schemas_credentials_credential_type", "SkyvernSchemasCredentialTypeCredentialType": ".skyvern_schemas_credential_type_credential_type", + "TagDeleteInput": ".tag_delete_input", + "TagHistoryItem": ".tag_history_item", + "TagHistoryResponse": ".tag_history_response", + "TagInput": ".tag_input", + "TagItem": ".tag_item", + "TagKey": ".tag_key", + "TagKeyDeleteResponse": ".tag_key_delete_response", + "TagResponse": ".tag_response", + "TagsResponse": ".tags_response", "TaskBlock": ".task_block", "TaskBlockDataSchema": ".task_block_data_schema", "TaskBlockParametersItem": ".task_block_parameters_item", @@ -1142,6 +1170,7 @@ _dynamic_imports: typing.Dict[str, str] = { "ThoughtType": ".thought_type", "TotpCode": ".totp_code", "TotpType": ".totp_type", + "UpdateBrowserProfileRequestProxyLocation": ".update_browser_profile_request_proxy_location", "UploadFileAction": ".upload_file_action", "UploadFileActionData": ".upload_file_action_data", "UploadFileResponse": ".upload_file_response", @@ -1367,6 +1396,7 @@ _dynamic_imports: typing.Dict[str, str] = { "WorkflowScheduleResponse": ".workflow_schedule_response", "WorkflowScheduleUpsertRequest": ".workflow_schedule_upsert_request", "WorkflowStatus": ".workflow_status", + "WorkflowTagsBatchResponse": ".workflow_tags_batch_response", "WorkflowTriggerBlock": ".workflow_trigger_block", "WorkflowTriggerBlockParametersItem": ".workflow_trigger_block_parameters_item", "WorkflowTriggerBlockParametersItem_AwsSecret": ".workflow_trigger_block_parameters_item", @@ -1427,6 +1457,7 @@ __all__ = [ "ActionOutput", "ActionStatus", "ActionType", + "AiFallbackMode", "Artifact", "ArtifactType", "AwsSecretParameter", @@ -1449,6 +1480,7 @@ __all__ = [ "BranchCriteriaYaml", "BranchCriteriaYamlCriteriaType", "BrowserProfile", + "BrowserProfileProxyLocation", "BrowserSessionResponse", "BulkCancelRunsResponse", "ClickAction", @@ -1485,9 +1517,11 @@ __all__ = [ "ContextParameterSource_Workflow", "ContextParameterValue", "ContextParameterYaml", + "CreateBrowserProfileRequestProxyLocation", "CreateBrowserSessionRequestProxyLocation", "CreateCredentialRequest", "CreateCredentialRequestCredential", + "CreateCredentialRequestProxyLocation", "CreateScriptResponse", "CredentialParameter", "CredentialParameterYaml", @@ -1778,6 +1812,15 @@ __all__ = [ "SendEmailBlockYaml", "SkyvernForgeSdkSchemasCredentialsCredentialType", "SkyvernSchemasCredentialTypeCredentialType", + "TagDeleteInput", + "TagHistoryItem", + "TagHistoryResponse", + "TagInput", + "TagItem", + "TagKey", + "TagKeyDeleteResponse", + "TagResponse", + "TagsResponse", "TaskBlock", "TaskBlockDataSchema", "TaskBlockParametersItem", @@ -1823,6 +1866,7 @@ __all__ = [ "ThoughtType", "TotpCode", "TotpType", + "UpdateBrowserProfileRequestProxyLocation", "UploadFileAction", "UploadFileActionData", "UploadFileResponse", @@ -2048,6 +2092,7 @@ __all__ = [ "WorkflowScheduleResponse", "WorkflowScheduleUpsertRequest", "WorkflowStatus", + "WorkflowTagsBatchResponse", "WorkflowTriggerBlock", "WorkflowTriggerBlockParametersItem", "WorkflowTriggerBlockParametersItem_AwsSecret", diff --git a/skyvern/client/types/action_block.py b/skyvern/client/types/action_block.py index aa9b30d0a..f4b098b29 100644 --- a/skyvern/client/types/action_block.py +++ b/skyvern/client/types/action_block.py @@ -8,6 +8,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from .action_block_data_schema import ActionBlockDataSchema from .action_block_parameters_item import ActionBlockParametersItem +from .ai_fallback_mode import AiFallbackMode from .output_parameter import OutputParameter from .run_engine import RunEngine @@ -50,6 +51,8 @@ class ActionBlock(UniversalBaseModel): include_action_history_in_verification: typing.Optional[bool] = None download_timeout: typing.Optional[float] = None include_extracted_text: typing.Optional[bool] = None + selector: typing.Optional[str] = None + ai_fallback: typing.Optional[AiFallbackMode] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/action_block_yaml.py b/skyvern/client/types/action_block_yaml.py index dd3abd85c..89fd2d23e 100644 --- a/skyvern/client/types/action_block_yaml.py +++ b/skyvern/client/types/action_block_yaml.py @@ -4,6 +4,7 @@ import typing import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .ai_fallback_mode import AiFallbackMode from .run_engine import RunEngine @@ -26,6 +27,8 @@ class ActionBlockYaml(UniversalBaseModel): title: typing.Optional[str] = None engine: typing.Optional[RunEngine] = None navigation_goal: typing.Optional[str] = None + selector: typing.Optional[str] = None + ai_fallback: typing.Optional[AiFallbackMode] = None error_code_mapping: typing.Optional[typing.Dict[str, typing.Optional[str]]] = None max_retries: typing.Optional[int] = None parameter_keys: typing.Optional[typing.List[str]] = None diff --git a/skyvern/client/types/action_type.py b/skyvern/client/types/action_type.py index 7fe706d12..ccbac8537 100644 --- a/skyvern/client/types/action_type.py +++ b/skyvern/client/types/action_type.py @@ -18,6 +18,8 @@ ActionType = typing.Union[ "complete", "reload_page", "close_page", + "new_tab", + "switch_tab", "extract", "verification_code", "goto_url", diff --git a/skyvern/client/types/ai_fallback_mode.py b/skyvern/client/types/ai_fallback_mode.py new file mode 100644 index 000000000..4a6634f7e --- /dev/null +++ b/skyvern/client/types/ai_fallback_mode.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +AiFallbackMode = typing.Union[typing.Literal["fallback", "proactive"], typing.Any] diff --git a/skyvern/client/types/artifact_type.py b/skyvern/client/types/artifact_type.py index c9e599864..915a30ed9 100644 --- a/skyvern/client/types/artifact_type.py +++ b/skyvern/client/types/artifact_type.py @@ -5,6 +5,8 @@ import typing ArtifactType = typing.Union[ typing.Literal[ "recording", + "audio", + "session_replay", "browser_console_log", "skyvern_log", "skyvern_log_raw", diff --git a/skyvern/client/types/browser_profile.py b/skyvern/client/types/browser_profile.py index f3547fa82..eff6f0e2a 100644 --- a/skyvern/client/types/browser_profile.py +++ b/skyvern/client/types/browser_profile.py @@ -5,7 +5,7 @@ import typing import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .proxy_location import ProxyLocation +from .browser_profile_proxy_location import BrowserProfileProxyLocation class BrowserProfile(UniversalBaseModel): @@ -14,8 +14,11 @@ class BrowserProfile(UniversalBaseModel): name: str description: typing.Optional[str] = None source_browser_type: typing.Optional[str] = None - proxy_location: typing.Optional[ProxyLocation] = None + proxy_location: typing.Optional[BrowserProfileProxyLocation] = None proxy_session_id: typing.Optional[str] = None + is_managed: typing.Optional[bool] = None + workflow_permanent_id: typing.Optional[str] = None + browser_profile_key_digest: typing.Optional[str] = None created_at: dt.datetime modified_at: dt.datetime deleted_at: typing.Optional[dt.datetime] = None diff --git a/skyvern/client/types/browser_profile_proxy_location.py b/skyvern/client/types/browser_profile_proxy_location.py new file mode 100644 index 000000000..b81a2d89b --- /dev/null +++ b/skyvern/client/types/browser_profile_proxy_location.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .geo_target import GeoTarget +from .proxy_location import ProxyLocation + +BrowserProfileProxyLocation = typing.Union[ProxyLocation, GeoTarget, typing.Dict[str, typing.Optional[typing.Any]]] diff --git a/skyvern/client/types/browser_session_response.py b/skyvern/client/types/browser_session_response.py index e8b12c533..75cf9c6c2 100644 --- a/skyvern/client/types/browser_session_response.py +++ b/skyvern/client/types/browser_session_response.py @@ -70,6 +70,11 @@ class BrowserSessionResponse(UniversalBaseModel): ID of the browser profile loaded into this session, if any. browser_profile_id starts with `bp_`. """ + generate_browser_profile: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether this session's browser profile will be saved when it ends so it can become a reusable browser profile. + """ + vnc_streaming_supported: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the browser session supports VNC streaming diff --git a/skyvern/client/types/create_browser_profile_request_proxy_location.py b/skyvern/client/types/create_browser_profile_request_proxy_location.py new file mode 100644 index 000000000..f070ab4cb --- /dev/null +++ b/skyvern/client/types/create_browser_profile_request_proxy_location.py @@ -0,0 +1,10 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .geo_target import GeoTarget +from .proxy_location import ProxyLocation + +CreateBrowserProfileRequestProxyLocation = typing.Union[ + ProxyLocation, GeoTarget, typing.Dict[str, typing.Optional[typing.Any]] +] diff --git a/skyvern/client/types/create_credential_request.py b/skyvern/client/types/create_credential_request.py index e3f3355fb..4cd292770 100644 --- a/skyvern/client/types/create_credential_request.py +++ b/skyvern/client/types/create_credential_request.py @@ -5,6 +5,7 @@ import typing import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from .create_credential_request_credential import CreateCredentialRequestCredential +from .create_credential_request_proxy_location import CreateCredentialRequestProxyLocation from .credential_vault_type import CredentialVaultType from .skyvern_forge_sdk_schemas_credentials_credential_type import SkyvernForgeSdkSchemasCredentialsCredentialType @@ -34,6 +35,21 @@ class CreateCredentialRequest(UniversalBaseModel): Which vault to store this credential in. If omitted, uses the instance default. Use this to mix Skyvern-hosted and custom credentials within the same organization. """ + proxy_location: typing.Optional[CreateCredentialRequestProxyLocation] = pydantic.Field(default=None) + """ + Optional proxy location for this credential's pinned proxy identity. + """ + + proxy_session_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional advanced reuse key for this credential's pinned proxy identity. + """ + + rotate_proxy_session_id: typing.Optional[bool] = pydantic.Field(default=None) + """ + Rotate the Skyvern-managed proxy sticky-session id when updating this credential. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/skyvern/client/types/create_credential_request_proxy_location.py b/skyvern/client/types/create_credential_request_proxy_location.py new file mode 100644 index 000000000..88c0fcca7 --- /dev/null +++ b/skyvern/client/types/create_credential_request_proxy_location.py @@ -0,0 +1,10 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .geo_target import GeoTarget +from .proxy_location import ProxyLocation + +CreateCredentialRequestProxyLocation = typing.Union[ + ProxyLocation, GeoTarget, typing.Dict[str, typing.Optional[typing.Any]] +] diff --git a/skyvern/client/types/credential_parameter.py b/skyvern/client/types/credential_parameter.py index e06bb2d75..6d4705bdf 100644 --- a/skyvern/client/types/credential_parameter.py +++ b/skyvern/client/types/credential_parameter.py @@ -13,8 +13,6 @@ class CredentialParameter(UniversalBaseModel): credential_parameter_id: str workflow_id: str credential_id: str - credential_ids: typing.Optional[typing.List[str]] = None - selection_strategy: typing.Optional[str] = None created_at: dt.datetime modified_at: dt.datetime deleted_at: typing.Optional[dt.datetime] = None diff --git a/skyvern/client/types/credential_parameter_yaml.py b/skyvern/client/types/credential_parameter_yaml.py index bc5ca5ecf..aa8a22e10 100644 --- a/skyvern/client/types/credential_parameter_yaml.py +++ b/skyvern/client/types/credential_parameter_yaml.py @@ -10,8 +10,6 @@ class CredentialParameterYaml(UniversalBaseModel): key: str description: typing.Optional[str] = None credential_id: str - credential_ids: typing.Optional[typing.List[str]] = None - selection_strategy: typing.Optional[str] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/credential_response.py b/skyvern/client/types/credential_response.py index 1294c7663..ceeb22370 100644 --- a/skyvern/client/types/credential_response.py +++ b/skyvern/client/types/credential_response.py @@ -7,7 +7,6 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from .credential_response_credential import CredentialResponseCredential from .credential_type_output import CredentialTypeOutput from .credential_vault_type import CredentialVaultType -from .proxy_location import ProxyLocation class CredentialResponse(UniversalBaseModel): @@ -45,16 +44,6 @@ class CredentialResponse(UniversalBaseModel): Browser profile ID linked to this credential """ - proxy_location: typing.Optional[ProxyLocation] = pydantic.Field(default=None) - """ - Optional proxy location for this credential's pinned proxy identity. - """ - - proxy_session_id: typing.Optional[str] = pydantic.Field(default=None) - """ - Optional advanced reuse key for this credential's pinned proxy identity. - """ - tested_url: typing.Optional[str] = pydantic.Field(default=None) """ Login page URL used during the credential test @@ -70,6 +59,11 @@ class CredentialResponse(UniversalBaseModel): Whether the user intends to save a browser session, regardless of test outcome """ + folder_id: typing.Optional[str] = pydantic.Field(default=None) + """ + ID of the credential folder this credential belongs to, if any + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/skyvern/client/types/file_type.py b/skyvern/client/types/file_type.py index 6575b7e3a..619ce5455 100644 --- a/skyvern/client/types/file_type.py +++ b/skyvern/client/types/file_type.py @@ -2,4 +2,4 @@ import typing -FileType = typing.Union[typing.Literal["auto_detect", "csv", "excel", "pdf", "image", "docx", "zip"], typing.Any] +FileType = typing.Union[typing.Literal["auto_detect", "csv", "excel", "pdf", "image", "docx"], typing.Any] diff --git a/skyvern/client/types/for_loop_block.py b/skyvern/client/types/for_loop_block.py index c0a2300b1..926ba5ef0 100644 --- a/skyvern/client/types/for_loop_block.py +++ b/skyvern/client/types/for_loop_block.py @@ -47,9 +47,9 @@ class ForLoopBlock(UniversalBaseModel): from .context_parameter import ContextParameter # noqa: E402, F401, I001 # Manual patch: Fern v4.31.1 emits bottom-cross-imports that deadlock at module -# load (for_loop ↔ while_loop ↔ *_loop_blocks_item). Catch the mid-load +# load (for_loop <-> while_loop <-> *_loop_blocks_item). Catch the mid-load # ImportError; the symmetric *_loop_blocks_item module back-resolves once both -# unions are fully defined. Reapply on every regen — see fern_build_python_sdk.sh. +# unions are fully defined. Reapplied on every regen by scripts/patch_generated_client.py. try: from .while_loop_block import WhileLoopBlock # noqa: E402, F401, I001 from .for_loop_block_loop_blocks_item import ForLoopBlockLoopBlocksItem # noqa: E402, F401, I001 diff --git a/skyvern/client/types/for_loop_block_loop_blocks_item.py b/skyvern/client/types/for_loop_block_loop_blocks_item.py index a015755c9..ff67f4bda 100644 --- a/skyvern/client/types/for_loop_block_loop_blocks_item.py +++ b/skyvern/client/types/for_loop_block_loop_blocks_item.py @@ -10,6 +10,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update from ..core.serialization import FieldMetadata from .action_block_data_schema import ActionBlockDataSchema from .action_block_parameters_item import ActionBlockParametersItem +from .ai_fallback_mode import AiFallbackMode from .aws_secret_parameter import AwsSecretParameter from .branch_condition import BranchCondition from .code_block_parameters_item import CodeBlockParametersItem @@ -77,6 +78,8 @@ class ForLoopBlockLoopBlocksItem_Action(UniversalBaseModel): include_action_history_in_verification: typing.Optional[bool] = None download_timeout: typing.Optional[float] = None include_extracted_text: typing.Optional[bool] = None + selector: typing.Optional[str] = None + ai_fallback: typing.Optional[AiFallbackMode] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -532,6 +535,7 @@ class ForLoopBlockLoopBlocksItem_Login(UniversalBaseModel): include_action_history_in_verification: typing.Optional[bool] = None download_timeout: typing.Optional[float] = None include_extracted_text: typing.Optional[bool] = None + skip_saved_profile: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -931,65 +935,24 @@ ForLoopBlockLoopBlocksItem = typing.Union[ ForLoopBlockLoopBlocksItem_WhileLoop, ForLoopBlockLoopBlocksItem_WorkflowTrigger, ] -# Manual patch: see for_loop_block.py header note. The cross-import below fails -# when this module is loaded mid-chain via while_loop_block_loop_blocks_item. -# The other side back-resolves us once it finishes loading. -try: - from .while_loop_block_loop_blocks_item import WhileLoopBlockLoopBlocksItem # noqa: E402, F401, I001 -except ImportError: - pass -else: - for _cls in ( - ForLoopBlockLoopBlocksItem_Action, - ForLoopBlockLoopBlocksItem_Code, - ForLoopBlockLoopBlocksItem_Extraction, - ForLoopBlockLoopBlocksItem_FileDownload, - ForLoopBlockLoopBlocksItem_ForLoop, - ForLoopBlockLoopBlocksItem_GoogleSheetsRead, - ForLoopBlockLoopBlocksItem_GoogleSheetsWrite, - ForLoopBlockLoopBlocksItem_GotoUrl, - ForLoopBlockLoopBlocksItem_HttpRequest, - ForLoopBlockLoopBlocksItem_HumanInteraction, - ForLoopBlockLoopBlocksItem_Login, - ForLoopBlockLoopBlocksItem_Navigation, - ForLoopBlockLoopBlocksItem_PrintPage, - ForLoopBlockLoopBlocksItem_Task, - ForLoopBlockLoopBlocksItem_TextPrompt, - ForLoopBlockLoopBlocksItem_Validation, - ForLoopBlockLoopBlocksItem_Wait, - ForLoopBlockLoopBlocksItem_WhileLoop, - ForLoopBlockLoopBlocksItem_WorkflowTrigger, - ): - update_forward_refs(_cls) - from . import while_loop_block_loop_blocks_item as _wllb - _wllb.ForLoopBlockLoopBlocksItem = ForLoopBlockLoopBlocksItem # type: ignore[attr-defined] - for _cls in ( - _wllb.WhileLoopBlockLoopBlocksItem_Action, - _wllb.WhileLoopBlockLoopBlocksItem_Code, - _wllb.WhileLoopBlockLoopBlocksItem_Extraction, - _wllb.WhileLoopBlockLoopBlocksItem_FileDownload, - _wllb.WhileLoopBlockLoopBlocksItem_ForLoop, - _wllb.WhileLoopBlockLoopBlocksItem_GoogleSheetsRead, - _wllb.WhileLoopBlockLoopBlocksItem_GoogleSheetsWrite, - _wllb.WhileLoopBlockLoopBlocksItem_GotoUrl, - _wllb.WhileLoopBlockLoopBlocksItem_HttpRequest, - _wllb.WhileLoopBlockLoopBlocksItem_HumanInteraction, - _wllb.WhileLoopBlockLoopBlocksItem_Login, - _wllb.WhileLoopBlockLoopBlocksItem_Navigation, - _wllb.WhileLoopBlockLoopBlocksItem_PrintPage, - _wllb.WhileLoopBlockLoopBlocksItem_Task, - _wllb.WhileLoopBlockLoopBlocksItem_TextPrompt, - _wllb.WhileLoopBlockLoopBlocksItem_Validation, - _wllb.WhileLoopBlockLoopBlocksItem_Wait, - _wllb.WhileLoopBlockLoopBlocksItem_WhileLoop, - _wllb.WhileLoopBlockLoopBlocksItem_WorkflowTrigger, - ): - update_forward_refs(_cls) - from . import for_loop_block as _flb - _flb.ForLoopBlockLoopBlocksItem = ForLoopBlockLoopBlocksItem # type: ignore[attr-defined] - _flb.WhileLoopBlockLoopBlocksItem = WhileLoopBlockLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_flb.ForLoopBlock) - from . import while_loop_block as _wlb - _wlb.ForLoopBlockLoopBlocksItem = ForLoopBlockLoopBlocksItem # type: ignore[attr-defined] - _wlb.WhileLoopBlockLoopBlocksItem = WhileLoopBlockLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_wlb.WhileLoopBlock) +from .while_loop_block_loop_blocks_item import WhileLoopBlockLoopBlocksItem # noqa: E402, F401, I001 + +update_forward_refs(ForLoopBlockLoopBlocksItem_Action) +update_forward_refs(ForLoopBlockLoopBlocksItem_Code) +update_forward_refs(ForLoopBlockLoopBlocksItem_Extraction) +update_forward_refs(ForLoopBlockLoopBlocksItem_FileDownload) +update_forward_refs(ForLoopBlockLoopBlocksItem_ForLoop) +update_forward_refs(ForLoopBlockLoopBlocksItem_GoogleSheetsRead) +update_forward_refs(ForLoopBlockLoopBlocksItem_GoogleSheetsWrite) +update_forward_refs(ForLoopBlockLoopBlocksItem_GotoUrl) +update_forward_refs(ForLoopBlockLoopBlocksItem_HttpRequest) +update_forward_refs(ForLoopBlockLoopBlocksItem_HumanInteraction) +update_forward_refs(ForLoopBlockLoopBlocksItem_Login) +update_forward_refs(ForLoopBlockLoopBlocksItem_Navigation) +update_forward_refs(ForLoopBlockLoopBlocksItem_PrintPage) +update_forward_refs(ForLoopBlockLoopBlocksItem_Task) +update_forward_refs(ForLoopBlockLoopBlocksItem_TextPrompt) +update_forward_refs(ForLoopBlockLoopBlocksItem_Validation) +update_forward_refs(ForLoopBlockLoopBlocksItem_Wait) +update_forward_refs(ForLoopBlockLoopBlocksItem_WhileLoop) +update_forward_refs(ForLoopBlockLoopBlocksItem_WorkflowTrigger) diff --git a/skyvern/client/types/for_loop_block_yaml.py b/skyvern/client/types/for_loop_block_yaml.py index 4cf687393..733fc8b9c 100644 --- a/skyvern/client/types/for_loop_block_yaml.py +++ b/skyvern/client/types/for_loop_block_yaml.py @@ -40,6 +40,7 @@ class ForLoopBlockYaml(UniversalBaseModel): extra = pydantic.Extra.allow + # Manual patch: Fern v4.31.1 emits bottom-cross-imports that deadlock at module # load. See for_loop_block.py for the explanation. try: diff --git a/skyvern/client/types/for_loop_block_yaml_loop_blocks_item.py b/skyvern/client/types/for_loop_block_yaml_loop_blocks_item.py index 8b5e6e4c7..428623ff4 100644 --- a/skyvern/client/types/for_loop_block_yaml_loop_blocks_item.py +++ b/skyvern/client/types/for_loop_block_yaml_loop_blocks_item.py @@ -8,6 +8,7 @@ import pydantic import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from ..core.serialization import FieldMetadata +from .ai_fallback_mode import AiFallbackMode from .branch_condition_yaml import BranchConditionYaml from .branch_criteria_yaml import BranchCriteriaYaml from .extraction_block_yaml_data_schema import ExtractionBlockYamlDataSchema @@ -308,6 +309,8 @@ class ForLoopBlockYamlLoopBlocksItem_Action(UniversalBaseModel): title: typing.Optional[str] = None engine: typing.Optional[RunEngine] = None navigation_goal: typing.Optional[str] = None + selector: typing.Optional[str] = None + ai_fallback: typing.Optional[AiFallbackMode] = None error_code_mapping: typing.Optional[typing.Dict[str, typing.Optional[str]]] = None max_retries: typing.Optional[int] = None parameter_keys: typing.Optional[typing.List[str]] = None @@ -413,6 +416,7 @@ class ForLoopBlockYamlLoopBlocksItem_Login(UniversalBaseModel): complete_criterion: typing.Optional[str] = None terminate_criterion: typing.Optional[str] = None complete_verification: typing.Optional[bool] = None + skip_saved_profile: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -751,23 +755,7 @@ ForLoopBlockYamlLoopBlocksItem = typing.Union[ ForLoopBlockYamlLoopBlocksItem_GoogleSheetsRead, ForLoopBlockYamlLoopBlocksItem_GoogleSheetsWrite, ] -# Manual patch: see for_loop_block.py header note. -try: - from .while_loop_block_yaml_loop_blocks_item import WhileLoopBlockYamlLoopBlocksItem # noqa: E402, F401, I001 -except ImportError: - pass -else: - update_forward_refs(ForLoopBlockYamlLoopBlocksItem_ForLoop) - update_forward_refs(ForLoopBlockYamlLoopBlocksItem_WhileLoop) - from . import while_loop_block_yaml_loop_blocks_item as _wlylb - _wlylb.ForLoopBlockYamlLoopBlocksItem = ForLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_wlylb.WhileLoopBlockYamlLoopBlocksItem_ForLoop) - update_forward_refs(_wlylb.WhileLoopBlockYamlLoopBlocksItem_WhileLoop) - from . import for_loop_block_yaml as _flby - _flby.ForLoopBlockYamlLoopBlocksItem = ForLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - _flby.WhileLoopBlockYamlLoopBlocksItem = WhileLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_flby.ForLoopBlockYaml) - from . import while_loop_block_yaml as _wlby - _wlby.ForLoopBlockYamlLoopBlocksItem = ForLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - _wlby.WhileLoopBlockYamlLoopBlocksItem = WhileLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_wlby.WhileLoopBlockYaml) +from .while_loop_block_yaml_loop_blocks_item import WhileLoopBlockYamlLoopBlocksItem # noqa: E402, F401, I001 + +update_forward_refs(ForLoopBlockYamlLoopBlocksItem_ForLoop) +update_forward_refs(ForLoopBlockYamlLoopBlocksItem_WhileLoop) diff --git a/skyvern/client/types/login_block.py b/skyvern/client/types/login_block.py index 3675e1928..698f6aec1 100644 --- a/skyvern/client/types/login_block.py +++ b/skyvern/client/types/login_block.py @@ -50,6 +50,7 @@ class LoginBlock(UniversalBaseModel): include_action_history_in_verification: typing.Optional[bool] = None download_timeout: typing.Optional[float] = None include_extracted_text: typing.Optional[bool] = None + skip_saved_profile: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/login_block_yaml.py b/skyvern/client/types/login_block_yaml.py index b64f4e033..f1630285c 100644 --- a/skyvern/client/types/login_block_yaml.py +++ b/skyvern/client/types/login_block_yaml.py @@ -36,6 +36,7 @@ class LoginBlockYaml(UniversalBaseModel): complete_criterion: typing.Optional[str] = None terminate_criterion: typing.Optional[str] = None complete_verification: typing.Optional[bool] = None + skip_saved_profile: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/non_empty_credit_card_credential.py b/skyvern/client/types/non_empty_credit_card_credential.py index f27f35046..6f8ee4c95 100644 --- a/skyvern/client/types/non_empty_credit_card_credential.py +++ b/skyvern/client/types/non_empty_credit_card_credential.py @@ -41,26 +41,6 @@ class NonEmptyCreditCardCredential(UniversalBaseModel): The name of the card holder (must not be empty) """ - billing_address: typing.Optional[typing.Dict[str, typing.Optional[str]]] = pydantic.Field(default=None) - """ - Optional billing address associated with the card - """ - - billing_email: typing.Optional[str] = pydantic.Field(default=None) - """ - Optional billing email address - """ - - billing_phone: typing.Optional[str] = pydantic.Field(default=None) - """ - Optional billing phone number - """ - - metadata: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) - """ - Optional additional credit card metadata fields - """ - if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/skyvern/client/types/tag_delete_input.py b/skyvern/client/types/tag_delete_input.py new file mode 100644 index 000000000..3b264679f --- /dev/null +++ b/skyvern/client/types/tag_delete_input.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TagDeleteInput(UniversalBaseModel): + """ + One tag to soft-delete: a grouped tag by its ``key``, or a standalone label + by its ``value`` (omit the key). + """ + + key: typing.Optional[str] = pydantic.Field(default=None) + """ + Group (key) to delete. Use for grouped tags. + """ + + value: typing.Optional[str] = pydantic.Field(default=None) + """ + Label (value) to delete. Use for standalone labels. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/tag_history_item.py b/skyvern/client/types/tag_history_item.py new file mode 100644 index 000000000..202b69630 --- /dev/null +++ b/skyvern/client/types/tag_history_item.py @@ -0,0 +1,31 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TagHistoryItem(UniversalBaseModel): + """ + One row from ``GET /v1/workflows/{wpid}/tags/history``. + """ + + tag_event_id: str + key: typing.Optional[str] = None + value: typing.Optional[str] = None + event_type: str + source: str + set_at: dt.datetime + set_by: str + superseded_at: typing.Optional[dt.datetime] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/tag_history_response.py b/skyvern/client/types/tag_history_response.py new file mode 100644 index 000000000..233d5d958 --- /dev/null +++ b/skyvern/client/types/tag_history_response.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .tag_history_item import TagHistoryItem + + +class TagHistoryResponse(UniversalBaseModel): + workflow_permanent_id: str + events: typing.List[TagHistoryItem] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/tag_input.py b/skyvern/client/types/tag_input.py new file mode 100644 index 000000000..50e315608 --- /dev/null +++ b/skyvern/client/types/tag_input.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TagInput(UniversalBaseModel): + """ + One tag to set. ``value`` is the required label; ``key`` is the optional + group — null for a standalone label, set for a grouped label (e.g. env:prod). + """ + + key: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional group (key). Omit for a standalone label. + """ + + value: str = pydantic.Field() + """ + Label (value). Always required. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/tag_item.py b/skyvern/client/types/tag_item.py new file mode 100644 index 000000000..9168657ac --- /dev/null +++ b/skyvern/client/types/tag_item.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TagItem(UniversalBaseModel): + """ + A single tag (key + label) without per-tag attribution. ``key`` is null + for a standalone label. + """ + + key: typing.Optional[str] = None + value: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/tag_key.py b/skyvern/client/types/tag_key.py new file mode 100644 index 000000000..7ceeaf299 --- /dev/null +++ b/skyvern/client/types/tag_key.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TagKey(UniversalBaseModel): + """ + Tag-key registry entry. + """ + + key: str + description: typing.Optional[str] = None + workflow_count: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/tag_key_delete_response.py b/skyvern/client/types/tag_key_delete_response.py new file mode 100644 index 000000000..92717e45b --- /dev/null +++ b/skyvern/client/types/tag_key_delete_response.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TagKeyDeleteResponse(UniversalBaseModel): + """ + Response for ``DELETE /v1/tag-keys/{key}``. + """ + + key: str + removed_from_workflow_count: int + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/tag_response.py b/skyvern/client/types/tag_response.py new file mode 100644 index 000000000..6212fa24f --- /dev/null +++ b/skyvern/client/types/tag_response.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TagResponse(UniversalBaseModel): + """ + Current state of one tag (``GET /v1/workflows/{wpid}/tags`` row). + ``key`` is null for a standalone label. + """ + + key: typing.Optional[str] = None + value: str + source: str + set_at: dt.datetime + set_by: str + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/tags_response.py b/skyvern/client/types/tags_response.py new file mode 100644 index 000000000..46eb0d51d --- /dev/null +++ b/skyvern/client/types/tags_response.py @@ -0,0 +1,26 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .tag_response import TagResponse + + +class TagsResponse(UniversalBaseModel): + """ + Current tags for a workflow. A list (not a key-map) so standalone labels, + which have no key, are representable. + """ + + workflow_permanent_id: str + tags: typing.List[TagResponse] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/types/update_browser_profile_request_proxy_location.py b/skyvern/client/types/update_browser_profile_request_proxy_location.py new file mode 100644 index 000000000..ef74c2994 --- /dev/null +++ b/skyvern/client/types/update_browser_profile_request_proxy_location.py @@ -0,0 +1,10 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .geo_target import GeoTarget +from .proxy_location import ProxyLocation + +UpdateBrowserProfileRequestProxyLocation = typing.Union[ + ProxyLocation, GeoTarget, typing.Dict[str, typing.Optional[typing.Any]] +] diff --git a/skyvern/client/types/while_loop_block_loop_blocks_item.py b/skyvern/client/types/while_loop_block_loop_blocks_item.py index 3511fde23..af7560111 100644 --- a/skyvern/client/types/while_loop_block_loop_blocks_item.py +++ b/skyvern/client/types/while_loop_block_loop_blocks_item.py @@ -10,6 +10,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update from ..core.serialization import FieldMetadata from .action_block_data_schema import ActionBlockDataSchema from .action_block_parameters_item import ActionBlockParametersItem +from .ai_fallback_mode import AiFallbackMode from .aws_secret_parameter import AwsSecretParameter from .branch_condition import BranchCondition from .code_block_parameters_item import CodeBlockParametersItem @@ -77,6 +78,8 @@ class WhileLoopBlockLoopBlocksItem_Action(UniversalBaseModel): include_action_history_in_verification: typing.Optional[bool] = None download_timeout: typing.Optional[float] = None include_extracted_text: typing.Optional[bool] = None + selector: typing.Optional[str] = None + ai_fallback: typing.Optional[AiFallbackMode] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -532,6 +535,7 @@ class WhileLoopBlockLoopBlocksItem_Login(UniversalBaseModel): include_action_history_in_verification: typing.Optional[bool] = None download_timeout: typing.Optional[float] = None include_extracted_text: typing.Optional[bool] = None + skip_saved_profile: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -931,63 +935,24 @@ WhileLoopBlockLoopBlocksItem = typing.Union[ WhileLoopBlockLoopBlocksItem_WhileLoop, WhileLoopBlockLoopBlocksItem_WorkflowTrigger, ] -# Manual patch: see for_loop_block.py header note. -try: - from .for_loop_block_loop_blocks_item import ForLoopBlockLoopBlocksItem # noqa: E402, F401, I001 -except ImportError: - pass -else: - for _cls in ( - WhileLoopBlockLoopBlocksItem_Action, - WhileLoopBlockLoopBlocksItem_Code, - WhileLoopBlockLoopBlocksItem_Extraction, - WhileLoopBlockLoopBlocksItem_FileDownload, - WhileLoopBlockLoopBlocksItem_ForLoop, - WhileLoopBlockLoopBlocksItem_GoogleSheetsRead, - WhileLoopBlockLoopBlocksItem_GoogleSheetsWrite, - WhileLoopBlockLoopBlocksItem_GotoUrl, - WhileLoopBlockLoopBlocksItem_HttpRequest, - WhileLoopBlockLoopBlocksItem_HumanInteraction, - WhileLoopBlockLoopBlocksItem_Login, - WhileLoopBlockLoopBlocksItem_Navigation, - WhileLoopBlockLoopBlocksItem_PrintPage, - WhileLoopBlockLoopBlocksItem_Task, - WhileLoopBlockLoopBlocksItem_TextPrompt, - WhileLoopBlockLoopBlocksItem_Validation, - WhileLoopBlockLoopBlocksItem_Wait, - WhileLoopBlockLoopBlocksItem_WhileLoop, - WhileLoopBlockLoopBlocksItem_WorkflowTrigger, - ): - update_forward_refs(_cls) - from . import for_loop_block_loop_blocks_item as _fllb - _fllb.WhileLoopBlockLoopBlocksItem = WhileLoopBlockLoopBlocksItem # type: ignore[attr-defined] - for _cls in ( - _fllb.ForLoopBlockLoopBlocksItem_Action, - _fllb.ForLoopBlockLoopBlocksItem_Code, - _fllb.ForLoopBlockLoopBlocksItem_Extraction, - _fllb.ForLoopBlockLoopBlocksItem_FileDownload, - _fllb.ForLoopBlockLoopBlocksItem_ForLoop, - _fllb.ForLoopBlockLoopBlocksItem_GoogleSheetsRead, - _fllb.ForLoopBlockLoopBlocksItem_GoogleSheetsWrite, - _fllb.ForLoopBlockLoopBlocksItem_GotoUrl, - _fllb.ForLoopBlockLoopBlocksItem_HttpRequest, - _fllb.ForLoopBlockLoopBlocksItem_HumanInteraction, - _fllb.ForLoopBlockLoopBlocksItem_Login, - _fllb.ForLoopBlockLoopBlocksItem_Navigation, - _fllb.ForLoopBlockLoopBlocksItem_PrintPage, - _fllb.ForLoopBlockLoopBlocksItem_Task, - _fllb.ForLoopBlockLoopBlocksItem_TextPrompt, - _fllb.ForLoopBlockLoopBlocksItem_Validation, - _fllb.ForLoopBlockLoopBlocksItem_Wait, - _fllb.ForLoopBlockLoopBlocksItem_WhileLoop, - _fllb.ForLoopBlockLoopBlocksItem_WorkflowTrigger, - ): - update_forward_refs(_cls) - from . import for_loop_block as _flb - _flb.ForLoopBlockLoopBlocksItem = ForLoopBlockLoopBlocksItem # type: ignore[attr-defined] - _flb.WhileLoopBlockLoopBlocksItem = WhileLoopBlockLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_flb.ForLoopBlock) - from . import while_loop_block as _wlb - _wlb.ForLoopBlockLoopBlocksItem = ForLoopBlockLoopBlocksItem # type: ignore[attr-defined] - _wlb.WhileLoopBlockLoopBlocksItem = WhileLoopBlockLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_wlb.WhileLoopBlock) +from .for_loop_block_loop_blocks_item import ForLoopBlockLoopBlocksItem # noqa: E402, F401, I001 + +update_forward_refs(WhileLoopBlockLoopBlocksItem_Action) +update_forward_refs(WhileLoopBlockLoopBlocksItem_Code) +update_forward_refs(WhileLoopBlockLoopBlocksItem_Extraction) +update_forward_refs(WhileLoopBlockLoopBlocksItem_FileDownload) +update_forward_refs(WhileLoopBlockLoopBlocksItem_ForLoop) +update_forward_refs(WhileLoopBlockLoopBlocksItem_GoogleSheetsRead) +update_forward_refs(WhileLoopBlockLoopBlocksItem_GoogleSheetsWrite) +update_forward_refs(WhileLoopBlockLoopBlocksItem_GotoUrl) +update_forward_refs(WhileLoopBlockLoopBlocksItem_HttpRequest) +update_forward_refs(WhileLoopBlockLoopBlocksItem_HumanInteraction) +update_forward_refs(WhileLoopBlockLoopBlocksItem_Login) +update_forward_refs(WhileLoopBlockLoopBlocksItem_Navigation) +update_forward_refs(WhileLoopBlockLoopBlocksItem_PrintPage) +update_forward_refs(WhileLoopBlockLoopBlocksItem_Task) +update_forward_refs(WhileLoopBlockLoopBlocksItem_TextPrompt) +update_forward_refs(WhileLoopBlockLoopBlocksItem_Validation) +update_forward_refs(WhileLoopBlockLoopBlocksItem_Wait) +update_forward_refs(WhileLoopBlockLoopBlocksItem_WhileLoop) +update_forward_refs(WhileLoopBlockLoopBlocksItem_WorkflowTrigger) diff --git a/skyvern/client/types/while_loop_block_yaml.py b/skyvern/client/types/while_loop_block_yaml.py index a58e8eeab..4c06d824d 100644 --- a/skyvern/client/types/while_loop_block_yaml.py +++ b/skyvern/client/types/while_loop_block_yaml.py @@ -37,6 +37,7 @@ class WhileLoopBlockYaml(UniversalBaseModel): extra = pydantic.Extra.allow + # Manual patch: Fern v4.31.1 emits bottom-cross-imports that deadlock at module # load. See for_loop_block.py for the explanation. try: diff --git a/skyvern/client/types/while_loop_block_yaml_loop_blocks_item.py b/skyvern/client/types/while_loop_block_yaml_loop_blocks_item.py index a08a387f9..19604a1fc 100644 --- a/skyvern/client/types/while_loop_block_yaml_loop_blocks_item.py +++ b/skyvern/client/types/while_loop_block_yaml_loop_blocks_item.py @@ -8,6 +8,7 @@ import pydantic import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from ..core.serialization import FieldMetadata +from .ai_fallback_mode import AiFallbackMode from .branch_condition_yaml import BranchConditionYaml from .branch_criteria_yaml import BranchCriteriaYaml from .extraction_block_yaml_data_schema import ExtractionBlockYamlDataSchema @@ -308,6 +309,8 @@ class WhileLoopBlockYamlLoopBlocksItem_Action(UniversalBaseModel): title: typing.Optional[str] = None engine: typing.Optional[RunEngine] = None navigation_goal: typing.Optional[str] = None + selector: typing.Optional[str] = None + ai_fallback: typing.Optional[AiFallbackMode] = None error_code_mapping: typing.Optional[typing.Dict[str, typing.Optional[str]]] = None max_retries: typing.Optional[int] = None parameter_keys: typing.Optional[typing.List[str]] = None @@ -413,6 +416,7 @@ class WhileLoopBlockYamlLoopBlocksItem_Login(UniversalBaseModel): complete_criterion: typing.Optional[str] = None terminate_criterion: typing.Optional[str] = None complete_verification: typing.Optional[bool] = None + skip_saved_profile: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -751,23 +755,7 @@ WhileLoopBlockYamlLoopBlocksItem = typing.Union[ WhileLoopBlockYamlLoopBlocksItem_GoogleSheetsRead, WhileLoopBlockYamlLoopBlocksItem_GoogleSheetsWrite, ] -# Manual patch: see for_loop_block.py header note. -try: - from .for_loop_block_yaml_loop_blocks_item import ForLoopBlockYamlLoopBlocksItem # noqa: E402, F401, I001 -except ImportError: - pass -else: - update_forward_refs(WhileLoopBlockYamlLoopBlocksItem_ForLoop) - update_forward_refs(WhileLoopBlockYamlLoopBlocksItem_WhileLoop) - from . import for_loop_block_yaml_loop_blocks_item as _flylb - _flylb.WhileLoopBlockYamlLoopBlocksItem = WhileLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_flylb.ForLoopBlockYamlLoopBlocksItem_ForLoop) - update_forward_refs(_flylb.ForLoopBlockYamlLoopBlocksItem_WhileLoop) - from . import for_loop_block_yaml as _flby - _flby.ForLoopBlockYamlLoopBlocksItem = ForLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - _flby.WhileLoopBlockYamlLoopBlocksItem = WhileLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_flby.ForLoopBlockYaml) - from . import while_loop_block_yaml as _wlby - _wlby.ForLoopBlockYamlLoopBlocksItem = ForLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - _wlby.WhileLoopBlockYamlLoopBlocksItem = WhileLoopBlockYamlLoopBlocksItem # type: ignore[attr-defined] - update_forward_refs(_wlby.WhileLoopBlockYaml) +from .for_loop_block_yaml_loop_blocks_item import ForLoopBlockYamlLoopBlocksItem # noqa: E402, F401, I001 + +update_forward_refs(WhileLoopBlockYamlLoopBlocksItem_ForLoop) +update_forward_refs(WhileLoopBlockYamlLoopBlocksItem_WhileLoop) diff --git a/skyvern/client/types/workflow.py b/skyvern/client/types/workflow.py index b335adac1..607fbc0bc 100644 --- a/skyvern/client/types/workflow.py +++ b/skyvern/client/types/workflow.py @@ -29,7 +29,6 @@ class Workflow(UniversalBaseModel): persist_browser_session: typing.Optional[bool] = None pin_saved_session_ip: typing.Optional[bool] = None browser_profile_id: typing.Optional[str] = None - browser_profile_key: typing.Optional[str] = None model: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = None status: typing.Optional[WorkflowStatus] = None max_screenshot_scrolls: typing.Optional[int] = None @@ -51,6 +50,10 @@ class Workflow(UniversalBaseModel): created_at: dt.datetime modified_at: dt.datetime deleted_at: typing.Optional[dt.datetime] = None + agent_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Alias of `workflow_permanent_id` — the stable agent identifier (starts with `wpid_`). + """ if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/workflow_create_yaml_request.py b/skyvern/client/types/workflow_create_yaml_request.py index ef46b7f46..91c2cba64 100644 --- a/skyvern/client/types/workflow_create_yaml_request.py +++ b/skyvern/client/types/workflow_create_yaml_request.py @@ -21,7 +21,6 @@ class WorkflowCreateYamlRequest(UniversalBaseModel): persist_browser_session: typing.Optional[bool] = None pin_saved_session_ip: typing.Optional[bool] = None browser_profile_id: typing.Optional[str] = None - browser_profile_key: typing.Optional[str] = None model: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = None workflow_definition: WorkflowDefinitionYaml is_saved_task: typing.Optional[bool] = None diff --git a/skyvern/client/types/workflow_definition_blocks_item.py b/skyvern/client/types/workflow_definition_blocks_item.py index aaea9ae50..795384696 100644 --- a/skyvern/client/types/workflow_definition_blocks_item.py +++ b/skyvern/client/types/workflow_definition_blocks_item.py @@ -10,6 +10,7 @@ from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update from ..core.serialization import FieldMetadata from .action_block_data_schema import ActionBlockDataSchema from .action_block_parameters_item import ActionBlockParametersItem +from .ai_fallback_mode import AiFallbackMode from .aws_secret_parameter import AwsSecretParameter from .branch_condition import BranchCondition from .code_block_parameters_item import CodeBlockParametersItem @@ -77,6 +78,8 @@ class WorkflowDefinitionBlocksItem_Action(UniversalBaseModel): include_action_history_in_verification: typing.Optional[bool] = None download_timeout: typing.Optional[float] = None include_extracted_text: typing.Optional[bool] = None + selector: typing.Optional[str] = None + ai_fallback: typing.Optional[AiFallbackMode] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -535,6 +538,7 @@ class WorkflowDefinitionBlocksItem_Login(UniversalBaseModel): include_action_history_in_verification: typing.Optional[bool] = None download_timeout: typing.Optional[float] = None include_extracted_text: typing.Optional[bool] = None + skip_saved_profile: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/workflow_definition_parameters_item.py b/skyvern/client/types/workflow_definition_parameters_item.py index 527152aca..a2cf40f66 100644 --- a/skyvern/client/types/workflow_definition_parameters_item.py +++ b/skyvern/client/types/workflow_definition_parameters_item.py @@ -183,8 +183,6 @@ class WorkflowDefinitionParametersItem_Credential(UniversalBaseModel): credential_parameter_id: str workflow_id: str credential_id: str - credential_ids: typing.Optional[typing.List[str]] = None - selection_strategy: typing.Optional[str] = None created_at: dt.datetime modified_at: dt.datetime deleted_at: typing.Optional[dt.datetime] = None diff --git a/skyvern/client/types/workflow_definition_yaml_blocks_item.py b/skyvern/client/types/workflow_definition_yaml_blocks_item.py index 8ec99f78f..19a3b6065 100644 --- a/skyvern/client/types/workflow_definition_yaml_blocks_item.py +++ b/skyvern/client/types/workflow_definition_yaml_blocks_item.py @@ -8,6 +8,7 @@ import pydantic import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel, update_forward_refs from ..core.serialization import FieldMetadata +from .ai_fallback_mode import AiFallbackMode from .branch_condition_yaml import BranchConditionYaml from .branch_criteria_yaml import BranchCriteriaYaml from .extraction_block_yaml_data_schema import ExtractionBlockYamlDataSchema @@ -32,6 +33,8 @@ class WorkflowDefinitionYamlBlocksItem_Action(UniversalBaseModel): title: typing.Optional[str] = None engine: typing.Optional[RunEngine] = None navigation_goal: typing.Optional[str] = None + selector: typing.Optional[str] = None + ai_fallback: typing.Optional[AiFallbackMode] = None error_code_mapping: typing.Optional[typing.Dict[str, typing.Optional[str]]] = None max_retries: typing.Optional[int] = None parameter_keys: typing.Optional[typing.List[str]] = None @@ -403,6 +406,7 @@ class WorkflowDefinitionYamlBlocksItem_Login(UniversalBaseModel): complete_criterion: typing.Optional[str] = None terminate_criterion: typing.Optional[str] = None complete_verification: typing.Optional[bool] = None + skip_saved_profile: typing.Optional[bool] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/workflow_definition_yaml_parameters_item.py b/skyvern/client/types/workflow_definition_yaml_parameters_item.py index 2363b0275..35603ba6d 100644 --- a/skyvern/client/types/workflow_definition_yaml_parameters_item.py +++ b/skyvern/client/types/workflow_definition_yaml_parameters_item.py @@ -128,8 +128,6 @@ class WorkflowDefinitionYamlParametersItem_Credential(UniversalBaseModel): key: str description: typing.Optional[str] = None credential_id: str - credential_ids: typing.Optional[typing.List[str]] = None - selection_strategy: typing.Optional[str] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/skyvern/client/types/workflow_run_request_output.py b/skyvern/client/types/workflow_run_request_output.py index cf48778f8..c483230d7 100644 --- a/skyvern/client/types/workflow_run_request_output.py +++ b/skyvern/client/types/workflow_run_request_output.py @@ -10,7 +10,7 @@ from .workflow_run_request_output_proxy_location import WorkflowRunRequestOutput class WorkflowRunRequestOutput(UniversalBaseModel): workflow_id: str = pydantic.Field() """ - ID of the workflow to run. Workflow ID starts with `wpid_`. + ID of the agent to run. Starts with `wpid_`. `workflow_id` is accepted as an alias. """ parameters: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) diff --git a/skyvern/client/types/workflow_tags_batch_response.py b/skyvern/client/types/workflow_tags_batch_response.py new file mode 100644 index 000000000..4303e3c32 --- /dev/null +++ b/skyvern/client/types/workflow_tags_batch_response.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .tag_item import TagItem + + +class WorkflowTagsBatchResponse(UniversalBaseModel): + """ + Response for the batch endpoint. + + Workflows with no tags are present with an empty list so the frontend can + distinguish "fetched, none set" from "not fetched" without a second call. + Workflows outside the caller's org are silently absent (no leakage). + """ + + workflow_tags: typing.Dict[str, typing.List[TagItem]] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/skyvern/client/workflows/__init__.py b/skyvern/client/workflows/__init__.py deleted file mode 100644 index 5cde0202d..000000000 --- a/skyvern/client/workflows/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -# isort: skip_file - diff --git a/skyvern/library/skyvern.py b/skyvern/library/skyvern.py index d7680c6d4..757e6cf39 100644 --- a/skyvern/library/skyvern.py +++ b/skyvern/library/skyvern.py @@ -374,7 +374,7 @@ class Skyvern(AsyncSkyvern): request_options: RequestOptions | None = None, ) -> WorkflowRunResponse: workflow_run = await super().run_workflow( - workflow_id=workflow_id, + agent_id=workflow_id, parameters=parameters, template=template, title=title, diff --git a/tests/unit/test_sdk_run_metadata.py b/tests/unit/test_sdk_run_metadata.py index 5fb1517db..260a353ad 100644 --- a/tests/unit/test_sdk_run_metadata.py +++ b/tests/unit/test_sdk_run_metadata.py @@ -68,14 +68,14 @@ def test_run_workflow_sends_run_metadata() -> None: ) response = client.run_workflow( - workflow_id="wpid_123", + agent_id="wpid_123", run_metadata={"customer": "acme", "tier": "enterprise"}, ) assert response.run_id == "wr_123" assert captured_bodies == [ { - "workflow_id": "wpid_123", + "agent_id": "wpid_123", "run_metadata": {"customer": "acme", "tier": "enterprise"}, } ] @@ -103,14 +103,14 @@ def test_run_workflow_sends_max_elapsed_time() -> None: ) response = client.run_workflow( - workflow_id="wpid_123", + agent_id="wpid_123", max_elapsed_time_minutes=10, ) assert response.run_id == "wr_123" assert captured_bodies == [ { - "workflow_id": "wpid_123", + "agent_id": "wpid_123", "max_elapsed_time_minutes": 10, } ] @@ -160,7 +160,7 @@ def test_retry_workflow_run_uses_retry_route() -> None: assert response.run_id == "wr_retry" assert captured_requests[0].method == "POST" - assert captured_requests[0].url.path == "/v1/workflows/runs/wr_original/retry" + assert captured_requests[0].url.path == "/v1/agents/runs/wr_original/retry" assert captured_requests[0].headers["x-max-steps-override"] == "12" assert captured_requests[0].headers["x-user-agent"] == "skyvern-ui" @@ -187,7 +187,7 @@ async def test_async_retry_workflow_run_uses_retry_route() -> None: assert response.run_id == "wr_retry" assert captured_requests[0].method == "POST" - assert captured_requests[0].url.path == "/v1/workflows/runs/wr_original/retry" + assert captured_requests[0].url.path == "/v1/agents/runs/wr_original/retry" assert captured_requests[0].headers["x-max-steps-override"] == "8" assert captured_requests[0].headers["x-user-agent"] == "skyvern-ui" @@ -216,7 +216,7 @@ def test_get_workflow_runs_by_id_uses_workflow_scoped_route() -> None: assert runs[0].workflow_run_id == "wr_123" assert captured_requests[0].method == "GET" - assert captured_requests[0].url.path == "/v1/workflows/wpid_123/runs" + assert captured_requests[0].url.path == "/v1/agents/wpid_123/runs" assert captured_requests[0].url.params["page"] == "1" assert captured_requests[0].url.params["page_size"] == "10" assert captured_requests[0].url.params["status"] == "completed" @@ -249,7 +249,7 @@ async def test_async_get_workflow_runs_by_id_uses_workflow_scoped_route() -> Non assert runs[0].workflow_run_id == "wr_123" assert captured_requests[0].method == "GET" - assert captured_requests[0].url.path == "/v1/workflows/wpid_123/runs" + assert captured_requests[0].url.path == "/v1/agents/wpid_123/runs" assert captured_requests[0].url.params["page"] == "2" assert captured_requests[0].url.params["page_size"] == "5" assert captured_requests[0].url.params["status"] == "failed" diff --git a/uv.lock b/uv.lock index dbd231316..0da7bc3b4 100644 --- a/uv.lock +++ b/uv.lock @@ -5776,7 +5776,7 @@ wheels = [ [[package]] name = "skyvern" -version = "1.0.44" +version = "1.0.45" source = { editable = "." } dependencies = [ { name = "cachetools" },