From e3cd3eeae0f7d2d6db790cf950520dd208493dbc Mon Sep 17 00:00:00 2001 From: Stanislav Novosad Date: Mon, 10 Nov 2025 13:51:53 -0700 Subject: [PATCH] Publish npm package using Trusted Publisher (#3953) --- .github/workflows/ts-sdk-release.yml | 15 +- fern/generators.yml | 5 + skyvern-ts/client/package-lock.json | 241 +++++---- skyvern-ts/client/package.json | 9 +- skyvern-ts/client/reference.md | 243 +++++++++ skyvern-ts/client/src/Client.ts | 27 +- .../client/requests/CreateWorkflowRequest.ts | 16 + .../client/src/api/client/requests/index.ts | 1 + .../browserProfiles/client/Client.ts | 343 ++++++++++++ .../resources/browserProfiles/client/index.ts | 1 + .../requests/CreateBrowserProfileRequest.ts | 18 + ...wserProfilesV1BrowserProfilesGetRequest.ts | 12 + .../browserProfiles/client/requests/index.ts | 2 + .../api/resources/browserProfiles/index.ts | 1 + skyvern-ts/client/src/api/resources/index.ts | 2 + .../client/src/api/types/BrowserProfile.ts | 11 + .../src/api/types/InputOrSelectContext.ts | 1 + .../api/types/RunSdkActionRequestAction.ts | 5 + .../client/src/api/types/TaskRunResponse.ts | 2 + .../client/src/api/types/UploadFileAction.ts | 24 + .../api/types/WorkflowCreateYamlRequest.ts | 1 + .../src/api/types/WorkflowRunRequest.ts | 2 + .../src/api/types/WorkflowRunResponse.ts | 2 + skyvern-ts/client/src/api/types/index.ts | 2 + .../client/tests/wire/browserProfiles.test.ts | 236 ++++++++ skyvern-ts/client/tests/wire/main.test.ts | 21 +- skyvern/client/__init__.py | 7 +- skyvern/client/browser_profiles/__init__.py | 4 + skyvern/client/browser_profiles/client.py | 379 +++++++++++++ skyvern/client/browser_profiles/raw_client.py | 507 ++++++++++++++++++ skyvern/client/client.py | 55 +- skyvern/client/raw_client.py | 24 + skyvern/client/types/__init__.py | 3 + skyvern/client/types/browser_profile.py | 26 + skyvern/client/types/get_run_response.py | 6 + .../client/types/input_or_select_context.py | 1 + .../types/run_sdk_action_response_result.py | 7 - skyvern/client/types/sdk_action.py | 129 ----- skyvern/client/types/task_run_response.py | 5 + .../types/workflow_create_yaml_request.py | 1 + skyvern/client/types/workflow_run_request.py | 5 + skyvern/client/types/workflow_run_response.py | 5 + skyvern/library/skyvern_browser_page_ai.py | 26 +- 43 files changed, 2143 insertions(+), 290 deletions(-) create mode 100644 skyvern-ts/client/src/api/client/requests/CreateWorkflowRequest.ts create mode 100644 skyvern-ts/client/src/api/resources/browserProfiles/client/Client.ts create mode 100644 skyvern-ts/client/src/api/resources/browserProfiles/client/index.ts create mode 100644 skyvern-ts/client/src/api/resources/browserProfiles/client/requests/CreateBrowserProfileRequest.ts create mode 100644 skyvern-ts/client/src/api/resources/browserProfiles/client/requests/ListBrowserProfilesV1BrowserProfilesGetRequest.ts create mode 100644 skyvern-ts/client/src/api/resources/browserProfiles/client/requests/index.ts create mode 100644 skyvern-ts/client/src/api/resources/browserProfiles/index.ts create mode 100644 skyvern-ts/client/src/api/types/BrowserProfile.ts create mode 100644 skyvern-ts/client/src/api/types/UploadFileAction.ts create mode 100644 skyvern-ts/client/tests/wire/browserProfiles.test.ts create mode 100644 skyvern/client/browser_profiles/__init__.py create mode 100644 skyvern/client/browser_profiles/client.py create mode 100644 skyvern/client/browser_profiles/raw_client.py create mode 100644 skyvern/client/types/browser_profile.py delete mode 100644 skyvern/client/types/run_sdk_action_response_result.py delete mode 100644 skyvern/client/types/sdk_action.py diff --git a/.github/workflows/ts-sdk-release.yml b/.github/workflows/ts-sdk-release.yml index 064e8d6a..600c3bdb 100644 --- a/.github/workflows/ts-sdk-release.yml +++ b/.github/workflows/ts-sdk-release.yml @@ -40,6 +40,9 @@ jobs: runs-on: ubuntu-latest needs: check-version-change if: needs.check-version-change.outputs.version_changed == 'true' || github.event_name == 'workflow_dispatch' + permissions: + contents: read + id-token: write defaults: run: working-directory: ./skyvern-ts/client @@ -49,19 +52,21 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '18' + node-version: '20' registry-url: 'https://registry.npmjs.org' + - name: Upgrade npm to a Trusted Publishing-capable version + run: npm i -g npm@^11.5.1 - name: Install Fern dependencies run: npm install -g patch-package - name: Install dependencies - run: npm install + run: npm ci - name: Build CJS run: npx tsc --project ./tsconfig.cjs.json - name: Build ESM run: npx tsc --project ./tsconfig.esm.json - name: Rename ESM files run: node scripts/rename-to-esm-files.js dist/esm - - name: Publish to npm - run: npm publish --access public + - name: Publish to npm with provenance via OIDC env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NPM_CONFIG_PROVENANCE: "true" + run: npm publish --access public --provenance diff --git a/fern/generators.yml b/fern/generators.yml index 05548323..cb022221 100644 --- a/fern/generators.yml +++ b/fern/generators.yml @@ -34,3 +34,8 @@ groups: description: "The Skyvern TypeScript library provides convenient access to the Skyvern APIs from TypeScript." publishConfig: access: "public" + provenance: true + repository: + type: git + url: https://github.com/Skyvern-AI/skyvern.git + directory: skyvern-ts/client diff --git a/skyvern-ts/client/package-lock.json b/skyvern-ts/client/package-lock.json index f80c5471..b371f0af 100644 --- a/skyvern-ts/client/package-lock.json +++ b/skyvern-ts/client/package-lock.json @@ -646,9 +646,9 @@ } }, "node_modules/@inquirer/ansi": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", - "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", "dev": true, "license": "MIT", "engines": { @@ -656,14 +656,14 @@ } }, "node_modules/@inquirer/confirm": { - "version": "5.1.19", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz", - "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==", + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.20.tgz", + "integrity": "sha512-HDGiWh2tyRZa0M1ZnEIUCQro25gW/mN8ODByicQrbR1yHx4hT+IOpozCMi5TgBtUdklLwRI2mv14eNpftDluEw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" + "@inquirer/core": "^10.3.1", + "@inquirer/type": "^3.0.10" }, "engines": { "node": ">=18" @@ -678,20 +678,20 @@ } }, "node_modules/@inquirer/core": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", - "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.1.tgz", + "integrity": "sha512-hzGKIkfomGFPgxKmnKEKeA+uCYBqC+TKtRx5LgyHRCrF6S2MliwRIjp3sUaWwVzMp7ZXVs8elB0Tfe682Rpg4w==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", - "mute-stream": "^2.0.0", + "mute-stream": "^3.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.2" + "yoctocolors-cjs": "^2.1.3" }, "engines": { "node": ">=18" @@ -706,9 +706,9 @@ } }, "node_modules/@inquirer/figures": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", - "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "dev": true, "license": "MIT", "engines": { @@ -716,9 +716,9 @@ } }, "node_modules/@inquirer/type": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", - "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "dev": true, "license": "MIT", "engines": { @@ -827,9 +827,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.0.tgz", - "integrity": "sha512-MX3DD/o2W36nlgQb8KA5QtUw/bK5aR9YDzNmX1PRHZAa6LF/MQCWMN477CgBMg8gH1vEiEZsjWRIZeL/7ttUVA==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz", + "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==", "cpu": [ "arm" ], @@ -841,9 +841,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.0.tgz", - "integrity": "sha512-U4/R8ZvikDYLkl+hyAGP23SRHp3LwYSRy9SvJqsnva7TYLhVMy39RTVCYn1DdRNxXl1CyCQgE/mXKm9jaQT4ig==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz", + "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==", "cpu": [ "arm64" ], @@ -855,9 +855,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.0.tgz", - "integrity": "sha512-nBG2BXRU3ifdK0HdqBKaT5VI6ScoIpABYZ+dWwQkIOYd8Suo4iykgPikjhsTd7NeHgJJ3OqlKYCcNkZtB1iLVQ==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz", + "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==", "cpu": [ "arm64" ], @@ -869,9 +869,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.0.tgz", - "integrity": "sha512-QuZ5hYStB/vW7b8zQYtdIPpIfNNlUXtGk8zVTkoTMKzMhE2/6tVvcCWqdWqCVhx6eguJJjKjtZ9lAAG/D3yNeA==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz", + "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==", "cpu": [ "x64" ], @@ -883,9 +883,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.0.tgz", - "integrity": "sha512-4yYPm1PJwK/HKI4FzElAPj2EAAFaaLUWzXV3S3edKy71JcEVzBCpgaXyEcDh3blBIjLml+aMkj6HEVGSuzpz+g==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz", + "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==", "cpu": [ "arm64" ], @@ -897,9 +897,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.0.tgz", - "integrity": "sha512-1SvE5euwWV8JqFc4zEAqHbJbf2yJl00EoHVcnlFqLzjrIExYttLxfZeMDIXY6Yx+bskphrQakpChZKzE2JECEg==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz", + "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==", "cpu": [ "x64" ], @@ -911,9 +911,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.0.tgz", - "integrity": "sha512-9tS4QyfU5NF5CdUugEi7kWbcGD7pbu6Fm8SunuePH6beeQgtcRZ9K9KVwKHEgfBHeeyrr5OvfV1qWs7PMDOf5w==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz", + "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==", "cpu": [ "arm" ], @@ -925,9 +925,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.0.tgz", - "integrity": "sha512-U+0ovxGU9bVJIHfW+oALpHd0ho1YDwhj0yHASDzIj+bOeo+VzEpNtHxcjhFab0YcHUorIMoqyxckC98+81oTJw==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz", + "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==", "cpu": [ "arm" ], @@ -939,9 +939,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.0.tgz", - "integrity": "sha512-Cp/TQ+wLjRTqTuiVwLz4XPZMo3ROl7EJYMF8HhMp8Uf+9kOOATB3/p4gGZPpuQ4BP7qEXG29ET24u9+F0ERYkQ==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz", + "integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==", "cpu": [ "arm64" ], @@ -953,9 +953,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.0.tgz", - "integrity": "sha512-SuGoAwhsSonrSTEZTiQOGC3+XZfq7rc/qAdAOBrYYIp8pu+Wh4EFFXl6+QYYNbNrHL3DnVoWACLwnfwlTa0neA==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz", + "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==", "cpu": [ "arm64" ], @@ -967,9 +967,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.0.tgz", - "integrity": "sha512-EOKej1x0WoePnJWfg7ZbnUqiuiQunshzsKZSIfTHFDiCY9pnsr3Weit1GjcpGnun7H5HuRREqkT2c9CcKxNwSg==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz", + "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==", "cpu": [ "loong64" ], @@ -981,9 +981,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.0.tgz", - "integrity": "sha512-YAvv2aMFlfiawJ97lutomuehG2Yowd4YgsAqI85XNiMK9eBA1vEMZHt3BShg8cUvak71BM+VFRHddqc+OrRdVA==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz", + "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==", "cpu": [ "ppc64" ], @@ -995,9 +995,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.0.tgz", - "integrity": "sha512-DxZe/sMVaqN+s5kVk3Iq619Rgyl1JCTob7xOLSNC84mbzg3NYTSheqqrtVllYjLYo4wm9YyqjVS57miuzNyXbQ==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz", + "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==", "cpu": [ "riscv64" ], @@ -1009,9 +1009,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.0.tgz", - "integrity": "sha512-N7+iZ0jEhwLY1FEsjbCR9lAxIZP0k+3Cghx9vSQWn+rcW8SgN8VcCmwJDoPDaGKTzWWB791U1s79BSLnEhUa0Q==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz", + "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==", "cpu": [ "riscv64" ], @@ -1023,9 +1023,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.0.tgz", - "integrity": "sha512-MA/NVneZyIskjvXdh2NR9YcPi7eHWBlQOWP2X8OymzyeUEB0JfUpmbKQZngHmOlyleV2IoR5nHIgMSRjLskOnA==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz", + "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==", "cpu": [ "s390x" ], @@ -1037,9 +1037,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.0.tgz", - "integrity": "sha512-iYEYzYpfaSCkunVD0LOYrD9OMc357be7+rBuCxW1qvsjCGl+95iWnYAFfyEoxAm6koasNN3tFxFYze5MKl5S3A==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz", + "integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==", "cpu": [ "x64" ], @@ -1051,9 +1051,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.0.tgz", - "integrity": "sha512-FoRekOqhRUKbJMsB5LvhQchDeFeNlS6UGUwi0p3860sxE4zE+lp07FnkuR+yQH0rSn6iLXsnr44jnorgl8mGlQ==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz", + "integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==", "cpu": [ "x64" ], @@ -1065,9 +1065,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.0.tgz", - "integrity": "sha512-mEN2k1zKO5PUzW8W15hKpLh+zZI2by1onX2GfI93OekGbKN5aTjWGo7yAjwRZLjhAgs2UQcXmEWbIw0R5B4RnQ==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz", + "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==", "cpu": [ "arm64" ], @@ -1079,9 +1079,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.0.tgz", - "integrity": "sha512-V1dEKUXqevG0wxo6ysGrL7g2T6tndmo6Uqw5vzOqCXv+DHc8m0RRgcCm+96iigDniwpvV6o4HZtkRUnuTz9XiA==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz", + "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==", "cpu": [ "arm64" ], @@ -1093,9 +1093,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.0.tgz", - "integrity": "sha512-93mJ8Hm9+vbhtu+A1VtmwptSqCYojtMQkBGDjLytCWC8muxmZLGo/MA/4CMAWf6+QpKlxTTMDAHdTC+kxn9ZcQ==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz", + "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==", "cpu": [ "ia32" ], @@ -1107,9 +1107,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.0.tgz", - "integrity": "sha512-1OrYs0p/deXEFLUW1gvyjIabmsJKY3I/9fCUA1K6demaNc4iEhXDW6RnyPv/BWqb7NRmQ9+i+SKoi1HgJxWcwg==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz", + "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==", "cpu": [ "x64" ], @@ -1121,9 +1121,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.0.tgz", - "integrity": "sha512-xtSei8paPcLy3GzeeOjoRrllJn6EN8PB+/bXnhZ4R0AaviJsRwtKxFZRVnfFXNZTTp0nLeDo+BcEuIfdZS14/A==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz", + "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==", "cpu": [ "x64" ], @@ -1843,9 +1843,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.248", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.248.tgz", - "integrity": "sha512-zsur2yunphlyAO4gIubdJEXCK6KOVvtpiuDfCIqbM9FjcnMYiyn0ICa3hWfPr0nc41zcLWobgy1iL7VvoOyA2Q==", + "version": "1.5.249", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz", + "integrity": "sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==", "dev": true, "license": "ISC" }, @@ -2317,13 +2317,13 @@ } }, "node_modules/mute-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", - "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", "dev": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/nanoid": { @@ -2477,11 +2477,10 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.0.tgz", - "integrity": "sha512-43Z5T+4YTdfYkkA6CStU2DUYh7Ha9dLtvK+K3n0yEE/QS+4i28vSxrQsM59KqpvmT4tbOwJsFnRGMj/tvmQwWw==", + "version": "4.53.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz", + "integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==", "dev": true, - "hasInstallScript": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.8" @@ -2494,28 +2493,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.0", - "@rollup/rollup-android-arm64": "4.53.0", - "@rollup/rollup-darwin-arm64": "4.53.0", - "@rollup/rollup-darwin-x64": "4.53.0", - "@rollup/rollup-freebsd-arm64": "4.53.0", - "@rollup/rollup-freebsd-x64": "4.53.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.0", - "@rollup/rollup-linux-arm-musleabihf": "4.53.0", - "@rollup/rollup-linux-arm64-gnu": "4.53.0", - "@rollup/rollup-linux-arm64-musl": "4.53.0", - "@rollup/rollup-linux-loong64-gnu": "4.53.0", - "@rollup/rollup-linux-ppc64-gnu": "4.53.0", - "@rollup/rollup-linux-riscv64-gnu": "4.53.0", - "@rollup/rollup-linux-riscv64-musl": "4.53.0", - "@rollup/rollup-linux-s390x-gnu": "4.53.0", - "@rollup/rollup-linux-x64-gnu": "4.53.0", - "@rollup/rollup-linux-x64-musl": "4.53.0", - "@rollup/rollup-openharmony-arm64": "4.53.0", - "@rollup/rollup-win32-arm64-msvc": "4.53.0", - "@rollup/rollup-win32-ia32-msvc": "4.53.0", - "@rollup/rollup-win32-x64-gnu": "4.53.0", - "@rollup/rollup-win32-x64-msvc": "4.53.0", + "@rollup/rollup-android-arm-eabi": "4.53.2", + "@rollup/rollup-android-arm64": "4.53.2", + "@rollup/rollup-darwin-arm64": "4.53.2", + "@rollup/rollup-darwin-x64": "4.53.2", + "@rollup/rollup-freebsd-arm64": "4.53.2", + "@rollup/rollup-freebsd-x64": "4.53.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", + "@rollup/rollup-linux-arm-musleabihf": "4.53.2", + "@rollup/rollup-linux-arm64-gnu": "4.53.2", + "@rollup/rollup-linux-arm64-musl": "4.53.2", + "@rollup/rollup-linux-loong64-gnu": "4.53.2", + "@rollup/rollup-linux-ppc64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-gnu": "4.53.2", + "@rollup/rollup-linux-riscv64-musl": "4.53.2", + "@rollup/rollup-linux-s390x-gnu": "4.53.2", + "@rollup/rollup-linux-x64-gnu": "4.53.2", + "@rollup/rollup-linux-x64-musl": "4.53.2", + "@rollup/rollup-openharmony-arm64": "4.53.2", + "@rollup/rollup-win32-arm64-msvc": "4.53.2", + "@rollup/rollup-win32-ia32-msvc": "4.53.2", + "@rollup/rollup-win32-x64-gnu": "4.53.2", + "@rollup/rollup-win32-x64-msvc": "4.53.2", "fsevents": "~2.3.2" } }, diff --git a/skyvern-ts/client/package.json b/skyvern-ts/client/package.json index f85c98c3..313e54da 100644 --- a/skyvern-ts/client/package.json +++ b/skyvern-ts/client/package.json @@ -2,7 +2,11 @@ "name": "@skyvern/client", "version": "0.2.22", "private": false, - "repository": "github:Skyvern-AI/skyvern", + "repository": { + "type": "git", + "url": "https://github.com/Skyvern-AI/skyvern.git", + "directory": "skyvern-ts/client" + }, "type": "commonjs", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.mjs", @@ -64,6 +68,7 @@ "sideEffects": false, "description": "The Skyvern TypeScript library provides convenient access to the Skyvern APIs from TypeScript.", "publishConfig": { - "access": "public" + "access": "public", + "provenance": true } } diff --git a/skyvern-ts/client/reference.md b/skyvern-ts/client/reference.md index d92184a3..8fcc22da 100644 --- a/skyvern-ts/client/reference.md +++ b/skyvern-ts/client/reference.md @@ -475,6 +475,249 @@ await client.workflows.updateWorkflowFolder("wpid_123"); + + + + +## BrowserProfiles +
client.browserProfiles.listBrowserProfiles({ ...params }) -> Skyvern.BrowserProfile[] +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all browser profiles for the organization +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.browserProfiles.listBrowserProfiles({ + include_deleted: true +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Skyvern.ListBrowserProfilesV1BrowserProfilesGetRequest` + +
+
+ +
+
+ +**requestOptions:** `BrowserProfiles.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.browserProfiles.createBrowserProfile({ ...params }) -> Skyvern.BrowserProfile +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.browserProfiles.createBrowserProfile({ + name: "name" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Skyvern.CreateBrowserProfileRequest` + +
+
+ +
+
+ +**requestOptions:** `BrowserProfiles.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.browserProfiles.getBrowserProfile(profileId) -> Skyvern.BrowserProfile +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get a specific browser profile by ID +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.browserProfiles.getBrowserProfile("bp_123456"); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**profileId:** `string` — The ID of the browser profile. browser_profile_id starts with `bp_` + +
+
+ +
+
+ +**requestOptions:** `BrowserProfiles.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.browserProfiles.deleteBrowserProfile(profileId) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Delete a browser profile (soft delete) +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.browserProfiles.deleteBrowserProfile("bp_123456"); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**profileId:** `string` — The ID of the browser profile to delete. browser_profile_id starts with `bp_` + +
+
+ +
+
+ +**requestOptions:** `BrowserProfiles.RequestOptions` + +
+
+
+
+ +
diff --git a/skyvern-ts/client/src/Client.ts b/skyvern-ts/client/src/Client.ts index 6e3d04b1..231c254a 100644 --- a/skyvern-ts/client/src/Client.ts +++ b/skyvern-ts/client/src/Client.ts @@ -1,6 +1,7 @@ // This file was auto-generated by Fern from our API Definition. import * as Skyvern from "./api/index.js"; +import { BrowserProfiles } from "./api/resources/browserProfiles/client/Client.js"; import { Scripts } from "./api/resources/scripts/client/Client.js"; import { Workflows } from "./api/resources/workflows/client/Client.js"; import type { BaseClientOptions, BaseRequestOptions } from "./BaseClient.js"; @@ -18,6 +19,7 @@ export declare namespace SkyvernClient { export class SkyvernClient { protected readonly _options: SkyvernClient.Options; protected _workflows: Workflows | undefined; + protected _browserProfiles: BrowserProfiles | undefined; protected _scripts: Scripts | undefined; constructor(_options: SkyvernClient.Options = {}) { @@ -42,6 +44,10 @@ export class SkyvernClient { return (this._workflows ??= new Workflows(this._options)); } + public get browserProfiles(): BrowserProfiles { + return (this._browserProfiles ??= new BrowserProfiles(this._options)); + } + public get scripts(): Scripts { return (this._scripts ??= new Scripts(this._options)); } @@ -530,25 +536,34 @@ export class SkyvernClient { /** * Create a new workflow * - * @param {Skyvern.WorkflowRequest} request + * @param {Skyvern.CreateWorkflowRequest} request * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Skyvern.UnprocessableEntityError} * * @example - * await client.createWorkflow({}) + * await client.createWorkflow({ + * folder_id: "folder_id", + * body: {} + * }) */ public createWorkflow( - request: Skyvern.WorkflowRequest, + request: Skyvern.CreateWorkflowRequest, requestOptions?: SkyvernClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__createWorkflow(request, requestOptions)); } private async __createWorkflow( - request: Skyvern.WorkflowRequest, + request: Skyvern.CreateWorkflowRequest, requestOptions?: SkyvernClient.RequestOptions, ): Promise> { + const { folder_id: folderId, body: _body } = request; + const _queryParams: Record = {}; + if (folderId != null) { + _queryParams.folder_id = folderId; + } + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( this._options?.headers, mergeOnlyDefinedHeaders({ "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey }), @@ -564,9 +579,9 @@ export class SkyvernClient { method: "POST", headers: _headers, contentType: "application/json", - queryParameters: requestOptions?.queryParams, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, requestType: "json", - body: request, + body: _body, timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, diff --git a/skyvern-ts/client/src/api/client/requests/CreateWorkflowRequest.ts b/skyvern-ts/client/src/api/client/requests/CreateWorkflowRequest.ts new file mode 100644 index 00000000..e263cf9a --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/CreateWorkflowRequest.ts @@ -0,0 +1,16 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * { + * folder_id: "folder_id", + * body: {} + * } + */ +export interface CreateWorkflowRequest { + /** Optional folder ID to assign the workflow to */ + folder_id?: string; + body: Skyvern.WorkflowRequest; +} diff --git a/skyvern-ts/client/src/api/client/requests/index.ts b/skyvern-ts/client/src/api/client/requests/index.ts index 42868e3e..9f1a7783 100644 --- a/skyvern-ts/client/src/api/client/requests/index.ts +++ b/skyvern-ts/client/src/api/client/requests/index.ts @@ -1,6 +1,7 @@ export type { CreateBrowserSessionRequest } from "./CreateBrowserSessionRequest.js"; export type { CreateCredentialRequest } from "./CreateCredentialRequest.js"; export type { CreateScriptRequest } from "./CreateScriptRequest.js"; +export type { CreateWorkflowRequest } from "./CreateWorkflowRequest.js"; export type { DeployScriptRequest } from "./DeployScriptRequest.js"; export type { GetCredentialsRequest } from "./GetCredentialsRequest.js"; export type { GetRunArtifactsRequest } from "./GetRunArtifactsRequest.js"; diff --git a/skyvern-ts/client/src/api/resources/browserProfiles/client/Client.ts b/skyvern-ts/client/src/api/resources/browserProfiles/client/Client.ts new file mode 100644 index 00000000..919b2cdb --- /dev/null +++ b/skyvern-ts/client/src/api/resources/browserProfiles/client/Client.ts @@ -0,0 +1,343 @@ +// 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"; +import * as Skyvern from "../../../index.js"; + +export declare namespace BrowserProfiles { + export interface Options extends BaseClientOptions {} + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class BrowserProfiles { + protected readonly _options: BrowserProfiles.Options; + + constructor(_options: BrowserProfiles.Options = {}) { + this._options = _options; + } + + /** + * Get all browser profiles for the organization + * + * @param {Skyvern.ListBrowserProfilesV1BrowserProfilesGetRequest} request + * @param {BrowserProfiles.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.browserProfiles.listBrowserProfiles({ + * include_deleted: true + * }) + */ + public listBrowserProfiles( + request: Skyvern.ListBrowserProfilesV1BrowserProfilesGetRequest = {}, + requestOptions?: BrowserProfiles.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__listBrowserProfiles(request, requestOptions)); + } + + private async __listBrowserProfiles( + request: Skyvern.ListBrowserProfilesV1BrowserProfilesGetRequest = {}, + requestOptions?: BrowserProfiles.RequestOptions, + ): Promise> { + const { include_deleted: includeDeleted } = request; + const _queryParams: Record = {}; + if (includeDeleted != null) { + _queryParams.include_deleted = includeDeleted.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/browser_profiles", + ), + 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.BrowserProfile[], 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/browser_profiles."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * @param {Skyvern.CreateBrowserProfileRequest} request + * @param {BrowserProfiles.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.browserProfiles.createBrowserProfile({ + * name: "name" + * }) + */ + public createBrowserProfile( + request: Skyvern.CreateBrowserProfileRequest, + requestOptions?: BrowserProfiles.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__createBrowserProfile(request, requestOptions)); + } + + private async __createBrowserProfile( + request: Skyvern.CreateBrowserProfileRequest, + requestOptions?: BrowserProfiles.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_profiles", + ), + 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.BrowserProfile, 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 POST /v1/browser_profiles."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get a specific browser profile by ID + * + * @param {string} profileId - The ID of the browser profile. browser_profile_id starts with `bp_` + * @param {BrowserProfiles.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.browserProfiles.getBrowserProfile("bp_123456") + */ + public getBrowserProfile( + profileId: string, + requestOptions?: BrowserProfiles.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getBrowserProfile(profileId, requestOptions)); + } + + private async __getBrowserProfile( + profileId: string, + requestOptions?: BrowserProfiles.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_profiles/${core.url.encodePathParam(profileId)}`, + ), + 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.BrowserProfile, 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/browser_profiles/{profile_id}.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Delete a browser profile (soft delete) + * + * @param {string} profileId - The ID of the browser profile to delete. browser_profile_id starts with `bp_` + * @param {BrowserProfiles.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.browserProfiles.deleteBrowserProfile("bp_123456") + */ + public deleteBrowserProfile( + profileId: string, + requestOptions?: BrowserProfiles.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__deleteBrowserProfile(profileId, requestOptions)); + } + + private async __deleteBrowserProfile( + profileId: string, + requestOptions?: BrowserProfiles.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_profiles/${core.url.encodePathParam(profileId)}`, + ), + 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: undefined, 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/browser_profiles/{profile_id}.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } +} diff --git a/skyvern-ts/client/src/api/resources/browserProfiles/client/index.ts b/skyvern-ts/client/src/api/resources/browserProfiles/client/index.ts new file mode 100644 index 00000000..195f9aa8 --- /dev/null +++ b/skyvern-ts/client/src/api/resources/browserProfiles/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/CreateBrowserProfileRequest.ts b/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/CreateBrowserProfileRequest.ts new file mode 100644 index 00000000..e45d2bb4 --- /dev/null +++ b/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/CreateBrowserProfileRequest.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * name: "name" + * } + */ +export interface CreateBrowserProfileRequest { + /** Name for the browser profile */ + name: string; + /** Optional profile description */ + description?: string; + /** Persistent browser session to convert into a profile */ + browser_session_id?: string; + /** Workflow run whose persisted session should be captured */ + workflow_run_id?: string; +} diff --git a/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/ListBrowserProfilesV1BrowserProfilesGetRequest.ts b/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/ListBrowserProfilesV1BrowserProfilesGetRequest.ts new file mode 100644 index 00000000..f608e5b5 --- /dev/null +++ b/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/ListBrowserProfilesV1BrowserProfilesGetRequest.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * include_deleted: true + * } + */ +export interface ListBrowserProfilesV1BrowserProfilesGetRequest { + /** Include deleted browser profiles */ + include_deleted?: boolean; +} diff --git a/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/index.ts b/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/index.ts new file mode 100644 index 00000000..cf162a87 --- /dev/null +++ b/skyvern-ts/client/src/api/resources/browserProfiles/client/requests/index.ts @@ -0,0 +1,2 @@ +export type { CreateBrowserProfileRequest } from "./CreateBrowserProfileRequest.js"; +export type { ListBrowserProfilesV1BrowserProfilesGetRequest } from "./ListBrowserProfilesV1BrowserProfilesGetRequest.js"; diff --git a/skyvern-ts/client/src/api/resources/browserProfiles/index.ts b/skyvern-ts/client/src/api/resources/browserProfiles/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/skyvern-ts/client/src/api/resources/browserProfiles/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/skyvern-ts/client/src/api/resources/index.ts b/skyvern-ts/client/src/api/resources/index.ts index 9852fa96..540d813e 100644 --- a/skyvern-ts/client/src/api/resources/index.ts +++ b/skyvern-ts/client/src/api/resources/index.ts @@ -1,3 +1,5 @@ +export * from "./browserProfiles/client/requests/index.js"; +export * as browserProfiles from "./browserProfiles/index.js"; export * as scripts from "./scripts/index.js"; export * from "./workflows/client/requests/index.js"; export * as workflows from "./workflows/index.js"; diff --git a/skyvern-ts/client/src/api/types/BrowserProfile.ts b/skyvern-ts/client/src/api/types/BrowserProfile.ts new file mode 100644 index 00000000..dc7b3361 --- /dev/null +++ b/skyvern-ts/client/src/api/types/BrowserProfile.ts @@ -0,0 +1,11 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface BrowserProfile { + browser_profile_id: string; + organization_id: string; + name: string; + description?: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/InputOrSelectContext.ts b/skyvern-ts/client/src/api/types/InputOrSelectContext.ts index 120d872f..ff2e27a8 100644 --- a/skyvern-ts/client/src/api/types/InputOrSelectContext.ts +++ b/skyvern-ts/client/src/api/types/InputOrSelectContext.ts @@ -7,4 +7,5 @@ export interface InputOrSelectContext { is_search_bar?: boolean; is_location_input?: boolean; is_date_related?: boolean; + date_format?: string; } diff --git a/skyvern-ts/client/src/api/types/RunSdkActionRequestAction.ts b/skyvern-ts/client/src/api/types/RunSdkActionRequestAction.ts index 12496e47..4c56c27e 100644 --- a/skyvern-ts/client/src/api/types/RunSdkActionRequestAction.ts +++ b/skyvern-ts/client/src/api/types/RunSdkActionRequestAction.ts @@ -10,6 +10,7 @@ export type RunSdkActionRequestAction = | Skyvern.RunSdkActionRequestAction.AiClick | Skyvern.RunSdkActionRequestAction.AiInputText | Skyvern.RunSdkActionRequestAction.AiSelectOption + | Skyvern.RunSdkActionRequestAction.AiUploadFile | Skyvern.RunSdkActionRequestAction.Extract; export namespace RunSdkActionRequestAction { @@ -29,6 +30,10 @@ export namespace RunSdkActionRequestAction { type: "ai_select_option"; } + export interface AiUploadFile extends Skyvern.UploadFileAction { + type: "ai_upload_file"; + } + export interface Extract extends Skyvern.ExtractAction { type: "extract"; } diff --git a/skyvern-ts/client/src/api/types/TaskRunResponse.ts b/skyvern-ts/client/src/api/types/TaskRunResponse.ts index eed4dda6..01d37c9e 100644 --- a/skyvern-ts/client/src/api/types/TaskRunResponse.ts +++ b/skyvern-ts/client/src/api/types/TaskRunResponse.ts @@ -31,6 +31,8 @@ export interface TaskRunResponse { app_url?: string; /** ID of the Skyvern persistent browser session used for this run */ browser_session_id?: string; + /** ID of the browser profile used for this run */ + 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; /** The script run result */ diff --git a/skyvern-ts/client/src/api/types/UploadFileAction.ts b/skyvern-ts/client/src/api/types/UploadFileAction.ts new file mode 100644 index 00000000..9f105512 --- /dev/null +++ b/skyvern-ts/client/src/api/types/UploadFileAction.ts @@ -0,0 +1,24 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Upload file action parameters. + */ +export interface UploadFileAction { + /** CSS selector for the element */ + selector?: string; + /** File URL for upload */ + file_url?: string; + /** The intention or goal of the upload */ + intention?: string; + /** Additional context data */ + data?: UploadFileAction.Data; + /** Timeout in milliseconds */ + timeout?: number; +} + +export namespace UploadFileAction { + /** + * Additional context data + */ + export type Data = string | Record; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowCreateYamlRequest.ts b/skyvern-ts/client/src/api/types/WorkflowCreateYamlRequest.ts index 8d9c2745..4deec6e6 100644 --- a/skyvern-ts/client/src/api/types/WorkflowCreateYamlRequest.ts +++ b/skyvern-ts/client/src/api/types/WorkflowCreateYamlRequest.ts @@ -21,4 +21,5 @@ export interface WorkflowCreateYamlRequest { cache_key?: string; run_sequentially?: boolean; sequential_key?: string; + folder_id?: string; } diff --git a/skyvern-ts/client/src/api/types/WorkflowRunRequest.ts b/skyvern-ts/client/src/api/types/WorkflowRunRequest.ts index 8198f10d..cf024b50 100644 --- a/skyvern-ts/client/src/api/types/WorkflowRunRequest.ts +++ b/skyvern-ts/client/src/api/types/WorkflowRunRequest.ts @@ -46,6 +46,8 @@ export interface WorkflowRunRequest { totp_identifier?: string; /** ID of a Skyvern browser session to reuse, having it continue from the current screen state */ browser_session_id?: string; + /** ID of a browser profile to reuse for this workflow run */ + 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; /** The extra HTTP headers for the requests in browser. */ diff --git a/skyvern-ts/client/src/api/types/WorkflowRunResponse.ts b/skyvern-ts/client/src/api/types/WorkflowRunResponse.ts index 77d08e37..1e4a7441 100644 --- a/skyvern-ts/client/src/api/types/WorkflowRunResponse.ts +++ b/skyvern-ts/client/src/api/types/WorkflowRunResponse.ts @@ -31,6 +31,8 @@ export interface WorkflowRunResponse { app_url?: string; /** ID of the Skyvern persistent browser session used for this run */ browser_session_id?: string; + /** ID of the browser profile used for this run */ + 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; /** The script run result */ diff --git a/skyvern-ts/client/src/api/types/index.ts b/skyvern-ts/client/src/api/types/index.ts index c3d99ddf..020d0f29 100644 --- a/skyvern-ts/client/src/api/types/index.ts +++ b/skyvern-ts/client/src/api/types/index.ts @@ -19,6 +19,7 @@ export * from "./BitwardenLoginCredentialParameterYaml.js"; export * from "./BitwardenSensitiveInformationParameter.js"; export * from "./BitwardenSensitiveInformationParameterYaml.js"; export * from "./BlockType.js"; +export * from "./BrowserProfile.js"; export * from "./BrowserSessionResponse.js"; export * from "./ClickAction.js"; export * from "./ClickContext.js"; @@ -113,6 +114,7 @@ export * from "./ThoughtScenario.js"; export * from "./ThoughtType.js"; export * from "./TotpCode.js"; export * from "./TotpType.js"; +export * from "./UploadFileAction.js"; export * from "./UploadToS3Block.js"; export * from "./UploadToS3BlockYaml.js"; export * from "./UrlBlock.js"; diff --git a/skyvern-ts/client/tests/wire/browserProfiles.test.ts b/skyvern-ts/client/tests/wire/browserProfiles.test.ts new file mode 100644 index 00000000..794c60ea --- /dev/null +++ b/skyvern-ts/client/tests/wire/browserProfiles.test.ts @@ -0,0 +1,236 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as Skyvern from "../../src/api/index"; +import { SkyvernClient } from "../../src/Client"; +import { mockServerPool } from "../mock-server/MockServerPool"; + +describe("BrowserProfiles", () => { + test("listBrowserProfiles (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + browser_profile_id: "browser_profile_id", + organization_id: "organization_id", + name: "name", + description: "description", + 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/browser_profiles") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.browserProfiles.listBrowserProfiles({ + include_deleted: true, + }); + expect(response).toEqual([ + { + browser_profile_id: "browser_profile_id", + organization_id: "organization_id", + name: "name", + description: "description", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }, + ]); + }); + + test("listBrowserProfiles (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/browser_profiles") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.browserProfiles.listBrowserProfiles(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("createBrowserProfile (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { name: "name" }; + const rawResponseBody = { + browser_profile_id: "browser_profile_id", + organization_id: "organization_id", + name: "name", + description: "description", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .post("/v1/browser_profiles") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.browserProfiles.createBrowserProfile({ + name: "name", + }); + expect(response).toEqual({ + browser_profile_id: "browser_profile_id", + organization_id: "organization_id", + name: "name", + description: "description", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }); + }); + + test("createBrowserProfile (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { name: "name" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/browser_profiles") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.browserProfiles.createBrowserProfile({ + name: "name", + }); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("getBrowserProfile (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + browser_profile_id: "browser_profile_id", + organization_id: "organization_id", + name: "name", + description: "description", + 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/browser_profiles/bp_123456") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.browserProfiles.getBrowserProfile("bp_123456"); + expect(response).toEqual({ + browser_profile_id: "browser_profile_id", + organization_id: "organization_id", + name: "name", + description: "description", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }); + }); + + test("getBrowserProfile (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/browser_profiles/profile_id") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.browserProfiles.getBrowserProfile("profile_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("getBrowserProfile (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/browser_profiles/profile_id") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.browserProfiles.getBrowserProfile("profile_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("deleteBrowserProfile (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + server.mockEndpoint().delete("/v1/browser_profiles/bp_123456").respondWith().statusCode(200).build(); + + const response = await client.browserProfiles.deleteBrowserProfile("bp_123456"); + expect(response).toEqual(undefined); + }); + + test("deleteBrowserProfile (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/browser_profiles/profile_id") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.browserProfiles.deleteBrowserProfile("profile_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("deleteBrowserProfile (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/browser_profiles/profile_id") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.browserProfiles.deleteBrowserProfile("profile_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); +}); diff --git a/skyvern-ts/client/tests/wire/main.test.ts b/skyvern-ts/client/tests/wire/main.test.ts index d42f0daf..5f5dcdee 100644 --- a/skyvern-ts/client/tests/wire/main.test.ts +++ b/skyvern-ts/client/tests/wire/main.test.ts @@ -26,6 +26,7 @@ describe("SkyvernClient", () => { 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 }, errors: [{ key: "value" }], @@ -90,6 +91,7 @@ describe("SkyvernClient", () => { 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, @@ -197,6 +199,7 @@ describe("SkyvernClient", () => { 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 }, errors: [{ key: "value" }], @@ -211,6 +214,7 @@ describe("SkyvernClient", () => { totp_url: "totp_url", totp_identifier: "totp_identifier", browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", max_screenshot_scrolls: 1, extra_http_headers: { key: "value" }, browser_address: "browser_address", @@ -261,6 +265,7 @@ describe("SkyvernClient", () => { 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, @@ -283,6 +288,7 @@ describe("SkyvernClient", () => { totp_url: "totp_url", totp_identifier: "totp_identifier", browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", max_screenshot_scrolls: 1, extra_http_headers: { key: "value", @@ -362,6 +368,7 @@ describe("SkyvernClient", () => { 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 }, errors: [{ key: "value" }], @@ -414,6 +421,7 @@ describe("SkyvernClient", () => { 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, @@ -728,7 +736,10 @@ describe("SkyvernClient", () => { .jsonBody(rawResponseBody) .build(); - const response = await client.createWorkflow({}); + const response = await client.createWorkflow({ + folder_id: "folder_id", + body: {}, + }); expect(response).toEqual({ workflow_id: "workflow_id", organization_id: "organization_id", @@ -804,7 +815,9 @@ describe("SkyvernClient", () => { .build(); await expect(async () => { - return await client.createWorkflow({}); + return await client.createWorkflow({ + body: {}, + }); }).rejects.toThrow(Skyvern.UnprocessableEntityError); }); @@ -2070,6 +2083,7 @@ describe("SkyvernClient", () => { 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 }, errors: [{ key: "value" }], @@ -2084,6 +2098,7 @@ describe("SkyvernClient", () => { totp_url: "totp_url", totp_identifier: "totp_identifier", browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", max_screenshot_scrolls: 1, extra_http_headers: { key: "value" }, browser_address: "browser_address", @@ -2127,6 +2142,7 @@ describe("SkyvernClient", () => { 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, @@ -2149,6 +2165,7 @@ describe("SkyvernClient", () => { totp_url: "totp_url", totp_identifier: "totp_identifier", browser_session_id: "browser_session_id", + browser_profile_id: "browser_profile_id", max_screenshot_scrolls: 1, extra_http_headers: { key: "value", diff --git a/skyvern/client/__init__.py b/skyvern/client/__init__.py index fb393f7b..22c29e84 100644 --- a/skyvern/client/__init__.py +++ b/skyvern/client/__init__.py @@ -41,6 +41,7 @@ if typing.TYPE_CHECKING: BitwardenSensitiveInformationParameter, BitwardenSensitiveInformationParameterYaml, BlockType, + BrowserProfile, BrowserSessionResponse, ClickAction, ClickActionData, @@ -468,7 +469,7 @@ if typing.TYPE_CHECKING: WorkflowStatus, ) from .errors import BadRequestError, ForbiddenError, NotFoundError, UnprocessableEntityError - from . import scripts, workflows + from . import browser_profiles, scripts, workflows from .client import AsyncSkyvern, Skyvern from .environment import SkyvernEnvironment from .version import __version__ @@ -509,6 +510,7 @@ _dynamic_imports: typing.Dict[str, str] = { "BitwardenSensitiveInformationParameter": ".types", "BitwardenSensitiveInformationParameterYaml": ".types", "BlockType": ".types", + "BrowserProfile": ".types", "BrowserSessionResponse": ".types", "ClickAction": ".types", "ClickActionData": ".types", @@ -940,6 +942,7 @@ _dynamic_imports: typing.Dict[str, str] = { "WorkflowRunTimelineType": ".types", "WorkflowStatus": ".types", "__version__": ".version", + "browser_profiles": ".browser_profiles", "scripts": ".scripts", "workflows": ".workflows", } @@ -1003,6 +1006,7 @@ __all__ = [ "BitwardenSensitiveInformationParameter", "BitwardenSensitiveInformationParameterYaml", "BlockType", + "BrowserProfile", "BrowserSessionResponse", "ClickAction", "ClickActionData", @@ -1434,6 +1438,7 @@ __all__ = [ "WorkflowRunTimelineType", "WorkflowStatus", "__version__", + "browser_profiles", "scripts", "workflows", ] diff --git a/skyvern/client/browser_profiles/__init__.py b/skyvern/client/browser_profiles/__init__.py new file mode 100644 index 00000000..5cde0202 --- /dev/null +++ b/skyvern/client/browser_profiles/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/skyvern/client/browser_profiles/client.py b/skyvern/client/browser_profiles/client.py new file mode 100644 index 00000000..6f05b290 --- /dev/null +++ b/skyvern/client/browser_profiles/client.py @@ -0,0 +1,379 @@ +# 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 ..types.browser_profile import BrowserProfile +from .raw_client import AsyncRawBrowserProfilesClient, RawBrowserProfilesClient + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class BrowserProfilesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawBrowserProfilesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawBrowserProfilesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawBrowserProfilesClient + """ + return self._raw_client + + def list_browser_profiles( + self, *, include_deleted: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[BrowserProfile]: + """ + Get all browser profiles for the organization + + Parameters + ---------- + include_deleted : typing.Optional[bool] + Include deleted browser profiles + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[BrowserProfile] + Successful Response + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.browser_profiles.list_browser_profiles( + include_deleted=True, + ) + """ + _response = self._raw_client.list_browser_profiles( + include_deleted=include_deleted, request_options=request_options + ) + return _response.data + + def create_browser_profile( + self, + *, + name: str, + description: typing.Optional[str] = OMIT, + browser_session_id: typing.Optional[str] = OMIT, + workflow_run_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> BrowserProfile: + """ + Parameters + ---------- + name : str + Name for the browser profile + + description : typing.Optional[str] + Optional profile description + + browser_session_id : typing.Optional[str] + Persistent browser session to convert into a profile + + workflow_run_id : typing.Optional[str] + Workflow run whose persisted session should be captured + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BrowserProfile + Successful Response + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.browser_profiles.create_browser_profile( + name="name", + ) + """ + _response = self._raw_client.create_browser_profile( + name=name, + description=description, + browser_session_id=browser_session_id, + workflow_run_id=workflow_run_id, + request_options=request_options, + ) + return _response.data + + def get_browser_profile( + self, profile_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> BrowserProfile: + """ + Get a specific browser profile by ID + + Parameters + ---------- + profile_id : str + The ID of the browser profile. browser_profile_id starts with `bp_` + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BrowserProfile + Successfully retrieved browser profile + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.browser_profiles.get_browser_profile( + profile_id="bp_123456", + ) + """ + _response = self._raw_client.get_browser_profile(profile_id, request_options=request_options) + return _response.data + + def delete_browser_profile( + self, profile_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a browser profile (soft delete) + + Parameters + ---------- + profile_id : str + The ID of the browser profile to delete. browser_profile_id starts with `bp_` + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from skyvern import Skyvern + + client = Skyvern( + api_key="YOUR_API_KEY", + ) + client.browser_profiles.delete_browser_profile( + profile_id="bp_123456", + ) + """ + _response = self._raw_client.delete_browser_profile(profile_id, request_options=request_options) + return _response.data + + +class AsyncBrowserProfilesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawBrowserProfilesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawBrowserProfilesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawBrowserProfilesClient + """ + return self._raw_client + + async def list_browser_profiles( + self, *, include_deleted: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[BrowserProfile]: + """ + Get all browser profiles for the organization + + Parameters + ---------- + include_deleted : typing.Optional[bool] + Include deleted browser profiles + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[BrowserProfile] + Successful Response + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.browser_profiles.list_browser_profiles( + include_deleted=True, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_browser_profiles( + include_deleted=include_deleted, request_options=request_options + ) + return _response.data + + async def create_browser_profile( + self, + *, + name: str, + description: typing.Optional[str] = OMIT, + browser_session_id: typing.Optional[str] = OMIT, + workflow_run_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> BrowserProfile: + """ + Parameters + ---------- + name : str + Name for the browser profile + + description : typing.Optional[str] + Optional profile description + + browser_session_id : typing.Optional[str] + Persistent browser session to convert into a profile + + workflow_run_id : typing.Optional[str] + Workflow run whose persisted session should be captured + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BrowserProfile + Successful Response + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.browser_profiles.create_browser_profile( + name="name", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_browser_profile( + name=name, + description=description, + browser_session_id=browser_session_id, + workflow_run_id=workflow_run_id, + request_options=request_options, + ) + return _response.data + + async def get_browser_profile( + self, profile_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> BrowserProfile: + """ + Get a specific browser profile by ID + + Parameters + ---------- + profile_id : str + The ID of the browser profile. browser_profile_id starts with `bp_` + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BrowserProfile + Successfully retrieved browser profile + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.browser_profiles.get_browser_profile( + profile_id="bp_123456", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_browser_profile(profile_id, request_options=request_options) + return _response.data + + async def delete_browser_profile( + self, profile_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Delete a browser profile (soft delete) + + Parameters + ---------- + profile_id : str + The ID of the browser profile to delete. browser_profile_id starts with `bp_` + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from skyvern import AsyncSkyvern + + client = AsyncSkyvern( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.browser_profiles.delete_browser_profile( + profile_id="bp_123456", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_browser_profile(profile_id, request_options=request_options) + return _response.data diff --git a/skyvern/client/browser_profiles/raw_client.py b/skyvern/client/browser_profiles/raw_client.py new file mode 100644 index 00000000..57536bc3 --- /dev/null +++ b/skyvern/client/browser_profiles/raw_client.py @@ -0,0 +1,507 @@ +# 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.jsonable_encoder import jsonable_encoder +from ..core.pydantic_utilities import parse_obj_as +from ..core.request_options import RequestOptions +from ..errors.not_found_error import NotFoundError +from ..errors.unprocessable_entity_error import UnprocessableEntityError +from ..types.browser_profile import BrowserProfile + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawBrowserProfilesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_browser_profiles( + self, *, include_deleted: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.List[BrowserProfile]]: + """ + Get all browser profiles for the organization + + Parameters + ---------- + include_deleted : typing.Optional[bool] + Include deleted browser profiles + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.List[BrowserProfile]] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + "v1/browser_profiles", + method="GET", + params={ + "include_deleted": include_deleted, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[BrowserProfile], + parse_obj_as( + type_=typing.List[BrowserProfile], # 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 create_browser_profile( + self, + *, + name: str, + description: typing.Optional[str] = OMIT, + browser_session_id: typing.Optional[str] = OMIT, + workflow_run_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[BrowserProfile]: + """ + Parameters + ---------- + name : str + Name for the browser profile + + description : typing.Optional[str] + Optional profile description + + browser_session_id : typing.Optional[str] + Persistent browser session to convert into a profile + + workflow_run_id : typing.Optional[str] + Workflow run whose persisted session should be captured + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[BrowserProfile] + Successful Response + """ + _response = self._client_wrapper.httpx_client.request( + "v1/browser_profiles", + method="POST", + json={ + "name": name, + "description": description, + "browser_session_id": browser_session_id, + "workflow_run_id": workflow_run_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BrowserProfile, + parse_obj_as( + type_=BrowserProfile, # 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_browser_profile( + self, profile_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[BrowserProfile]: + """ + Get a specific browser profile by ID + + Parameters + ---------- + profile_id : str + The ID of the browser profile. browser_profile_id starts with `bp_` + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[BrowserProfile] + Successfully retrieved browser profile + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/browser_profiles/{jsonable_encoder(profile_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BrowserProfile, + parse_obj_as( + type_=BrowserProfile, # 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_browser_profile( + self, profile_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[None]: + """ + Delete a browser profile (soft delete) + + Parameters + ---------- + profile_id : str + The ID of the browser profile to delete. browser_profile_id starts with `bp_` + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"v1/browser_profiles/{jsonable_encoder(profile_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + 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) + + +class AsyncRawBrowserProfilesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_browser_profiles( + self, *, include_deleted: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[typing.List[BrowserProfile]]: + """ + Get all browser profiles for the organization + + Parameters + ---------- + include_deleted : typing.Optional[bool] + Include deleted browser profiles + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.List[BrowserProfile]] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/browser_profiles", + method="GET", + params={ + "include_deleted": include_deleted, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[BrowserProfile], + parse_obj_as( + type_=typing.List[BrowserProfile], # 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 create_browser_profile( + self, + *, + name: str, + description: typing.Optional[str] = OMIT, + browser_session_id: typing.Optional[str] = OMIT, + workflow_run_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[BrowserProfile]: + """ + Parameters + ---------- + name : str + Name for the browser profile + + description : typing.Optional[str] + Optional profile description + + browser_session_id : typing.Optional[str] + Persistent browser session to convert into a profile + + workflow_run_id : typing.Optional[str] + Workflow run whose persisted session should be captured + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[BrowserProfile] + Successful Response + """ + _response = await self._client_wrapper.httpx_client.request( + "v1/browser_profiles", + method="POST", + json={ + "name": name, + "description": description, + "browser_session_id": browser_session_id, + "workflow_run_id": workflow_run_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BrowserProfile, + parse_obj_as( + type_=BrowserProfile, # 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_browser_profile( + self, profile_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[BrowserProfile]: + """ + Get a specific browser profile by ID + + Parameters + ---------- + profile_id : str + The ID of the browser profile. browser_profile_id starts with `bp_` + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[BrowserProfile] + Successfully retrieved browser profile + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/browser_profiles/{jsonable_encoder(profile_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BrowserProfile, + parse_obj_as( + type_=BrowserProfile, # 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_browser_profile( + self, profile_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[None]: + """ + Delete a browser profile (soft delete) + + Parameters + ---------- + profile_id : str + The ID of the browser profile to delete. browser_profile_id starts with `bp_` + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"v1/browser_profiles/{jsonable_encoder(profile_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + 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) diff --git a/skyvern/client/client.py b/skyvern/client/client.py index 2cb9de05..521af1c9 100644 --- a/skyvern/client/client.py +++ b/skyvern/client/client.py @@ -35,6 +35,7 @@ from .types.workflow_run_timeline import WorkflowRunTimeline from .types.workflow_status import WorkflowStatus if typing.TYPE_CHECKING: + from .browser_profiles.client import AsyncBrowserProfilesClient, BrowserProfilesClient from .scripts.client import AsyncScriptsClient, ScriptsClient from .workflows.client import AsyncWorkflowsClient, WorkflowsClient # this is used as the default value for optional parameters @@ -108,6 +109,7 @@ class Skyvern: ) self._raw_client = RawSkyvern(client_wrapper=self._client_wrapper) self._workflows: typing.Optional[WorkflowsClient] = None + self._browser_profiles: typing.Optional[BrowserProfilesClient] = None self._scripts: typing.Optional[ScriptsClient] = None @property @@ -297,6 +299,7 @@ class Skyvern: totp_url: typing.Optional[str] = OMIT, totp_identifier: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, + browser_profile_id: typing.Optional[str] = OMIT, max_screenshot_scrolls: typing.Optional[int] = OMIT, extra_http_headers: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, browser_address: typing.Optional[str] = OMIT, @@ -363,6 +366,9 @@ class Skyvern: browser_session_id : typing.Optional[str] ID of a Skyvern browser session to reuse, having it continue from the current screen state + browser_profile_id : typing.Optional[str] + ID of a browser profile to reuse for this workflow run + max_screenshot_scrolls : typing.Optional[int] The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. @@ -412,6 +418,7 @@ class Skyvern: totp_url=totp_url, totp_identifier=totp_identifier, browser_session_id=browser_session_id, + browser_profile_id=browser_profile_id, max_screenshot_scrolls=max_screenshot_scrolls, extra_http_headers=extra_http_headers, browser_address=browser_address, @@ -575,6 +582,7 @@ class Skyvern: def create_workflow( self, *, + folder_id: typing.Optional[str] = None, json_definition: typing.Optional[WorkflowCreateYamlRequest] = OMIT, yaml_definition: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -584,6 +592,9 @@ class Skyvern: Parameters ---------- + folder_id : typing.Optional[str] + Optional folder ID to assign the workflow to + json_definition : typing.Optional[WorkflowCreateYamlRequest] Workflow definition in JSON format @@ -605,10 +616,15 @@ class Skyvern: client = Skyvern( api_key="YOUR_API_KEY", ) - client.create_workflow() + client.create_workflow( + folder_id="folder_id", + ) """ _response = self._raw_client.create_workflow( - json_definition=json_definition, yaml_definition=yaml_definition, request_options=request_options + folder_id=folder_id, + json_definition=json_definition, + yaml_definition=yaml_definition, + request_options=request_options, ) return _response.data @@ -1577,6 +1593,14 @@ class Skyvern: self._workflows = WorkflowsClient(client_wrapper=self._client_wrapper) return self._workflows + @property + def browser_profiles(self): + if self._browser_profiles is None: + from .browser_profiles.client import BrowserProfilesClient # noqa: E402 + + self._browser_profiles = BrowserProfilesClient(client_wrapper=self._client_wrapper) + return self._browser_profiles + @property def scripts(self): if self._scripts is None: @@ -1653,6 +1677,7 @@ class AsyncSkyvern: ) self._raw_client = AsyncRawSkyvern(client_wrapper=self._client_wrapper) self._workflows: typing.Optional[AsyncWorkflowsClient] = None + self._browser_profiles: typing.Optional[AsyncBrowserProfilesClient] = None self._scripts: typing.Optional[AsyncScriptsClient] = None @property @@ -1850,6 +1875,7 @@ class AsyncSkyvern: totp_url: typing.Optional[str] = OMIT, totp_identifier: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, + browser_profile_id: typing.Optional[str] = OMIT, max_screenshot_scrolls: typing.Optional[int] = OMIT, extra_http_headers: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, browser_address: typing.Optional[str] = OMIT, @@ -1916,6 +1942,9 @@ class AsyncSkyvern: browser_session_id : typing.Optional[str] ID of a Skyvern browser session to reuse, having it continue from the current screen state + browser_profile_id : typing.Optional[str] + ID of a browser profile to reuse for this workflow run + max_screenshot_scrolls : typing.Optional[int] The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. @@ -1973,6 +2002,7 @@ class AsyncSkyvern: totp_url=totp_url, totp_identifier=totp_identifier, browser_session_id=browser_session_id, + browser_profile_id=browser_profile_id, max_screenshot_scrolls=max_screenshot_scrolls, extra_http_headers=extra_http_headers, browser_address=browser_address, @@ -2160,6 +2190,7 @@ class AsyncSkyvern: async def create_workflow( self, *, + folder_id: typing.Optional[str] = None, json_definition: typing.Optional[WorkflowCreateYamlRequest] = OMIT, yaml_definition: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -2169,6 +2200,9 @@ class AsyncSkyvern: Parameters ---------- + folder_id : typing.Optional[str] + Optional folder ID to assign the workflow to + json_definition : typing.Optional[WorkflowCreateYamlRequest] Workflow definition in JSON format @@ -2195,13 +2229,18 @@ class AsyncSkyvern: async def main() -> None: - await client.create_workflow() + await client.create_workflow( + folder_id="folder_id", + ) asyncio.run(main()) """ _response = await self._raw_client.create_workflow( - json_definition=json_definition, yaml_definition=yaml_definition, request_options=request_options + folder_id=folder_id, + json_definition=json_definition, + yaml_definition=yaml_definition, + request_options=request_options, ) return _response.data @@ -3344,6 +3383,14 @@ class AsyncSkyvern: self._workflows = AsyncWorkflowsClient(client_wrapper=self._client_wrapper) return self._workflows + @property + def browser_profiles(self): + if self._browser_profiles is None: + from .browser_profiles.client import AsyncBrowserProfilesClient # noqa: E402 + + self._browser_profiles = AsyncBrowserProfilesClient(client_wrapper=self._client_wrapper) + return self._browser_profiles + @property def scripts(self): if self._scripts is None: diff --git a/skyvern/client/raw_client.py b/skyvern/client/raw_client.py index 600097a2..7a437ab1 100644 --- a/skyvern/client/raw_client.py +++ b/skyvern/client/raw_client.py @@ -256,6 +256,7 @@ class RawSkyvern: totp_url: typing.Optional[str] = OMIT, totp_identifier: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, + browser_profile_id: typing.Optional[str] = OMIT, max_screenshot_scrolls: typing.Optional[int] = OMIT, extra_http_headers: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, browser_address: typing.Optional[str] = OMIT, @@ -322,6 +323,9 @@ class RawSkyvern: browser_session_id : typing.Optional[str] ID of a Skyvern browser session to reuse, having it continue from the current screen state + browser_profile_id : typing.Optional[str] + ID of a browser profile to reuse for this workflow run + max_screenshot_scrolls : typing.Optional[int] The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. @@ -360,6 +364,7 @@ class RawSkyvern: "totp_url": totp_url, "totp_identifier": totp_identifier, "browser_session_id": browser_session_id, + "browser_profile_id": browser_profile_id, "max_screenshot_scrolls": max_screenshot_scrolls, "extra_http_headers": extra_http_headers, "browser_address": browser_address, @@ -624,6 +629,7 @@ class RawSkyvern: def create_workflow( self, *, + folder_id: typing.Optional[str] = None, json_definition: typing.Optional[WorkflowCreateYamlRequest] = OMIT, yaml_definition: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -633,6 +639,9 @@ class RawSkyvern: Parameters ---------- + folder_id : typing.Optional[str] + Optional folder ID to assign the workflow to + json_definition : typing.Optional[WorkflowCreateYamlRequest] Workflow definition in JSON format @@ -650,6 +659,9 @@ class RawSkyvern: _response = self._client_wrapper.httpx_client.request( "v1/workflows", method="POST", + params={ + "folder_id": folder_id, + }, json={ "json_definition": convert_and_respect_annotation_metadata( object_=json_definition, annotation=WorkflowCreateYamlRequest, direction="write" @@ -2360,6 +2372,7 @@ class AsyncRawSkyvern: totp_url: typing.Optional[str] = OMIT, totp_identifier: typing.Optional[str] = OMIT, browser_session_id: typing.Optional[str] = OMIT, + browser_profile_id: typing.Optional[str] = OMIT, max_screenshot_scrolls: typing.Optional[int] = OMIT, extra_http_headers: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, browser_address: typing.Optional[str] = OMIT, @@ -2426,6 +2439,9 @@ class AsyncRawSkyvern: browser_session_id : typing.Optional[str] ID of a Skyvern browser session to reuse, having it continue from the current screen state + browser_profile_id : typing.Optional[str] + ID of a browser profile to reuse for this workflow run + max_screenshot_scrolls : typing.Optional[int] The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. @@ -2464,6 +2480,7 @@ class AsyncRawSkyvern: "totp_url": totp_url, "totp_identifier": totp_identifier, "browser_session_id": browser_session_id, + "browser_profile_id": browser_profile_id, "max_screenshot_scrolls": max_screenshot_scrolls, "extra_http_headers": extra_http_headers, "browser_address": browser_address, @@ -2728,6 +2745,7 @@ class AsyncRawSkyvern: async def create_workflow( self, *, + folder_id: typing.Optional[str] = None, json_definition: typing.Optional[WorkflowCreateYamlRequest] = OMIT, yaml_definition: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, @@ -2737,6 +2755,9 @@ class AsyncRawSkyvern: Parameters ---------- + folder_id : typing.Optional[str] + Optional folder ID to assign the workflow to + json_definition : typing.Optional[WorkflowCreateYamlRequest] Workflow definition in JSON format @@ -2754,6 +2775,9 @@ class AsyncRawSkyvern: _response = await self._client_wrapper.httpx_client.request( "v1/workflows", method="POST", + params={ + "folder_id": folder_id, + }, json={ "json_definition": convert_and_respect_annotation_metadata( object_=json_definition, annotation=WorkflowCreateYamlRequest, direction="write" diff --git a/skyvern/client/types/__init__.py b/skyvern/client/types/__init__.py index 2ddc9898..7967124c 100644 --- a/skyvern/client/types/__init__.py +++ b/skyvern/client/types/__init__.py @@ -42,6 +42,7 @@ if typing.TYPE_CHECKING: from .bitwarden_sensitive_information_parameter import BitwardenSensitiveInformationParameter from .bitwarden_sensitive_information_parameter_yaml import BitwardenSensitiveInformationParameterYaml from .block_type import BlockType + from .browser_profile import BrowserProfile from .browser_session_response import BrowserSessionResponse from .click_action import ClickAction from .click_action_data import ClickActionData @@ -546,6 +547,7 @@ _dynamic_imports: typing.Dict[str, str] = { "BitwardenSensitiveInformationParameter": ".bitwarden_sensitive_information_parameter", "BitwardenSensitiveInformationParameterYaml": ".bitwarden_sensitive_information_parameter_yaml", "BlockType": ".block_type", + "BrowserProfile": ".browser_profile", "BrowserSessionResponse": ".browser_session_response", "ClickAction": ".click_action", "ClickActionData": ".click_action_data", @@ -1030,6 +1032,7 @@ __all__ = [ "BitwardenSensitiveInformationParameter", "BitwardenSensitiveInformationParameterYaml", "BlockType", + "BrowserProfile", "BrowserSessionResponse", "ClickAction", "ClickActionData", diff --git a/skyvern/client/types/browser_profile.py b/skyvern/client/types/browser_profile.py new file mode 100644 index 00000000..cce68275 --- /dev/null +++ b/skyvern/client/types/browser_profile.py @@ -0,0 +1,26 @@ +# 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 BrowserProfile(UniversalBaseModel): + browser_profile_id: str + organization_id: str + name: str + description: typing.Optional[str] = None + created_at: dt.datetime + modified_at: dt.datetime + deleted_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/get_run_response.py b/skyvern/client/types/get_run_response.py index e86943aa..8c371918 100644 --- a/skyvern/client/types/get_run_response.py +++ b/skyvern/client/types/get_run_response.py @@ -32,6 +32,7 @@ class GetRunResponse_TaskV1(UniversalBaseModel): finished_at: typing.Optional[dt.datetime] = None app_url: typing.Optional[str] = None browser_session_id: typing.Optional[str] = None + browser_profile_id: typing.Optional[str] = None max_screenshot_scrolls: typing.Optional[int] = None script_run: typing.Optional[ScriptRunResponse] = None errors: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = None @@ -63,6 +64,7 @@ class GetRunResponse_TaskV2(UniversalBaseModel): finished_at: typing.Optional[dt.datetime] = None app_url: typing.Optional[str] = None browser_session_id: typing.Optional[str] = None + browser_profile_id: typing.Optional[str] = None max_screenshot_scrolls: typing.Optional[int] = None script_run: typing.Optional[ScriptRunResponse] = None errors: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = None @@ -94,6 +96,7 @@ class GetRunResponse_OpenaiCua(UniversalBaseModel): finished_at: typing.Optional[dt.datetime] = None app_url: typing.Optional[str] = None browser_session_id: typing.Optional[str] = None + browser_profile_id: typing.Optional[str] = None max_screenshot_scrolls: typing.Optional[int] = None script_run: typing.Optional[ScriptRunResponse] = None errors: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = None @@ -125,6 +128,7 @@ class GetRunResponse_AnthropicCua(UniversalBaseModel): finished_at: typing.Optional[dt.datetime] = None app_url: typing.Optional[str] = None browser_session_id: typing.Optional[str] = None + browser_profile_id: typing.Optional[str] = None max_screenshot_scrolls: typing.Optional[int] = None script_run: typing.Optional[ScriptRunResponse] = None errors: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = None @@ -156,6 +160,7 @@ class GetRunResponse_UiTars(UniversalBaseModel): finished_at: typing.Optional[dt.datetime] = None app_url: typing.Optional[str] = None browser_session_id: typing.Optional[str] = None + browser_profile_id: typing.Optional[str] = None max_screenshot_scrolls: typing.Optional[int] = None script_run: typing.Optional[ScriptRunResponse] = None errors: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = None @@ -187,6 +192,7 @@ class GetRunResponse_WorkflowRun(UniversalBaseModel): finished_at: typing.Optional[dt.datetime] = None app_url: typing.Optional[str] = None browser_session_id: typing.Optional[str] = None + browser_profile_id: typing.Optional[str] = None max_screenshot_scrolls: typing.Optional[int] = None script_run: typing.Optional[ScriptRunResponse] = None errors: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = None diff --git a/skyvern/client/types/input_or_select_context.py b/skyvern/client/types/input_or_select_context.py index 1de646bc..e3a01232 100644 --- a/skyvern/client/types/input_or_select_context.py +++ b/skyvern/client/types/input_or_select_context.py @@ -13,6 +13,7 @@ class InputOrSelectContext(UniversalBaseModel): is_search_bar: typing.Optional[bool] = None is_location_input: typing.Optional[bool] = None is_date_related: typing.Optional[bool] = None + date_format: 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/run_sdk_action_response_result.py b/skyvern/client/types/run_sdk_action_response_result.py deleted file mode 100644 index b771d251..00000000 --- a/skyvern/client/types/run_sdk_action_response_result.py +++ /dev/null @@ -1,7 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -RunSdkActionResponseResult = typing.Union[ - str, typing.Dict[str, typing.Optional[typing.Any]], typing.List[typing.Optional[typing.Any]], float, bool -] diff --git a/skyvern/client/types/sdk_action.py b/skyvern/client/types/sdk_action.py deleted file mode 100644 index fff9c3cc..00000000 --- a/skyvern/client/types/sdk_action.py +++ /dev/null @@ -1,129 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from __future__ import annotations - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .click_action_data import ClickActionData -from .extract_action_data import ExtractActionData -from .extract_action_extract_schema import ExtractActionExtractSchema -from .input_text_action_data import InputTextActionData -from .select_option_action_data import SelectOptionActionData -from .upload_file_action_data import UploadFileActionData - - -class SdkAction_AiClick(UniversalBaseModel): - type: typing.Literal["ai_click"] = "ai_click" - selector: typing.Optional[str] = None - intention: typing.Optional[str] = None - data: typing.Optional[ClickActionData] = None - timeout: typing.Optional[float] = 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 - - -class SdkAction_AiInputText(UniversalBaseModel): - type: typing.Literal["ai_input_text"] = "ai_input_text" - selector: typing.Optional[str] = None - value: typing.Optional[str] = None - intention: typing.Optional[str] = None - data: typing.Optional[InputTextActionData] = None - totp_identifier: typing.Optional[str] = None - totp_url: typing.Optional[str] = None - timeout: typing.Optional[float] = 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 - - -class SdkAction_AiSelectOption(UniversalBaseModel): - type: typing.Literal["ai_select_option"] = "ai_select_option" - selector: typing.Optional[str] = None - value: typing.Optional[str] = None - intention: typing.Optional[str] = None - data: typing.Optional[SelectOptionActionData] = None - timeout: typing.Optional[float] = 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 - - -class SdkAction_AiUploadFile(UniversalBaseModel): - type: typing.Literal["ai_upload_file"] = "ai_upload_file" - selector: typing.Optional[str] = None - file_url: typing.Optional[str] = None - intention: typing.Optional[str] = None - data: typing.Optional[UploadFileActionData] = None - timeout: typing.Optional[float] = 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 - - -class SdkAction_AiAct(UniversalBaseModel): - type: typing.Literal["ai_act"] = "ai_act" - intention: typing.Optional[str] = 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 - - -class SdkAction_Extract(UniversalBaseModel): - type: typing.Literal["extract"] = "extract" - prompt: typing.Optional[str] = None - extract_schema: typing.Optional[ExtractActionExtractSchema] = None - error_code_mapping: typing.Optional[typing.Dict[str, typing.Optional[str]]] = None - intention: typing.Optional[str] = None - data: typing.Optional[ExtractActionData] = 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 - - -SdkAction = typing.Union[ - SdkAction_AiClick, - SdkAction_AiInputText, - SdkAction_AiSelectOption, - SdkAction_AiUploadFile, - SdkAction_AiAct, - SdkAction_Extract, -] diff --git a/skyvern/client/types/task_run_response.py b/skyvern/client/types/task_run_response.py index 6409b93b..4521f2c1 100644 --- a/skyvern/client/types/task_run_response.py +++ b/skyvern/client/types/task_run_response.py @@ -83,6 +83,11 @@ class TaskRunResponse(UniversalBaseModel): ID of the Skyvern persistent browser session used for this run """ + browser_profile_id: typing.Optional[str] = pydantic.Field(default=None) + """ + ID of the browser profile used for this run + """ + max_screenshot_scrolls: typing.Optional[int] = pydantic.Field(default=None) """ The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot diff --git a/skyvern/client/types/workflow_create_yaml_request.py b/skyvern/client/types/workflow_create_yaml_request.py index 63a971ee..08bca456 100644 --- a/skyvern/client/types/workflow_create_yaml_request.py +++ b/skyvern/client/types/workflow_create_yaml_request.py @@ -30,6 +30,7 @@ class WorkflowCreateYamlRequest(UniversalBaseModel): cache_key: typing.Optional[str] = None run_sequentially: typing.Optional[bool] = None sequential_key: typing.Optional[str] = None + folder_id: 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.py b/skyvern/client/types/workflow_run_request.py index 5602dcfe..46f75e8e 100644 --- a/skyvern/client/types/workflow_run_request.py +++ b/skyvern/client/types/workflow_run_request.py @@ -72,6 +72,11 @@ class WorkflowRunRequest(UniversalBaseModel): ID of a Skyvern browser session to reuse, having it continue from the current screen state """ + browser_profile_id: typing.Optional[str] = pydantic.Field(default=None) + """ + ID of a browser profile to reuse for this workflow run + """ + max_screenshot_scrolls: typing.Optional[int] = pydantic.Field(default=None) """ The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. diff --git a/skyvern/client/types/workflow_run_response.py b/skyvern/client/types/workflow_run_response.py index 71cd462e..0459d13a 100644 --- a/skyvern/client/types/workflow_run_response.py +++ b/skyvern/client/types/workflow_run_response.py @@ -83,6 +83,11 @@ class WorkflowRunResponse(UniversalBaseModel): ID of the Skyvern persistent browser session used for this run """ + browser_profile_id: typing.Optional[str] = pydantic.Field(default=None) + """ + ID of the browser profile used for this run + """ + max_screenshot_scrolls: typing.Optional[int] = pydantic.Field(default=None) """ The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot diff --git a/skyvern/library/skyvern_browser_page_ai.py b/skyvern/library/skyvern_browser_page_ai.py index 10f359e4..44ce01d3 100644 --- a/skyvern/library/skyvern_browser_page_ai.py +++ b/skyvern/library/skyvern_browser_page_ai.py @@ -2,13 +2,13 @@ from typing import TYPE_CHECKING, Any from playwright.async_api import Page -from skyvern.client.types.sdk_action import ( - SdkAction_AiAct, - SdkAction_AiClick, - SdkAction_AiInputText, - SdkAction_AiSelectOption, - SdkAction_AiUploadFile, - SdkAction_Extract, +from skyvern.client import ( + RunSdkActionRequestAction_AiAct, + RunSdkActionRequestAction_AiClick, + RunSdkActionRequestAction_AiInputText, + RunSdkActionRequestAction_AiSelectOption, + RunSdkActionRequestAction_AiUploadFile, + RunSdkActionRequestAction_Extract, ) from skyvern.config import settings from skyvern.core.script_generations.skyvern_page_ai import SkyvernPageAi @@ -43,7 +43,7 @@ class SdkSkyvernPageAi(SkyvernPageAi): browser_session_id=self._browser.browser_session_id, browser_address=self._browser.browser_address, workflow_run_id=self._browser.workflow_run_id, - action=SdkAction_AiClick( + action=RunSdkActionRequestAction_AiClick( selector=selector, intention=intention, data=data, @@ -68,7 +68,7 @@ class SdkSkyvernPageAi(SkyvernPageAi): await self._browser.sdk.ensure_has_server() response = await self._browser.client.run_sdk_action( url=self._page.url, - action=SdkAction_AiInputText( + action=RunSdkActionRequestAction_AiInputText( selector=selector, value=value, intention=intention, @@ -97,7 +97,7 @@ class SdkSkyvernPageAi(SkyvernPageAi): await self._browser.sdk.ensure_has_server() response = await self._browser.client.run_sdk_action( url=self._page.url, - action=SdkAction_AiSelectOption( + action=RunSdkActionRequestAction_AiSelectOption( selector=selector, value=value, intention=intention, @@ -125,7 +125,7 @@ class SdkSkyvernPageAi(SkyvernPageAi): await self._browser.sdk.ensure_has_server() response = await self._browser.client.run_sdk_action( url=self._page.url, - action=SdkAction_AiUploadFile( + action=RunSdkActionRequestAction_AiUploadFile( selector=selector, file_url=files, intention=intention, @@ -152,7 +152,7 @@ class SdkSkyvernPageAi(SkyvernPageAi): await self._browser.sdk.ensure_has_server() response = await self._browser.client.run_sdk_action( url=self._page.url, - action=SdkAction_Extract( + action=RunSdkActionRequestAction_Extract( prompt=prompt, extract_schema=schema, error_code_mapping=error_code_mapping, @@ -175,7 +175,7 @@ class SdkSkyvernPageAi(SkyvernPageAi): await self._browser.sdk.ensure_has_server() response = await self._browser.client.run_sdk_action( url=self._page.url, - action=SdkAction_AiAct( + action=RunSdkActionRequestAction_AiAct( intention=prompt, ), browser_session_id=self._browser.browser_session_id,