mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-09 15:17:59 -05:00
fix(frontend): Credentials disabling onboarding Run button (#11244)
## Changes 🏗️ The onboarding `Run` button is disabled sometimes when an agent requiring credentials is selected. We think this can be because the credentials load _async_ by a sub-component ( `<CredentialsInputs />` ), and there wasn't a way for the parent component to know whether they loaded or not. - Refactored **Step 5** of onboarding to adhere to our code conventions - split concerns and colocated state - used generated API hooks - the UI will only render once API calls succeed - Created a system where ``<CredentialsInputs />` notify the parent component when they load - Did minor adjustments here and there ## Checklist 📋 ### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] I will know once I find an agent with credentials that I can run.... <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added visual agent selection card displaying agent details during onboarding * Introduced credentials input management for agent configuration * Added onboarding guidance for initiating agent runs * **Improvements** * Enhanced onboarding flow with improved state management * Refined login state handling * Adjusted spacing in agent rating display <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -55,7 +55,7 @@
|
||||
"@sentry/nextjs": "10.15.0",
|
||||
"@supabase/ssr": "0.6.1",
|
||||
"@supabase/supabase-js": "2.55.0",
|
||||
"@tanstack/react-query": "5.85.3",
|
||||
"@tanstack/react-query": "5.87.1",
|
||||
"@tanstack/react-table": "8.21.3",
|
||||
"@types/jaro-winkler": "0.2.4",
|
||||
"@vercel/analytics": "1.5.0",
|
||||
@@ -103,7 +103,7 @@
|
||||
"shepherd.js": "14.5.1",
|
||||
"sonner": "2.0.7",
|
||||
"tailwind-merge": "2.6.0",
|
||||
"tailwind-scrollbar": "4.0.2",
|
||||
"tailwind-scrollbar": "3.1.0",
|
||||
"tailwindcss-animate": "1.0.7",
|
||||
"uuid": "11.1.0",
|
||||
"vaul": "1.1.2",
|
||||
|
||||
144
autogpt_platform/frontend/pnpm-lock.yaml
generated
144
autogpt_platform/frontend/pnpm-lock.yaml
generated
@@ -99,8 +99,8 @@ importers:
|
||||
specifier: 2.55.0
|
||||
version: 2.55.0
|
||||
'@tanstack/react-query':
|
||||
specifier: 5.85.3
|
||||
version: 5.85.3(react@18.3.1)
|
||||
specifier: 5.87.1
|
||||
version: 5.87.1(react@18.3.1)
|
||||
'@tanstack/react-table':
|
||||
specifier: 8.21.3
|
||||
version: 8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -243,8 +243,8 @@ importers:
|
||||
specifier: 2.6.0
|
||||
version: 2.6.0
|
||||
tailwind-scrollbar:
|
||||
specifier: 4.0.2
|
||||
version: 4.0.2(react@18.3.1)(tailwindcss@3.4.17)
|
||||
specifier: 3.1.0
|
||||
version: 3.1.0(tailwindcss@3.4.17)
|
||||
tailwindcss-animate:
|
||||
specifier: 1.0.7
|
||||
version: 1.0.7(tailwindcss@3.4.17)
|
||||
@@ -287,7 +287,7 @@ importers:
|
||||
version: 5.86.0(eslint@8.57.1)(typescript@5.9.2)
|
||||
'@tanstack/react-query-devtools':
|
||||
specifier: 5.87.3
|
||||
version: 5.87.3(@tanstack/react-query@5.85.3(react@18.3.1))(react@18.3.1)
|
||||
version: 5.87.3(@tanstack/react-query@5.87.1(react@18.3.1))(react@18.3.1)
|
||||
'@types/canvas-confetti':
|
||||
specifier: 1.9.0
|
||||
version: 1.9.0
|
||||
@@ -947,10 +947,6 @@ packages:
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/runtime@7.28.3':
|
||||
resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/runtime@7.28.4':
|
||||
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -985,9 +981,6 @@ packages:
|
||||
'@emnapi/core@1.5.0':
|
||||
resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==}
|
||||
|
||||
'@emnapi/runtime@1.4.5':
|
||||
resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==}
|
||||
|
||||
'@emnapi/runtime@1.5.0':
|
||||
resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==}
|
||||
|
||||
@@ -1159,12 +1152,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@eslint-community/eslint-utils@4.7.0':
|
||||
resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||
|
||||
'@eslint-community/eslint-utils@4.9.0':
|
||||
resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
@@ -2856,8 +2843,8 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
|
||||
'@tanstack/query-core@5.85.3':
|
||||
resolution: {integrity: sha512-9Ne4USX83nHmRuEYs78LW+3lFEEO2hBDHu7mrdIgAFx5Zcrs7ker3n/i8p4kf6OgKExmaDN5oR0efRD7i2J0DQ==}
|
||||
'@tanstack/query-core@5.87.1':
|
||||
resolution: {integrity: sha512-HOFHVvhOCprrWvtccSzc7+RNqpnLlZ5R6lTmngb8aq7b4rc2/jDT0w+vLdQ4lD9bNtQ+/A4GsFXy030Gk4ollA==}
|
||||
|
||||
'@tanstack/query-devtools@5.87.3':
|
||||
resolution: {integrity: sha512-LkzxzSr2HS1ALHTgDmJH5eGAVsSQiuwz//VhFW5OqNk0OQ+Fsqba0Tsf+NzWRtXYvpgUqwQr4b2zdFZwxHcGvg==}
|
||||
@@ -2868,8 +2855,8 @@ packages:
|
||||
'@tanstack/react-query': ^5.87.1
|
||||
react: ^18 || ^19
|
||||
|
||||
'@tanstack/react-query@5.85.3':
|
||||
resolution: {integrity: sha512-AqU8TvNh5GVIE8I+TUU0noryBRy7gOY0XhSayVXmOPll4UkZeLWKDwi0rtWOZbwLRCbyxorfJ5DIjDqE7GXpcQ==}
|
||||
'@tanstack/react-query@5.87.1':
|
||||
resolution: {integrity: sha512-YKauf8jfMowgAqcxj96AHs+Ux3m3bWT1oSVKamaRPXSnW2HqSznnTCEkAVqctF1e/W9R/mPcyzzINIgpOH94qg==}
|
||||
peerDependencies:
|
||||
react: ^18 || ^19
|
||||
|
||||
@@ -3045,9 +3032,6 @@ packages:
|
||||
'@types/phoenix@1.6.6':
|
||||
resolution: {integrity: sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==}
|
||||
|
||||
'@types/prismjs@1.26.5':
|
||||
resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==}
|
||||
|
||||
'@types/prop-types@15.7.15':
|
||||
resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
|
||||
|
||||
@@ -3740,9 +3724,6 @@ packages:
|
||||
camelize@1.0.1:
|
||||
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
|
||||
|
||||
caniuse-lite@1.0.30001735:
|
||||
resolution: {integrity: sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==}
|
||||
|
||||
caniuse-lite@1.0.30001741:
|
||||
resolution: {integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==}
|
||||
|
||||
@@ -4108,15 +4089,6 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.4.1:
|
||||
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.4.3:
|
||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -6220,11 +6192,6 @@ packages:
|
||||
resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
|
||||
prism-react-renderer@2.4.1:
|
||||
resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==}
|
||||
peerDependencies:
|
||||
react: '>=16.0.0'
|
||||
|
||||
process-nextick-args@2.0.1:
|
||||
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
|
||||
|
||||
@@ -6949,11 +6916,11 @@ packages:
|
||||
tailwind-merge@2.6.0:
|
||||
resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==}
|
||||
|
||||
tailwind-scrollbar@4.0.2:
|
||||
resolution: {integrity: sha512-wAQiIxAPqk0MNTPptVe/xoyWi27y+NRGnTwvn4PQnbvB9kp8QUBiGl/wsfoVBHnQxTmhXJSNt9NHTmcz9EivFA==}
|
||||
tailwind-scrollbar@3.1.0:
|
||||
resolution: {integrity: sha512-pmrtDIZeHyu2idTejfV59SbaJyvp1VRjYxAjZBH0jnyrPRo6HL1kD5Glz8VPagasqr6oAx6M05+Tuw429Z8jxg==}
|
||||
engines: {node: '>=12.13.0'}
|
||||
peerDependencies:
|
||||
tailwindcss: 4.x
|
||||
tailwindcss: 3.x
|
||||
|
||||
tailwindcss-animate@1.0.7:
|
||||
resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
|
||||
@@ -7567,7 +7534,7 @@ snapshots:
|
||||
'@babel/types': 7.28.4
|
||||
'@jridgewell/remapping': 2.3.5
|
||||
convert-source-map: 2.0.0
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
gensync: 1.0.0-beta.2
|
||||
json5: 2.2.3
|
||||
semver: 6.3.1
|
||||
@@ -7619,7 +7586,7 @@ snapshots:
|
||||
'@babel/core': 7.28.4
|
||||
'@babel/helper-compilation-targets': 7.27.2
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
lodash.debounce: 4.0.8
|
||||
resolve: 1.22.10
|
||||
transitivePeerDependencies:
|
||||
@@ -8270,8 +8237,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/runtime@7.28.3': {}
|
||||
|
||||
'@babel/runtime@7.28.4': {}
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
@@ -8288,7 +8253,7 @@ snapshots:
|
||||
'@babel/parser': 7.28.4
|
||||
'@babel/template': 7.27.2
|
||||
'@babel/types': 7.28.4
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -8325,11 +8290,6 @@ snapshots:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@emnapi/runtime@1.4.5':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@emnapi/runtime@1.5.0':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -8426,11 +8386,6 @@ snapshots:
|
||||
'@esbuild/win32-x64@0.25.9':
|
||||
optional: true
|
||||
|
||||
'@eslint-community/eslint-utils@4.7.0(eslint@8.57.1)':
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.9.0(eslint@8.57.1)':
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
@@ -8441,7 +8396,7 @@ snapshots:
|
||||
'@eslint/eslintrc@2.1.4':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
espree: 9.6.1
|
||||
globals: 13.24.0
|
||||
ignore: 5.3.2
|
||||
@@ -8491,7 +8446,7 @@ snapshots:
|
||||
'@humanwhocodes/config-array@0.13.0':
|
||||
dependencies:
|
||||
'@humanwhocodes/object-schema': 2.0.3
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
minimatch: 3.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -8592,7 +8547,7 @@ snapshots:
|
||||
|
||||
'@img/sharp-wasm32@0.34.3':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.4.5
|
||||
'@emnapi/runtime': 1.5.0
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-arm64@0.34.3':
|
||||
@@ -9041,7 +8996,7 @@ snapshots:
|
||||
ajv: 8.17.1
|
||||
chalk: 4.1.2
|
||||
compare-versions: 6.1.1
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
esbuild: 0.25.9
|
||||
esutils: 2.0.3
|
||||
fs-extra: 11.3.1
|
||||
@@ -10373,7 +10328,7 @@ snapshots:
|
||||
|
||||
'@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.9.2)(webpack@5.101.3(esbuild@0.25.9))':
|
||||
dependencies:
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
endent: 2.1.0
|
||||
find-cache-dir: 3.3.2
|
||||
flat-cache: 3.2.0
|
||||
@@ -10460,19 +10415,19 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@tanstack/query-core@5.85.3': {}
|
||||
'@tanstack/query-core@5.87.1': {}
|
||||
|
||||
'@tanstack/query-devtools@5.87.3': {}
|
||||
|
||||
'@tanstack/react-query-devtools@5.87.3(@tanstack/react-query@5.85.3(react@18.3.1))(react@18.3.1)':
|
||||
'@tanstack/react-query-devtools@5.87.3(@tanstack/react-query@5.87.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/query-devtools': 5.87.3
|
||||
'@tanstack/react-query': 5.85.3(react@18.3.1)
|
||||
'@tanstack/react-query': 5.87.1(react@18.3.1)
|
||||
react: 18.3.1
|
||||
|
||||
'@tanstack/react-query@5.85.3(react@18.3.1)':
|
||||
'@tanstack/react-query@5.87.1(react@18.3.1)':
|
||||
dependencies:
|
||||
'@tanstack/query-core': 5.85.3
|
||||
'@tanstack/query-core': 5.87.1
|
||||
react: 18.3.1
|
||||
|
||||
'@tanstack/react-table@8.21.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
@@ -10664,8 +10619,6 @@ snapshots:
|
||||
|
||||
'@types/phoenix@1.6.6': {}
|
||||
|
||||
'@types/prismjs@1.26.5': {}
|
||||
|
||||
'@types/prop-types@15.7.15': {}
|
||||
|
||||
'@types/react-dom@18.3.5(@types/react@18.3.17)':
|
||||
@@ -10734,7 +10687,7 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/visitor-keys': 8.43.0
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
eslint: 8.57.1
|
||||
typescript: 5.9.2
|
||||
transitivePeerDependencies:
|
||||
@@ -10744,7 +10697,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
typescript: 5.9.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -10763,7 +10716,7 @@ snapshots:
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
'@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/utils': 8.43.0(eslint@8.57.1)(typescript@5.9.2)
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
eslint: 8.57.1
|
||||
ts-api-utils: 2.1.0(typescript@5.9.2)
|
||||
typescript: 5.9.2
|
||||
@@ -10778,7 +10731,7 @@ snapshots:
|
||||
'@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2)
|
||||
'@typescript-eslint/types': 8.43.0
|
||||
'@typescript-eslint/visitor-keys': 8.43.0
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
fast-glob: 3.3.3
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.5
|
||||
@@ -11395,8 +11348,6 @@ snapshots:
|
||||
|
||||
camelize@1.0.1: {}
|
||||
|
||||
caniuse-lite@1.0.30001735: {}
|
||||
|
||||
caniuse-lite@1.0.30001741: {}
|
||||
|
||||
case-sensitive-paths-webpack-plugin@2.4.0: {}
|
||||
@@ -11598,7 +11549,7 @@ snapshots:
|
||||
dependencies:
|
||||
cipher-base: 1.0.6
|
||||
inherits: 2.0.4
|
||||
ripemd160: 2.0.1
|
||||
ripemd160: 2.0.2
|
||||
sha.js: 2.4.12
|
||||
|
||||
create-hash@1.2.0:
|
||||
@@ -11612,9 +11563,9 @@ snapshots:
|
||||
create-hmac@1.1.7:
|
||||
dependencies:
|
||||
cipher-base: 1.0.6
|
||||
create-hash: 1.1.3
|
||||
create-hash: 1.2.0
|
||||
inherits: 2.0.4
|
||||
ripemd160: 2.0.1
|
||||
ripemd160: 2.0.2
|
||||
safe-buffer: 5.2.1
|
||||
sha.js: 2.4.12
|
||||
|
||||
@@ -11772,10 +11723,6 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.1:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.3:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
@@ -12077,7 +12024,7 @@ snapshots:
|
||||
|
||||
esbuild-register@3.6.0(esbuild@0.25.9):
|
||||
dependencies:
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
esbuild: 0.25.9
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -12148,7 +12095,7 @@ snapshots:
|
||||
eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@8.57.1):
|
||||
dependencies:
|
||||
'@nolyfill/is-core-module': 1.0.39
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
eslint: 8.57.1
|
||||
get-tsconfig: 4.10.1
|
||||
is-bun-module: 2.0.0
|
||||
@@ -12270,7 +12217,7 @@ snapshots:
|
||||
|
||||
eslint@8.57.1:
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1)
|
||||
'@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1)
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint/eslintrc': 2.1.4
|
||||
'@eslint/js': 8.57.1
|
||||
@@ -12281,7 +12228,7 @@ snapshots:
|
||||
ajv: 6.12.6
|
||||
chalk: 4.1.2
|
||||
cross-spawn: 7.0.6
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
doctrine: 3.0.0
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint-scope: 7.2.2
|
||||
@@ -13654,7 +13601,7 @@ snapshots:
|
||||
micromark@4.0.2:
|
||||
dependencies:
|
||||
'@types/debug': 4.1.12
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
decode-named-character-reference: 1.2.0
|
||||
devlop: 1.1.0
|
||||
micromark-core-commonmark: 2.0.3
|
||||
@@ -13790,7 +13737,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@next/env': 15.4.7
|
||||
'@swc/helpers': 0.5.15
|
||||
caniuse-lite: 1.0.30001735
|
||||
caniuse-lite: 1.0.30001741
|
||||
postcss: 8.4.31
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
@@ -14311,12 +14258,6 @@ snapshots:
|
||||
ansi-styles: 5.2.0
|
||||
react-is: 17.0.2
|
||||
|
||||
prism-react-renderer@2.4.1(react@18.3.1):
|
||||
dependencies:
|
||||
'@types/prismjs': 1.26.5
|
||||
clsx: 2.1.1
|
||||
react: 18.3.1
|
||||
|
||||
process-nextick-args@2.0.1: {}
|
||||
|
||||
process@0.11.10: {}
|
||||
@@ -14495,7 +14436,7 @@ snapshots:
|
||||
|
||||
react-window@1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@babel/runtime': 7.28.4
|
||||
memoize-one: 5.2.1
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
@@ -14716,7 +14657,7 @@ snapshots:
|
||||
|
||||
require-in-the-middle@7.5.2:
|
||||
dependencies:
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
module-details-from-path: 1.0.4
|
||||
resolve: 1.22.10
|
||||
transitivePeerDependencies:
|
||||
@@ -15259,12 +15200,9 @@ snapshots:
|
||||
|
||||
tailwind-merge@2.6.0: {}
|
||||
|
||||
tailwind-scrollbar@4.0.2(react@18.3.1)(tailwindcss@3.4.17):
|
||||
tailwind-scrollbar@3.1.0(tailwindcss@3.4.17):
|
||||
dependencies:
|
||||
prism-react-renderer: 2.4.1(react@18.3.1)
|
||||
tailwindcss: 3.4.17
|
||||
transitivePeerDependencies:
|
||||
- react
|
||||
|
||||
tailwindcss-animate@1.0.7(tailwindcss@3.4.17):
|
||||
dependencies:
|
||||
|
||||
@@ -10,9 +10,9 @@ import OnboardingAgentCard from "../components/OnboardingAgentCard";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
import { StoreAgentDetails } from "@/lib/autogpt-server-api";
|
||||
import { finishOnboarding } from "../6-congrats/actions";
|
||||
import { isEmptyOrWhitespace } from "@/lib/utils";
|
||||
import { useOnboarding } from "../../../../providers/onboarding/onboarding-provider";
|
||||
import { finishOnboarding } from "../6-congrats/actions";
|
||||
|
||||
export default function Page() {
|
||||
const { state, updateState } = useOnboarding(4, "INTEGRATIONS");
|
||||
@@ -24,6 +24,7 @@ export default function Page() {
|
||||
if (agents.length < 2) {
|
||||
finishOnboarding();
|
||||
}
|
||||
|
||||
setAgents(agents);
|
||||
});
|
||||
}, [api, setAgents]);
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import { CredentialsInput } from "@/app/(platform)/library/agents/[id]/components/AgentRunsView/components/CredentialsInputs/CredentialsInputs";
|
||||
import { CredentialsMetaInput } from "@/app/api/__generated__/models/credentialsMetaInput";
|
||||
import { GraphMeta } from "@/app/api/__generated__/models/graphMeta";
|
||||
import { useState } from "react";
|
||||
import { getSchemaDefaultCredentials } from "../../helpers";
|
||||
import { areAllCredentialsSet, getCredentialFields } from "./helpers";
|
||||
|
||||
type Credential = CredentialsMetaInput | undefined;
|
||||
type Credentials = Record<string, Credential>;
|
||||
|
||||
type Props = {
|
||||
agent: GraphMeta | null;
|
||||
siblingInputs?: Record<string, any>;
|
||||
onCredentialsChange: (
|
||||
credentials: Record<string, CredentialsMetaInput>,
|
||||
) => void;
|
||||
onValidationChange: (isValid: boolean) => void;
|
||||
onLoadingChange: (isLoading: boolean) => void;
|
||||
};
|
||||
|
||||
export function AgentOnboardingCredentials(props: Props) {
|
||||
const [inputCredentials, setInputCredentials] = useState<Credentials>({});
|
||||
|
||||
const fields = getCredentialFields(props.agent);
|
||||
const required = Object.keys(fields || {}).length > 0;
|
||||
|
||||
if (!required) return null;
|
||||
|
||||
function handleSelectCredentials(key: string, value: Credential) {
|
||||
const updated = { ...inputCredentials, [key]: value };
|
||||
setInputCredentials(updated);
|
||||
|
||||
const sanitized: Record<string, CredentialsMetaInput> = {};
|
||||
for (const [k, v] of Object.entries(updated)) {
|
||||
if (v) sanitized[k] = v;
|
||||
}
|
||||
|
||||
props.onCredentialsChange(sanitized);
|
||||
|
||||
const isValid = !required || areAllCredentialsSet(fields, updated);
|
||||
props.onValidationChange(isValid);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{Object.entries(fields).map(([key, inputSubSchema]) => (
|
||||
<div key={key} className="mt-4">
|
||||
<CredentialsInput
|
||||
schema={inputSubSchema}
|
||||
selectedCredentials={
|
||||
inputCredentials[key] ??
|
||||
getSchemaDefaultCredentials(inputSubSchema)
|
||||
}
|
||||
onSelectCredentials={(value) => handleSelectCredentials(key, value)}
|
||||
siblingInputs={props.siblingInputs}
|
||||
onLoaded={(loaded) => props.onLoadingChange(!loaded)}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { CredentialsMetaInput } from "@/app/api/__generated__/models/credentialsMetaInput";
|
||||
import { GraphMeta } from "@/app/api/__generated__/models/graphMeta";
|
||||
import { BlockIOCredentialsSubSchema } from "@/lib/autogpt-server-api/types";
|
||||
|
||||
export function getCredentialFields(
|
||||
agent: GraphMeta | null,
|
||||
): AgentCredentialsFields {
|
||||
if (!agent) return {};
|
||||
|
||||
const hasNoInputs =
|
||||
!agent.credentials_input_schema ||
|
||||
typeof agent.credentials_input_schema !== "object" ||
|
||||
!("properties" in agent.credentials_input_schema) ||
|
||||
!agent.credentials_input_schema.properties;
|
||||
|
||||
if (hasNoInputs) return {};
|
||||
|
||||
return agent.credentials_input_schema.properties as AgentCredentialsFields;
|
||||
}
|
||||
|
||||
export type AgentCredentialsFields = Record<
|
||||
string,
|
||||
BlockIOCredentialsSubSchema
|
||||
>;
|
||||
|
||||
export function areAllCredentialsSet(
|
||||
fields: AgentCredentialsFields,
|
||||
inputs: Record<string, CredentialsMetaInput | undefined>,
|
||||
) {
|
||||
const required = Object.keys(fields || {});
|
||||
return required.every((k) => Boolean(inputs[k]));
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { OnboardingText } from "../../components/OnboardingText";
|
||||
|
||||
type RunAgentHintProps = {
|
||||
handleNewRun: () => void;
|
||||
};
|
||||
|
||||
export function RunAgentHint(props: RunAgentHintProps) {
|
||||
return (
|
||||
<div className="ml-[104px] w-[481px] pl-5">
|
||||
<div className="flex flex-col">
|
||||
<OnboardingText variant="header">Run your first agent</OnboardingText>
|
||||
<span className="mt-9 text-base font-normal leading-normal text-zinc-600">
|
||||
A 'run' is when your agent starts working on a task
|
||||
</span>
|
||||
<span className="mt-4 text-base font-normal leading-normal text-zinc-600">
|
||||
Click on <b>New Run</b> below to try it out
|
||||
</span>
|
||||
|
||||
<div
|
||||
onClick={props.handleNewRun}
|
||||
className={cn(
|
||||
"mt-16 flex h-[68px] w-[330px] items-center justify-center rounded-xl border-2 border-violet-700 bg-neutral-50",
|
||||
"cursor-pointer transition-all duration-200 ease-in-out hover:bg-violet-50",
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
width="38"
|
||||
height="38"
|
||||
viewBox="0 0 32 32"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g stroke="#6d28d9" strokeWidth="1.2" strokeLinecap="round">
|
||||
<line x1="16" y1="8" x2="16" y2="24" />
|
||||
<line x1="8" y1="16" x2="24" y2="16" />
|
||||
</g>
|
||||
</svg>
|
||||
<span className="ml-3 font-sans text-[19px] font-medium leading-normal text-violet-700">
|
||||
New run
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { StoreAgentDetails } from "@/app/api/__generated__/models/storeAgentDetails";
|
||||
import StarRating from "../../components/StarRating";
|
||||
import SmartImage from "@/components/__legacy__/SmartImage";
|
||||
|
||||
type Props = {
|
||||
storeAgent: StoreAgentDetails | null;
|
||||
};
|
||||
|
||||
export function SelectedAgentCard(props: Props) {
|
||||
return (
|
||||
<div className="fixed left-1/4 top-1/2 w-[481px] -translate-x-1/2 -translate-y-1/2">
|
||||
<div className="h-[156px] w-[481px] rounded-xl bg-white px-6 pb-5 pt-4">
|
||||
<span className="font-sans text-xs font-medium tracking-wide text-zinc-500">
|
||||
SELECTED AGENT
|
||||
</span>
|
||||
{props.storeAgent ? (
|
||||
<div className="mt-4 flex h-20 rounded-lg bg-violet-50 p-3">
|
||||
{/* Left image */}
|
||||
<SmartImage
|
||||
src={props.storeAgent.agent_image[0]}
|
||||
alt="Agent cover"
|
||||
className="w-[350px] rounded-lg"
|
||||
/>
|
||||
{/* Right content */}
|
||||
<div className="ml-3 flex flex-1 flex-col">
|
||||
<div className="mb-2 flex flex-col items-start">
|
||||
<span className="w-[292px] truncate font-sans text-[14px] font-medium leading-tight text-zinc-800">
|
||||
{props.storeAgent.agent_name}
|
||||
</span>
|
||||
<span className="font-norma w-[292px] truncate font-sans text-xs text-zinc-600">
|
||||
by {props.storeAgent.creator}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex w-[292px] items-center justify-between">
|
||||
<span className="truncate font-sans text-xs font-normal leading-tight text-zinc-600">
|
||||
{props.storeAgent.runs.toLocaleString("en-US")} runs
|
||||
</span>
|
||||
<StarRating
|
||||
className="font-sans text-xs font-normal leading-tight text-zinc-600"
|
||||
starSize={12}
|
||||
rating={props.storeAgent.rating || 0}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-4 flex h-20 animate-pulse rounded-lg bg-gray-300 p-2" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { GraphMeta } from "@/lib/autogpt-server-api";
|
||||
import type {
|
||||
BlockIOCredentialsSubSchema,
|
||||
CredentialsMetaInput,
|
||||
} from "@/lib/autogpt-server-api/types";
|
||||
import type { InputValues } from "./types";
|
||||
import { GraphMeta } from "@/app/api/__generated__/models/graphMeta";
|
||||
|
||||
export function computeInitialAgentInputs(
|
||||
agent: GraphMeta | null,
|
||||
@@ -21,7 +21,6 @@ export function computeInitialAgentInputs(
|
||||
result[key] = existingInputs[key];
|
||||
return;
|
||||
}
|
||||
// GraphIOSubSchema.default is typed as string, but server may return other primitives
|
||||
const def = (subSchema as unknown as { default?: string | number }).default;
|
||||
result[key] = def ?? "";
|
||||
});
|
||||
@@ -29,40 +28,20 @@ export function computeInitialAgentInputs(
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getAgentCredentialsInputFields(agent: GraphMeta | null) {
|
||||
const hasNoInputs =
|
||||
!agent?.credentials_input_schema ||
|
||||
typeof agent.credentials_input_schema !== "object" ||
|
||||
!("properties" in agent.credentials_input_schema) ||
|
||||
!agent.credentials_input_schema.properties;
|
||||
|
||||
if (hasNoInputs) return {};
|
||||
|
||||
return agent.credentials_input_schema.properties;
|
||||
}
|
||||
|
||||
export function areAllCredentialsSet(
|
||||
fields: Record<string, BlockIOCredentialsSubSchema>,
|
||||
inputs: Record<string, CredentialsMetaInput | undefined>,
|
||||
) {
|
||||
const required = Object.keys(fields || {});
|
||||
return required.every((k) => Boolean(inputs[k]));
|
||||
}
|
||||
|
||||
type IsRunDisabledParams = {
|
||||
agent: GraphMeta | null;
|
||||
isRunning: boolean;
|
||||
agentInputs: InputValues | null | undefined;
|
||||
credentialsRequired: boolean;
|
||||
credentialsSatisfied: boolean;
|
||||
credentialsValid: boolean;
|
||||
credentialsLoaded: boolean;
|
||||
};
|
||||
|
||||
export function isRunDisabled({
|
||||
agent,
|
||||
isRunning,
|
||||
agentInputs,
|
||||
credentialsRequired,
|
||||
credentialsSatisfied,
|
||||
credentialsValid,
|
||||
credentialsLoaded,
|
||||
}: IsRunDisabledParams) {
|
||||
const hasEmptyInput = Object.values(agentInputs || {}).some(
|
||||
(value) => String(value).trim() === "",
|
||||
@@ -71,7 +50,8 @@ export function isRunDisabled({
|
||||
if (hasEmptyInput) return true;
|
||||
if (!agent) return true;
|
||||
if (isRunning) return true;
|
||||
if (credentialsRequired && !credentialsSatisfied) return true;
|
||||
if (!credentialsValid) return true;
|
||||
if (!credentialsLoaded) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -81,13 +61,3 @@ export function getSchemaDefaultCredentials(
|
||||
): CredentialsMetaInput | undefined {
|
||||
return schema.default as CredentialsMetaInput | undefined;
|
||||
}
|
||||
|
||||
export function sanitizeCredentials(
|
||||
map: Record<string, CredentialsMetaInput | undefined>,
|
||||
): Record<string, CredentialsMetaInput> {
|
||||
const sanitized: Record<string, CredentialsMetaInput> = {};
|
||||
for (const [key, value] of Object.entries(map)) {
|
||||
if (value) sanitized[key] = value;
|
||||
}
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
@@ -1,224 +1,66 @@
|
||||
"use client";
|
||||
import SmartImage from "@/components/__legacy__/SmartImage";
|
||||
import { useOnboarding } from "../../../../providers/onboarding/onboarding-provider";
|
||||
|
||||
import OnboardingButton from "../components/OnboardingButton";
|
||||
import { OnboardingHeader, OnboardingStep } from "../components/OnboardingStep";
|
||||
import { OnboardingText } from "../components/OnboardingText";
|
||||
import StarRating from "../components/StarRating";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/__legacy__/ui/card";
|
||||
import { useToast } from "@/components/molecules/Toast/use-toast";
|
||||
import { GraphMeta, StoreAgentDetails } from "@/lib/autogpt-server-api";
|
||||
import type { InputValues } from "./types";
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Play } from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { RunAgentInputs } from "@/app/(platform)/library/agents/[id]/components/AgentRunsView/components/RunAgentInputs/RunAgentInputs";
|
||||
import { InformationTooltip } from "@/components/molecules/InformationTooltip/InformationTooltip";
|
||||
import { CredentialsInput } from "@/app/(platform)/library/agents/[id]/components/AgentRunsView/components/CredentialsInputs/CredentialsInputs";
|
||||
import type { CredentialsMetaInput } from "@/lib/autogpt-server-api/types";
|
||||
import {
|
||||
areAllCredentialsSet,
|
||||
computeInitialAgentInputs,
|
||||
getAgentCredentialsInputFields,
|
||||
isRunDisabled,
|
||||
getSchemaDefaultCredentials,
|
||||
sanitizeCredentials,
|
||||
} from "./helpers";
|
||||
import { isRunDisabled } from "./helpers";
|
||||
import { useOnboardingRunStep } from "./useOnboardingRunStep";
|
||||
import { RunAgentHint } from "./components/RunAgentHint";
|
||||
import { SelectedAgentCard } from "./components/SelectedAgentCard";
|
||||
import { AgentOnboardingCredentials } from "./components/AgentOnboardingCredentials/AgentOnboardingCredentials";
|
||||
import { ErrorCard } from "@/components/molecules/ErrorCard/ErrorCard";
|
||||
import { Skeleton } from "@/components/__legacy__/ui/skeleton";
|
||||
|
||||
export default function Page() {
|
||||
const { state, updateState, setStep } = useOnboarding(
|
||||
undefined,
|
||||
"AGENT_CHOICE",
|
||||
);
|
||||
const [showInput, setShowInput] = useState(false);
|
||||
const [agent, setAgent] = useState<GraphMeta | null>(null);
|
||||
const [storeAgent, setStoreAgent] = useState<StoreAgentDetails | null>(null);
|
||||
const [runningAgent, setRunningAgent] = useState(false);
|
||||
const [inputCredentials, setInputCredentials] = useState<
|
||||
Record<string, CredentialsMetaInput | undefined>
|
||||
>({});
|
||||
const { toast } = useToast();
|
||||
const router = useRouter();
|
||||
const api = useBackendAPI();
|
||||
const {
|
||||
ready,
|
||||
error,
|
||||
showInput,
|
||||
agent,
|
||||
onboarding,
|
||||
storeAgent,
|
||||
runningAgent,
|
||||
credentialsValid,
|
||||
credentialsLoaded,
|
||||
handleSetAgentInput,
|
||||
handleRunAgent,
|
||||
handleNewRun,
|
||||
handleCredentialsChange,
|
||||
handleCredentialsValidationChange,
|
||||
handleCredentialsLoadingChange,
|
||||
} = useOnboardingRunStep();
|
||||
|
||||
useEffect(() => {
|
||||
setStep(5);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!state?.selectedStoreListingVersionId) {
|
||||
return;
|
||||
}
|
||||
api
|
||||
.getStoreAgentByVersionId(state?.selectedStoreListingVersionId)
|
||||
.then((storeAgent) => {
|
||||
setStoreAgent(storeAgent);
|
||||
});
|
||||
api
|
||||
.getGraphMetaByStoreListingVersionID(state.selectedStoreListingVersionId)
|
||||
.then((meta) => {
|
||||
setAgent(meta);
|
||||
const update = computeInitialAgentInputs(
|
||||
meta,
|
||||
(state.agentInput as unknown as InputValues) || null,
|
||||
);
|
||||
updateState({ agentInput: update });
|
||||
});
|
||||
}, [api, setAgent, updateState, state?.selectedStoreListingVersionId]);
|
||||
|
||||
const agentCredentialsInputFields = getAgentCredentialsInputFields(agent);
|
||||
|
||||
const credentialsRequired =
|
||||
Object.keys(agentCredentialsInputFields || {}).length > 0;
|
||||
|
||||
const allCredentialsAreSet = areAllCredentialsSet(
|
||||
agentCredentialsInputFields,
|
||||
inputCredentials,
|
||||
);
|
||||
|
||||
function setAgentInput(key: string, value: string) {
|
||||
updateState({
|
||||
agentInput: {
|
||||
...state?.agentInput,
|
||||
[key]: value,
|
||||
},
|
||||
});
|
||||
if (error) {
|
||||
return <ErrorCard responseError={error} />;
|
||||
}
|
||||
|
||||
async function runAgent() {
|
||||
if (!agent) {
|
||||
return;
|
||||
}
|
||||
setRunningAgent(true);
|
||||
try {
|
||||
const libraryAgent = await api.addMarketplaceAgentToLibrary(
|
||||
storeAgent?.store_listing_version_id || "",
|
||||
);
|
||||
const { id: runID } = await api.executeGraph(
|
||||
libraryAgent.graph_id,
|
||||
libraryAgent.graph_version,
|
||||
state?.agentInput || {},
|
||||
sanitizeCredentials(inputCredentials),
|
||||
);
|
||||
updateState({
|
||||
onboardingAgentExecutionId: runID,
|
||||
agentRuns: (state?.agentRuns || 0) + 1,
|
||||
});
|
||||
router.push("/onboarding/6-congrats");
|
||||
} catch (error) {
|
||||
console.error("Error running agent:", error);
|
||||
toast({
|
||||
title: "Error running agent",
|
||||
description:
|
||||
"There was an error running your agent. Please try again or try choosing a different agent if it still fails.",
|
||||
variant: "destructive",
|
||||
});
|
||||
setRunningAgent(false);
|
||||
}
|
||||
}
|
||||
|
||||
const runYourAgent = (
|
||||
<div className="ml-[104px] w-[481px] pl-5">
|
||||
<div className="flex flex-col">
|
||||
<OnboardingText variant="header">Run your first agent</OnboardingText>
|
||||
<span className="mt-9 text-base font-normal leading-normal text-zinc-600">
|
||||
A 'run' is when your agent starts working on a task
|
||||
</span>
|
||||
<span className="mt-4 text-base font-normal leading-normal text-zinc-600">
|
||||
Click on <b>New Run</b> below to try it out
|
||||
</span>
|
||||
|
||||
<div
|
||||
onClick={() => {
|
||||
setShowInput(true);
|
||||
setStep(6);
|
||||
updateState({
|
||||
completedSteps: [
|
||||
...(state?.completedSteps || []),
|
||||
"AGENT_NEW_RUN",
|
||||
],
|
||||
});
|
||||
}}
|
||||
className={cn(
|
||||
"mt-16 flex h-[68px] w-[330px] items-center justify-center rounded-xl border-2 border-violet-700 bg-neutral-50",
|
||||
"cursor-pointer transition-all duration-200 ease-in-out hover:bg-violet-50",
|
||||
)}
|
||||
>
|
||||
<svg
|
||||
width="38"
|
||||
height="38"
|
||||
viewBox="0 0 32 32"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g stroke="#6d28d9" strokeWidth="1.2" strokeLinecap="round">
|
||||
<line x1="16" y1="8" x2="16" y2="24" />
|
||||
<line x1="8" y1="16" x2="24" y2="16" />
|
||||
</g>
|
||||
</svg>
|
||||
<span className="ml-3 font-sans text-[19px] font-medium leading-normal text-violet-700">
|
||||
New run
|
||||
</span>
|
||||
</div>
|
||||
if (!ready) {
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
<Skeleton className="h-10 w-full" />
|
||||
<Skeleton className="h-10 w-full" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<OnboardingStep dotted>
|
||||
<OnboardingHeader backHref={"/onboarding/4-agent"} transparent />
|
||||
{/* Agent card */}
|
||||
<div className="fixed left-1/4 top-1/2 w-[481px] -translate-x-1/2 -translate-y-1/2">
|
||||
<div className="h-[156px] w-[481px] rounded-xl bg-white px-6 pb-5 pt-4">
|
||||
<span className="font-sans text-xs font-medium tracking-wide text-zinc-500">
|
||||
SELECTED AGENT
|
||||
</span>
|
||||
{storeAgent ? (
|
||||
<div className="mt-4 flex h-20 rounded-lg bg-violet-50 p-2">
|
||||
{/* Left image */}
|
||||
<SmartImage
|
||||
src={storeAgent?.agent_image[0]}
|
||||
alt="Agent cover"
|
||||
imageContain
|
||||
className="w-[350px] rounded-lg"
|
||||
/>
|
||||
{/* Right content */}
|
||||
<div className="ml-2 flex flex-1 flex-col">
|
||||
<span className="w-[292px] truncate font-sans text-[14px] font-medium leading-normal text-zinc-800">
|
||||
{storeAgent?.agent_name}
|
||||
</span>
|
||||
<span className="mt-[5px] w-[292px] truncate font-sans text-xs font-normal leading-tight text-zinc-600">
|
||||
by {storeAgent?.creator}
|
||||
</span>
|
||||
<div className="mt-auto flex w-[292px] justify-between">
|
||||
<span className="mt-1 truncate font-sans text-xs font-normal leading-tight text-zinc-600">
|
||||
{storeAgent?.runs.toLocaleString("en-US")} runs
|
||||
</span>
|
||||
<StarRating
|
||||
className="font-sans text-xs font-normal leading-tight text-zinc-600"
|
||||
starSize={12}
|
||||
rating={storeAgent?.rating || 0}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-4 flex h-20 animate-pulse rounded-lg bg-gray-300 p-2" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex min-h-[80vh] items-center justify-center">
|
||||
{/* Left side */}
|
||||
<SelectedAgentCard storeAgent={storeAgent} />
|
||||
<div className="w-[481px]" />
|
||||
{/* Right side */}
|
||||
{!showInput ? (
|
||||
runYourAgent
|
||||
<RunAgentHint handleNewRun={handleNewRun} />
|
||||
) : (
|
||||
<div className="ml-[104px] w-[481px] pl-5">
|
||||
<div className="flex flex-col">
|
||||
@@ -232,30 +74,7 @@ export default function Page() {
|
||||
<span className="mt-4 text-base font-normal leading-normal text-zinc-600">
|
||||
When you're done, click <b>Run Agent</b>.
|
||||
</span>
|
||||
{Object.entries(agentCredentialsInputFields || {}).map(
|
||||
([key, inputSubSchema]) => (
|
||||
<div key={key} className="mt-4">
|
||||
<CredentialsInput
|
||||
schema={inputSubSchema}
|
||||
selectedCredentials={
|
||||
inputCredentials[key] ??
|
||||
getSchemaDefaultCredentials(inputSubSchema)
|
||||
}
|
||||
onSelectCredentials={(value) =>
|
||||
setInputCredentials((prev) => ({
|
||||
...prev,
|
||||
[key]: value,
|
||||
}))
|
||||
}
|
||||
siblingInputs={
|
||||
(state?.agentInput || undefined) as
|
||||
| Record<string, any>
|
||||
| undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
|
||||
<Card className="agpt-box mt-4">
|
||||
<CardHeader>
|
||||
<CardTitle className="font-poppins text-lg">Input</CardTitle>
|
||||
@@ -272,13 +91,23 @@ export default function Page() {
|
||||
</label>
|
||||
<RunAgentInputs
|
||||
schema={inputSubSchema}
|
||||
value={state?.agentInput?.[key]}
|
||||
value={onboarding.state?.agentInput?.[key]}
|
||||
placeholder={inputSubSchema.description}
|
||||
onChange={(value) => setAgentInput(key, value)}
|
||||
onChange={(value) => handleSetAgentInput(key, value)}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
<AgentOnboardingCredentials
|
||||
agent={agent}
|
||||
siblingInputs={
|
||||
(onboarding.state?.agentInput as Record<string, any>) ||
|
||||
undefined
|
||||
}
|
||||
onCredentialsChange={handleCredentialsChange}
|
||||
onValidationChange={handleCredentialsValidationChange}
|
||||
onLoadingChange={handleCredentialsLoadingChange}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<OnboardingButton
|
||||
@@ -289,11 +118,12 @@ export default function Page() {
|
||||
agent,
|
||||
isRunning: runningAgent,
|
||||
agentInputs:
|
||||
(state?.agentInput as unknown as InputValues) || null,
|
||||
credentialsRequired,
|
||||
credentialsSatisfied: allCredentialsAreSet,
|
||||
(onboarding.state?.agentInput as unknown as InputValues) ||
|
||||
null,
|
||||
credentialsValid,
|
||||
credentialsLoaded,
|
||||
})}
|
||||
onClick={runAgent}
|
||||
onClick={handleRunAgent}
|
||||
icon={<Play className="mr-2" size={18} />}
|
||||
>
|
||||
Run agent
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
import { CredentialsMetaInput } from "@/app/api/__generated__/models/credentialsMetaInput";
|
||||
import { GraphMeta } from "@/app/api/__generated__/models/graphMeta";
|
||||
import { StoreAgentDetails } from "@/app/api/__generated__/models/storeAgentDetails";
|
||||
import { useToast } from "@/components/molecules/Toast/use-toast";
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
import { useOnboarding } from "@/providers/onboarding/onboarding-provider";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { computeInitialAgentInputs } from "./helpers";
|
||||
import { InputValues } from "./types";
|
||||
import {
|
||||
useGetV2GetAgentByVersion,
|
||||
useGetV2GetAgentGraph,
|
||||
} from "@/app/api/__generated__/endpoints/store/store";
|
||||
|
||||
export function useOnboardingRunStep() {
|
||||
const onboarding = useOnboarding(undefined, "AGENT_CHOICE");
|
||||
|
||||
const [showInput, setShowInput] = useState(false);
|
||||
const [agent, setAgent] = useState<GraphMeta | null>(null);
|
||||
const [storeAgent, setStoreAgent] = useState<StoreAgentDetails | null>(null);
|
||||
const [runningAgent, setRunningAgent] = useState(false);
|
||||
|
||||
const [inputCredentials, setInputCredentials] = useState<
|
||||
Record<string, CredentialsMetaInput>
|
||||
>({});
|
||||
|
||||
const [credentialsValid, setCredentialsValid] = useState(true);
|
||||
const [credentialsLoaded, setCredentialsLoaded] = useState(false);
|
||||
|
||||
const { toast } = useToast();
|
||||
const router = useRouter();
|
||||
const api = useBackendAPI();
|
||||
|
||||
const currentAgentVersion =
|
||||
onboarding.state?.selectedStoreListingVersionId ?? "";
|
||||
|
||||
const storeAgentQuery = useGetV2GetAgentByVersion(currentAgentVersion, {
|
||||
query: { enabled: !!currentAgentVersion },
|
||||
});
|
||||
|
||||
const graphMetaQuery = useGetV2GetAgentGraph(currentAgentVersion, {
|
||||
query: { enabled: !!currentAgentVersion },
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
onboarding.setStep(5);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (storeAgentQuery.data && storeAgentQuery.data.status === 200) {
|
||||
setStoreAgent(storeAgentQuery.data.data);
|
||||
}
|
||||
}, [storeAgentQuery.data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
graphMetaQuery.data &&
|
||||
graphMetaQuery.data.status === 200 &&
|
||||
onboarding.state
|
||||
) {
|
||||
const graphMeta = graphMetaQuery.data.data as GraphMeta;
|
||||
|
||||
setAgent(graphMeta);
|
||||
|
||||
const update = computeInitialAgentInputs(
|
||||
graphMeta,
|
||||
(onboarding.state.agentInput as unknown as InputValues) || null,
|
||||
);
|
||||
|
||||
onboarding.updateState({ agentInput: update });
|
||||
}
|
||||
}, [graphMetaQuery.data]);
|
||||
|
||||
function handleNewRun() {
|
||||
if (!onboarding.state) return;
|
||||
|
||||
setShowInput(true);
|
||||
onboarding.setStep(6);
|
||||
onboarding.updateState({
|
||||
completedSteps: [
|
||||
...(onboarding.state.completedSteps || []),
|
||||
"AGENT_NEW_RUN",
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
function handleSetAgentInput(key: string, value: string) {
|
||||
if (!onboarding.state) return;
|
||||
|
||||
onboarding.updateState({
|
||||
agentInput: {
|
||||
...onboarding.state.agentInput,
|
||||
[key]: value,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function handleRunAgent() {
|
||||
if (!agent || !storeAgent || !onboarding.state) {
|
||||
toast({
|
||||
title: "Error getting agent",
|
||||
description:
|
||||
"Either the agent is not available or there was an error getting it.",
|
||||
variant: "destructive",
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setRunningAgent(true);
|
||||
|
||||
try {
|
||||
const libraryAgent = await api.addMarketplaceAgentToLibrary(
|
||||
storeAgent?.store_listing_version_id || "",
|
||||
);
|
||||
|
||||
const { id: runID } = await api.executeGraph(
|
||||
libraryAgent.graph_id,
|
||||
libraryAgent.graph_version,
|
||||
onboarding.state.agentInput || {},
|
||||
inputCredentials,
|
||||
);
|
||||
|
||||
onboarding.updateState({
|
||||
onboardingAgentExecutionId: runID,
|
||||
agentRuns: (onboarding.state.agentRuns || 0) + 1,
|
||||
});
|
||||
|
||||
router.push("/onboarding/6-congrats");
|
||||
} catch (error) {
|
||||
console.error("Error running agent:", error);
|
||||
|
||||
toast({
|
||||
title: "Error running agent",
|
||||
description:
|
||||
"There was an error running your agent. Please try again or try choosing a different agent if it still fails.",
|
||||
variant: "destructive",
|
||||
});
|
||||
|
||||
setRunningAgent(false);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ready: graphMetaQuery.isSuccess && storeAgentQuery.isSuccess,
|
||||
error: graphMetaQuery.error || storeAgentQuery.error,
|
||||
agent,
|
||||
onboarding,
|
||||
showInput,
|
||||
storeAgent,
|
||||
runningAgent,
|
||||
credentialsValid,
|
||||
credentialsLoaded,
|
||||
handleSetAgentInput,
|
||||
handleRunAgent,
|
||||
handleNewRun,
|
||||
handleCredentialsChange: setInputCredentials,
|
||||
handleCredentialsValidationChange: setCredentialsValid,
|
||||
handleCredentialsLoadingChange: (v: boolean) => setCredentialsLoaded(!v),
|
||||
};
|
||||
}
|
||||
@@ -46,7 +46,7 @@ export default function StarRating({
|
||||
)}
|
||||
>
|
||||
{/* Display numerical rating */}
|
||||
<span className="mr-1 mt-1">{roundedRating}</span>
|
||||
<span className="mr-1 mt-0.5">{roundedRating}</span>
|
||||
|
||||
{/* Display stars */}
|
||||
{stars.map((starType, index) => {
|
||||
|
||||
@@ -105,6 +105,7 @@ export const CredentialsInput: FC<{
|
||||
onSelectCredentials: (newValue?: CredentialsMetaInput) => void;
|
||||
siblingInputs?: Record<string, any>;
|
||||
hideIfSingleCredentialAvailable?: boolean;
|
||||
onLoaded?: (loaded: boolean) => void;
|
||||
}> = ({
|
||||
schema,
|
||||
className,
|
||||
@@ -112,6 +113,7 @@ export const CredentialsInput: FC<{
|
||||
onSelectCredentials,
|
||||
siblingInputs,
|
||||
hideIfSingleCredentialAvailable = true,
|
||||
onLoaded,
|
||||
}) => {
|
||||
const [isAPICredentialsModalOpen, setAPICredentialsModalOpen] =
|
||||
useState(false);
|
||||
@@ -129,6 +131,13 @@ export const CredentialsInput: FC<{
|
||||
const api = useBackendAPI();
|
||||
const credentials = useCredentials(schema, siblingInputs);
|
||||
|
||||
// Report loaded state to parent
|
||||
useEffect(() => {
|
||||
if (onLoaded) {
|
||||
onLoaded(Boolean(credentials && credentials.isLoading === false));
|
||||
}
|
||||
}, [credentials, onLoaded]);
|
||||
|
||||
// Deselect credentials if they do not exist (e.g. provider was changed)
|
||||
useEffect(() => {
|
||||
if (!credentials || !("savedCredentials" in credentials)) return;
|
||||
|
||||
@@ -14,12 +14,12 @@ import { environment } from "@/services/environment";
|
||||
|
||||
export default function LoginPage() {
|
||||
const {
|
||||
user,
|
||||
form,
|
||||
feedback,
|
||||
turnstile,
|
||||
captchaKey,
|
||||
isLoading,
|
||||
isLoggedIn,
|
||||
isCloudEnv,
|
||||
isUserLoading,
|
||||
isGoogleLoading,
|
||||
@@ -30,7 +30,7 @@ export default function LoginPage() {
|
||||
handleCloseNotAllowedModal,
|
||||
} = useLoginPage();
|
||||
|
||||
if (isUserLoading || isLoggedIn) {
|
||||
if (isUserLoading || user) {
|
||||
return <LoadingLogin />;
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ export function useLoginPage() {
|
||||
feedback,
|
||||
turnstile,
|
||||
captchaKey,
|
||||
isLoggedIn: !!user,
|
||||
user,
|
||||
isLoading,
|
||||
isCloudEnv,
|
||||
isUserLoading,
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
@layer components {
|
||||
.agpt-border-input {
|
||||
@apply m-0.5 border border-input focus:border-gray-400 focus:outline-none focus:ring-1 focus:ring-gray-400 data-[state=open]:border-gray-400 data-[state=open]:ring-1 data-[state=open]:ring-gray-400;
|
||||
@apply m-0.5 border border-input data-[state=open]:border-gray-400 data-[state=open]:ring-1 data-[state=open]:ring-gray-400 focus:border-gray-400 focus:outline-none focus:ring-1 focus:ring-gray-400;
|
||||
}
|
||||
|
||||
.agpt-shadow-input {
|
||||
|
||||
@@ -13,7 +13,7 @@ const Checkbox = React.forwardRef<
|
||||
<CheckboxPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"peer h-4 w-4 shrink-0 rounded-sm border border-neutral-200 border-neutral-900 shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-neutral-950 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-neutral-900 data-[state=checked]:text-neutral-50 dark:border-neutral-50 dark:border-neutral-800 dark:focus-visible:ring-neutral-300 dark:data-[state=checked]:bg-neutral-50 dark:data-[state=checked]:text-neutral-900",
|
||||
"peer h-4 w-4 shrink-0 rounded-sm border border-neutral-200 border-neutral-900 shadow data-[state=checked]:bg-neutral-900 data-[state=checked]:text-neutral-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-neutral-950 disabled:cursor-not-allowed disabled:opacity-50 dark:border-neutral-50 dark:border-neutral-800 dark:data-[state=checked]:bg-neutral-50 dark:data-[state=checked]:text-neutral-900 dark:focus-visible:ring-neutral-300",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -44,7 +44,7 @@ const DialogContent = React.forwardRef<
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-neutral-100 data-[state=open]:text-neutral-500 dark:ring-offset-neutral-950 dark:focus:ring-neutral-300 dark:data-[state=open]:bg-neutral-800 dark:data-[state=open]:text-neutral-400">
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity data-[state=open]:bg-neutral-100 data-[state=open]:text-neutral-500 hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none dark:ring-offset-neutral-950 dark:data-[state=open]:bg-neutral-800 dark:data-[state=open]:text-neutral-400 dark:focus:ring-neutral-300">
|
||||
<Cross2Icon className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
|
||||
@@ -31,7 +31,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-neutral-100 data-[state=open]:bg-neutral-100 dark:focus:bg-neutral-800 dark:data-[state=open]:bg-neutral-800",
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-neutral-100 focus:bg-neutral-100 dark:data-[state=open]:bg-neutral-800 dark:focus:bg-neutral-800",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
@@ -88,7 +88,7 @@ const DropdownMenuItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-neutral-100 focus:text-neutral-900 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
@@ -104,7 +104,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-neutral-100 focus:text-neutral-900 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
@@ -128,7 +128,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-neutral-100 focus:text-neutral-900 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -24,7 +24,7 @@ const SelectTrigger = React.forwardRef<
|
||||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"agpt-border-input agpt-shadow-input flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-transparent px-3 py-2 text-sm ring-offset-white placeholder:text-neutral-500 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 data-[state=open]:border-gray-400 dark:placeholder:text-neutral-400 [&>span]:line-clamp-1",
|
||||
"agpt-border-input agpt-shadow-input flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-transparent px-3 py-2 text-sm ring-offset-white placeholder:text-neutral-500 data-[state=open]:border-gray-400 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:placeholder:text-neutral-400 [&>span]:line-clamp-1",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
@@ -123,7 +123,7 @@ const SelectItem = React.forwardRef<
|
||||
<SelectPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-neutral-100 focus:text-neutral-900 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -64,7 +64,7 @@ const SheetContent = React.forwardRef<
|
||||
className={cn(sheetVariants({ side }), className)}
|
||||
{...props}
|
||||
>
|
||||
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-neutral-100 dark:ring-offset-neutral-950 dark:focus:ring-neutral-300 dark:data-[state=open]:bg-neutral-800">
|
||||
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity data-[state=open]:bg-neutral-100 hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none dark:ring-offset-neutral-950 dark:data-[state=open]:bg-neutral-800 dark:focus:ring-neutral-300">
|
||||
<Cross2Icon className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</SheetPrimitive.Close>
|
||||
|
||||
@@ -58,7 +58,7 @@ const TableRow = React.forwardRef<
|
||||
<tr
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"border-b transition-colors hover:bg-neutral-100/50 data-[state=selected]:bg-neutral-100 dark:hover:bg-neutral-800/50 dark:data-[state=selected]:bg-neutral-800",
|
||||
"border-b transition-colors data-[state=selected]:bg-neutral-100 hover:bg-neutral-100/50 dark:data-[state=selected]:bg-neutral-800 dark:hover:bg-neutral-800/50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -11,7 +11,7 @@ const Switch = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SwitchPrimitives.Root
|
||||
className={cn(
|
||||
"peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-neutral-900 data-[state=unchecked]:bg-neutral-200 dark:focus-visible:ring-neutral-300 dark:focus-visible:ring-offset-neutral-950 dark:data-[state=checked]:bg-neutral-50 dark:data-[state=unchecked]:bg-neutral-800",
|
||||
"peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors data-[state=checked]:bg-neutral-900 data-[state=unchecked]:bg-neutral-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:cursor-not-allowed disabled:opacity-50 dark:data-[state=checked]:bg-neutral-50 dark:data-[state=unchecked]:bg-neutral-800 dark:focus-visible:ring-neutral-300 dark:focus-visible:ring-offset-neutral-950",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -25,7 +25,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-neutral-100 data-[state=open]:bg-neutral-100 dark:focus:bg-neutral-800 dark:data-[state=open]:bg-neutral-800",
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[state=open]:bg-neutral-100 focus:bg-neutral-100 dark:data-[state=open]:bg-neutral-800 dark:focus:bg-neutral-800",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
@@ -82,7 +82,7 @@ const DropdownMenuItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-neutral-100 focus:text-neutral-900 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
inset && "pl-8",
|
||||
className,
|
||||
)}
|
||||
@@ -98,7 +98,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-neutral-100 focus:text-neutral-900 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
@@ -122,7 +122,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-neutral-100 focus:text-neutral-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
"relative flex cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 focus:bg-neutral-100 focus:text-neutral-900 dark:focus:bg-neutral-800 dark:focus:text-neutral-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -109,7 +109,7 @@ const TabsLineTrigger = React.forwardRef<
|
||||
elementRef.current = node;
|
||||
}}
|
||||
className={cn(
|
||||
"relative inline-flex items-center justify-center whitespace-nowrap px-3 py-3 font-sans text-[1rem] font-medium leading-[1.5rem] text-zinc-700 transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-purple-600",
|
||||
"relative inline-flex items-center justify-center whitespace-nowrap px-3 py-3 font-sans text-[1rem] font-medium leading-[1.5rem] text-zinc-700 transition-all data-[state=active]:text-purple-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -74,46 +74,6 @@ test.describe("Library", () => {
|
||||
test.expect(allAgents.length).toEqual(displayedCount);
|
||||
});
|
||||
|
||||
test("sorting works correctly", async ({ page }) => {
|
||||
await page.goto("/library");
|
||||
|
||||
const initialAgents = await libraryPage.getAgents();
|
||||
expect(initialAgents.length).toBeGreaterThan(0);
|
||||
|
||||
await libraryPage.selectSortOption(page, "Creation Date");
|
||||
await libraryPage.waitForAgentsToLoad();
|
||||
|
||||
const creationDateSortOption = await libraryPage.getCurrentSortOption();
|
||||
expect(creationDateSortOption).toContain("Creation Date");
|
||||
|
||||
const creationDateAgents = await libraryPage.getAgents();
|
||||
expect(creationDateAgents.length).toBeGreaterThan(0);
|
||||
|
||||
await libraryPage.selectSortOption(page, "Last Modified");
|
||||
await libraryPage.waitForAgentsToLoad();
|
||||
|
||||
const lastModifiedSortOption = await libraryPage.getCurrentSortOption();
|
||||
expect(lastModifiedSortOption).toContain("Last Modified");
|
||||
|
||||
const lastModifiedAgents = await libraryPage.getAgents();
|
||||
expect(lastModifiedAgents.length).toBeGreaterThan(0);
|
||||
|
||||
if (initialAgents.length > 1) {
|
||||
const initialFirstAgentId = initialAgents[0].id;
|
||||
const creationDateFirstAgentId = creationDateAgents[0].id;
|
||||
const lastModifiedFirstAgentId = lastModifiedAgents[0].id;
|
||||
|
||||
expect(
|
||||
creationDateFirstAgentId !== initialFirstAgentId ||
|
||||
lastModifiedFirstAgentId !== initialFirstAgentId ||
|
||||
creationDateFirstAgentId !== lastModifiedFirstAgentId,
|
||||
).toBeTruthy();
|
||||
}
|
||||
|
||||
expect(creationDateAgents.length).toEqual(initialAgents.length);
|
||||
expect(lastModifiedAgents.length).toEqual(initialAgents.length);
|
||||
});
|
||||
|
||||
test("searching works correctly", async ({ page }) => {
|
||||
await page.goto("/library");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user