From 0aba8423a21ad0824c2f1be5fee6101c17ae8b9e Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 29 Apr 2025 16:26:31 +0100 Subject: [PATCH] =?UTF-8?q?chore:=20=F0=9F=A4=96=20chatbox=20to=20deployme?= =?UTF-8?q?nt=20setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-dry-run.yml | 1 - .github/workflows/fleek-deploy-common.yml | 1 - README.md | 1 - package-lock.json | 64 ++++++++++--- package.json | 3 +- src/components/ChatToAIAgentDeploy/index.tsx | 98 +++++++------------- src/components/LandingPage/Hero.tsx | 13 +-- src/components/Navbar/index.tsx | 10 +- src/utils/funnel.ts | 16 ++++ 9 files changed, 115 insertions(+), 92 deletions(-) create mode 100644 src/utils/funnel.ts diff --git a/.github/workflows/build-dry-run.yml b/.github/workflows/build-dry-run.yml index 4fd8e152f..cbdcbcf57 100644 --- a/.github/workflows/build-dry-run.yml +++ b/.github/workflows/build-dry-run.yml @@ -28,7 +28,6 @@ jobs: PUBLIC_FLEEK_REST_API_URL: dry.run PUBLIC_DYNAMIC_ENVIRONMENT_ID: 'UNAVAILABLE' PUBLIC_UI_APP_URL: dry.run - PUBLIC_PERSONA_GENERATOR_API_URL: dry.run steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/fleek-deploy-common.yml b/.github/workflows/fleek-deploy-common.yml index 609344f5f..b083214fa 100644 --- a/.github/workflows/fleek-deploy-common.yml +++ b/.github/workflows/fleek-deploy-common.yml @@ -37,7 +37,6 @@ jobs: PUBLIC_SUPPORT_API_HOST: ${{ vars.PUBLIC_SUPPORT_API_HOST }} PUBLIC_UI_APP_URL: ${{ vars.PUBLIC_UI_APP_URL }} PUBLIC_UI_AGENTS_APP_URL: ${{ vars.PUBLIC_UI_AGENTS_APP_URL }} - PUBLIC_PERSONA_GENERATOR_API_URL: ${{ vars.PUBLIC_PERSONA_GENERATOR_API_URL }} steps: - name: Checkout uses: actions/checkout@v4 diff --git a/README.md b/README.md index 81bacfea4..0978fae78 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,6 @@ PUBLIC_POSTHOG_HOST="https://us.i.posthog.com" PUBLIC_POSTHOG_API_KEY="phc_SdvLWEagL7nAauyEBun0ZF6v59DxMIk8ofzI91gpIUw" PUBLIC_OPEN_API_ENDPOINT="https://api.fleek.xyz/api/openapi.json" PUBLIC_FLEEK_WEBSITE_URL="https://fleek.xyz" -PUBLIC_PERSONA_GENERATOR_API_URL="https://persona-generator.flkservices.io" ``` 💡 The SUPPORT_ALLOW_ORIGIN_ADDR and SUPPORT_RATE_LIMIT_PATHS are comma separated values (csv). the MEILISEARCH_DOCUMENTS_CLIENT_API_KEY is required when querying staging, production environments which should be provided in the headers. diff --git a/package-lock.json b/package-lock.json index fa9a17810..a3e3e0b85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@astrojs/react": "^3.3.2", "@astrojs/sitemap": "^3.1.4", "@astrojs/tailwind": "^5.1.0", - "@fleek-platform/agents-ui": "^8.12.0", + "@fleek-platform/agents-ui": "8.10.5", "@fleek-platform/dashboard": "0.20.4", "@fleek-platform/login-button": "2.10.1", "@fleek-platform/sdk": "^3.6.2", @@ -26,7 +26,6 @@ "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.4", "@tailwindcss/aspect-ratio": "^0.4.2", - "@tanstack/react-query": "^5.66.7", "@types/react": "^18.2.74", "@types/react-dom": "^18.2.24", "astro": "^4.15.3", @@ -4496,13 +4495,12 @@ } }, "node_modules/@fleek-platform/agents-ui": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/@fleek-platform/agents-ui/-/agents-ui-8.12.0.tgz", - "integrity": "sha512-Ldz6Lhz9AuHKa7ZxkPfIhSGXGxsBJdt6t/UGoLzPWKrQrtLtY87VMtfysu2HQVCJoattvHxNDWqxTAU1uNz2Sg==", - "license": "MIT", + "version": "8.10.5", + "resolved": "https://registry.npmjs.org/@fleek-platform/agents-ui/-/agents-ui-8.10.5.tgz", + "integrity": "sha512-MMsBYC2Rwv1q7jS4oU9K82CwECL6m9dyNVqj7sYltFBTQlUYlhjZgVXh+tuXvGoVh6U5V+8jJ8IjX1tMEUcHCw==", "dependencies": { "@fleek-platform/agents-chatbox-widget": "^0.9.0", - "@fleek-platform/login-button": "^2.9.0", + "@fleek-platform/login-button": "^2.7.3", "@hookform/resolvers": "^3.9.1", "@monaco-editor/react": "^4.6.0", "@radix-ui/react-dropdown-menu": "^2.1.4", @@ -4702,6 +4700,16 @@ "@types/hast": "^3.0.4" } }, + "node_modules/@fleek-platform/agents-ui/node_modules/@tanstack/query-core": { + "version": "5.66.4", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.4.tgz", + "integrity": "sha512-skM/gzNX4shPkqmdTCSoHtJAPMTtmIJNS0hE+xwTTUVYwezArCT34NMermABmBVUg5Ls5aiUXEDXfqwR1oVkcA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@fleek-platform/agents-ui/node_modules/@tanstack/query-persist-client-core": { "version": "5.66.4", "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.66.4.tgz", @@ -4729,6 +4737,22 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@fleek-platform/agents-ui/node_modules/@tanstack/react-query": { + "version": "5.66.7", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.66.7.tgz", + "integrity": "sha512-qd3q/tUpF2K1xItfPZddk1k/8pSXnovg41XyCqJgPoyYEirMBtB0sVEVVQ/CsAOngzgWtBPXimVf4q4kM9uO6A==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.66.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@fleek-platform/agents-ui/node_modules/motion": { "version": "12.6.2", "resolved": "https://registry.npmjs.org/motion/-/motion-12.6.2.tgz", @@ -13750,10 +13774,11 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.66.4", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.4.tgz", - "integrity": "sha512-skM/gzNX4shPkqmdTCSoHtJAPMTtmIJNS0hE+xwTTUVYwezArCT34NMermABmBVUg5Ls5aiUXEDXfqwR1oVkcA==", + "version": "5.67.3", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.67.3.tgz", + "integrity": "sha512-pq76ObpjcaspAW4OmCbpXLF6BCZP2Zr/J5ztnyizXhSlNe7fIUp0QKZsd0JMkw9aDa+vxDX/OY7N+hjNY/dCGg==", "license": "MIT", + "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -13806,12 +13831,13 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.66.7", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.66.7.tgz", - "integrity": "sha512-qd3q/tUpF2K1xItfPZddk1k/8pSXnovg41XyCqJgPoyYEirMBtB0sVEVVQ/CsAOngzgWtBPXimVf4q4kM9uO6A==", + "version": "5.67.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.67.3.tgz", + "integrity": "sha512-u/n2HsQeH1vpZIOzB/w2lqKlXUDUKo6BxTdGXSMvNzIq5MHYFckRMVuFABp+QB7RN8LFXWV6X1/oSkuDq+MPIA==", "license": "MIT", + "peer": true, "dependencies": { - "@tanstack/query-core": "5.66.4" + "@tanstack/query-core": "5.67.3" }, "funding": { "type": "github", @@ -13855,6 +13881,16 @@ "react": "^18 || ^19" } }, + "node_modules/@tanstack/react-query-persist-client/node_modules/@tanstack/query-core": { + "version": "5.66.4", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.66.4.tgz", + "integrity": "sha512-skM/gzNX4shPkqmdTCSoHtJAPMTtmIJNS0hE+xwTTUVYwezArCT34NMermABmBVUg5Ls5aiUXEDXfqwR1oVkcA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tanstack/react-query-persist-client/node_modules/@tanstack/query-persist-client-core": { "version": "5.66.4", "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.66.4.tgz", diff --git a/package.json b/package.json index e6e8bd245..e27b77647 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@astrojs/react": "^3.3.2", "@astrojs/sitemap": "^3.1.4", "@astrojs/tailwind": "^5.1.0", - "@fleek-platform/agents-ui": "^8.12.0", + "@fleek-platform/agents-ui": "8.10.5", "@fleek-platform/dashboard": "0.20.4", "@fleek-platform/login-button": "2.10.1", "@fleek-platform/sdk": "^3.6.2", @@ -65,7 +65,6 @@ "@radix-ui/react-checkbox": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.4", "@tailwindcss/aspect-ratio": "^0.4.2", - "@tanstack/react-query": "^5.66.7", "@types/react": "^18.2.74", "@types/react-dom": "^18.2.24", "astro": "^4.15.3", diff --git a/src/components/ChatToAIAgentDeploy/index.tsx b/src/components/ChatToAIAgentDeploy/index.tsx index 52d36f1d6..35b491f40 100644 --- a/src/components/ChatToAIAgentDeploy/index.tsx +++ b/src/components/ChatToAIAgentDeploy/index.tsx @@ -2,27 +2,16 @@ import '@fleek-platform/agents-ui/styles'; import { ChatBox, type FileWithPreview, - useDeployFromPrompt, - SubscriptionModal, - setDefined, + DRAFT_BOOTSTRAP_DATA_KEY, + ROUTE_NEW_DRAFT, } from '@fleek-platform/agents-ui'; import { useAuthStore } from '@fleek-platform/login-button'; +import { storeFunnelData } from '@utils/funnel'; +import { fileToBase64 } from '@utils/file'; import { setReferralQueryKeyValuePair } from '@utils/referrals'; -import { useEffect, useRef } from 'react'; -import { createPortal } from 'react-dom'; -import { isClient } from '@utils/common'; -import toast from 'react-hot-toast'; const MAX_FILE_SIZE = 10 * 1024 * 1024; -const updateDefined = () => { - setDefined({ - PUBLIC_FLEEK_REST_API_HOST: import.meta.env.PUBLIC_FLEEK_REST_API_HOST, - PUBLIC_PERSONA_GENERATOR_API_URL: import.meta.env - .PUBLIC_PERSONA_GENERATOR_API_URL, - }); -}; - export const ChatToAIAgentDeploy = ({ role, onDescriptionChange, @@ -30,48 +19,46 @@ export const ChatToAIAgentDeploy = ({ role?: string; onDescriptionChange?: () => void; }) => { - const { triggerLoginModal, isLoggedIn, accessToken, projectId } = - useAuthStore(); - - const { deploy, isDeploying } = useDeployFromPrompt({ - onDeploy: ({ agentId }) => { - window.location.href = `${import.meta.env.PUBLIC_UI_AGENTS_APP_URL}/drafts/${agentId}/deploying`; - }, - onError: () => { - toast.error('Failed to deploy agent'); - }, - }); - - const hasRun = useRef(false); - const pendingPrompt = useRef(); - useEffect(() => { - if (isLoggedIn && !hasRun.current && pendingPrompt.current) { - hasRun.current = true; - updateDefined(); - deploy({ - prompt: pendingPrompt.current, - accessToken, - projectId, - }); - pendingPrompt.current = undefined; - } - }, [isLoggedIn, accessToken, projectId, deploy]); + const { triggerLoginModal, isLoggedIn } = useAuthStore(); const onSubmit = async (description: string, files: FileWithPreview[]) => { + console.log('[debug] Description:', description); + console.log('[debug] Files:', files); + + // TODO: Validate data + + const fileDataPromises = files.map((file) => fileToBase64(file)); + const fileDataArray = await Promise.all(fileDataPromises); + + const data = { + mode: 'chat', + fromApp: 'website', + prompt: description, + timestamp: new Date(), + }; + + setReferralQueryKeyValuePair('agents'); + storeFunnelData({ + key: DRAFT_BOOTSTRAP_DATA_KEY, + data, + }); + if (isLoggedIn) { - updateDefined(); - deploy({ - prompt: description, - accessToken, - projectId, + const currentParams = new URLSearchParams(window.location.search); + + const targetUrl = new URL( + `${import.meta.env.PUBLIC_UI_AGENTS_APP_URL}${ROUTE_NEW_DRAFT}`, + ); + + currentParams.forEach((value, key) => { + targetUrl.searchParams.append(key, value); }); + window.location.assign(targetUrl.toString()); + return true; } - pendingPrompt.current = description; - hasRun.current = false; - setReferralQueryKeyValuePair('agents'); if (typeof triggerLoginModal !== 'function') { console.log('[debug] triggerLoginModal is not a fn!'); @@ -83,10 +70,6 @@ export const ChatToAIAgentDeploy = ({ return true; }; - useEffect(() => { - updateDefined(); - }, []); - const onSuccess = () => { console.log('[debug] Submission successful'); }; @@ -106,16 +89,7 @@ export const ChatToAIAgentDeploy = ({ prompt={ role ? `I want to create a ${role.toLocaleLowerCase()}.` : undefined } - isSubmitting={isDeploying} /> - - {isClient && - createPortal( -
- -
, - document.body, - )} ); }; diff --git a/src/components/LandingPage/Hero.tsx b/src/components/LandingPage/Hero.tsx index dd4695c37..44ccc5c70 100644 --- a/src/components/LandingPage/Hero.tsx +++ b/src/components/LandingPage/Hero.tsx @@ -16,9 +16,6 @@ import { ChatToAIAgentDeploy } from '@components/ChatToAIAgentDeploy'; import type { IconType } from 'react-icons/lib'; import { cn } from '@utils/cn'; import { useState } from 'react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; - -const queryClient = new QueryClient(); const calculateDelay = (factor: number) => 0.25 * factor; @@ -101,12 +98,10 @@ export const Hero = () => { - - setRole(undefined)} - /> - + setRole(undefined)} + /> diff --git a/src/components/Navbar/index.tsx b/src/components/Navbar/index.tsx index d8a61c3a8..cf294bba7 100644 --- a/src/components/Navbar/index.tsx +++ b/src/components/Navbar/index.tsx @@ -18,20 +18,26 @@ import type { Project } from '@fleek-platform/sdk/browser'; import { isClient } from '../../utils/common'; import { useSession } from '@hooks/useSession'; import { isReferralName } from '@utils/referrals'; +import { ROUTE_NEW_DRAFT } from '@fleek-platform/agents-ui'; const dashboardUrl = import.meta.env.PUBLIC_UI_APP_URL; +const agentsUrl = `${import.meta.env.PUBLIC_UI_AGENTS_APP_URL}${ROUTE_NEW_DRAFT}`; const onAuthenticationSuccess = () => { - if (!isClient || isReferralName('agents')) return; + if (!isClient) return; const currentParams = new URLSearchParams(window.location.search); - const targetUrl = new URL(dashboardUrl); + let targetUrl = new URL(agentsUrl); currentParams.forEach((value, key) => { targetUrl.searchParams.append(key, value); }); + if (isReferralName('dashboard')) { + targetUrl = new URL(dashboardUrl); + } + window.location.assign(targetUrl.toString()); }; diff --git a/src/utils/funnel.ts b/src/utils/funnel.ts new file mode 100644 index 000000000..8bbc65e8a --- /dev/null +++ b/src/utils/funnel.ts @@ -0,0 +1,16 @@ +// TODO: Use `sessionStorage` instead of `localStorage` +// to prevent tab concurrency? Might not be necessary +// if the user journey happens in a particular route path +export const storeFunnelData = ({ + key, + data, +}: { + key: string; + data: unknown; +}) => window.localStorage.setItem(key, JSON.stringify(data)); + +export const retrieveFunnelData = ({ key }: { key: string }) => + window.localStorage.getItem(key); + +export const clearFunnelData = ({ key }: { key: string }) => + window.localStorage.removeItem(key);