diff --git a/openbot/app/src/routes/_authed/onboarding.tsx b/openbot/app/src/routes/_authed/onboarding.tsx index b4e0661c..a9b5e466 100644 --- a/openbot/app/src/routes/_authed/onboarding.tsx +++ b/openbot/app/src/routes/_authed/onboarding.tsx @@ -373,6 +373,30 @@ function AgentsStep() { ); } +/** + * CopilotKit's other open products, named and described as the website's own Products menu has them + * (copilotkit.ai). Somebody trying OpenDuet on their own machine is the person most likely to want + * one of them, and this is the slide about what comes after trying it. `ref` tells CopilotKit the + * visit came from onboarding. + */ +const MORE_FROM_COPILOTKIT = [ + { + name: "OpenBot", + line: "The self-hosted assistant OpenDuet is built on.", + href: "https://www.copilotkit.ai/openbot?ref=openduet_onboarding", + }, + { + name: "OpenMuse", + line: "A personal agent with its own browser and files, on iOS, Android and web.", + href: "https://www.copilotkit.ai/openmuse?ref=openduet_onboarding", + }, + { + name: "OpenDots", + line: "Always-on coworkers for text, calls and Slack.", + href: "https://www.copilotkit.ai/opendots?ref=openduet_onboarding", + }, +] as const; + function OrganizationStep() { return (
@@ -381,13 +405,14 @@ function OrganizationStep() {

Run one container image, or a Helm chart for EKS, GKE or AKS. Your - people sign in with Google, Microsoft or Okta. + people sign in with Google, Microsoft or Okta. Enterprise deployments + are available now in early access.

{/* - * The one real control on these slides, so it sits outside the frame: a frame means picture. - * A new tab, because following it must not cost this person their place in onboarding. + * The real controls on these slides, so they sit outside the frame: a frame means picture. + * New tabs, because following one must not cost this person their place in onboarding. */} - Talk to an engineer + Get early access +
+

+ More from CopilotKit +

+ +
); } diff --git a/openbot/app/tests/onboarding-route.test.tsx b/openbot/app/tests/onboarding-route.test.tsx index 02706f4f..f89c499c 100644 --- a/openbot/app/tests/onboarding-route.test.tsx +++ b/openbot/app/tests/onboarding-route.test.tsx @@ -207,6 +207,30 @@ test("the local install's step says where its data really lives", async () => { expect(page).not.toContain("Only what you send to your model leaves it"); }); +test("the organization step offers enterprise early access and CopilotKit's other products", async () => { + localEvaluation = true; + const view = open("/onboarding?step=organization"); + + await heading(view, "Deploy it for your organization"); + expect(document.body.textContent).toContain( + "Enterprise deployments are available now in early access.", + ); + const early = view.getByRole("link", { name: "Get early access" }); + expect(early.getAttribute("href")).toBe( + "https://www.copilotkit.ai/talk-to-an-engineer?ref=openduet_app", + ); + expect(early.getAttribute("target")).toBe("_blank"); + for (const product of ["openbot", "openmuse", "opendots"]) { + const link = view + .getAllByRole("link") + .find((a) => a.getAttribute("href")?.includes(`/${product}?`)); + expect(link?.getAttribute("href")).toBe( + `https://www.copilotkit.ai/${product}?ref=openduet_onboarding`, + ); + expect(link?.getAttribute("target")).toBe("_blank"); + } +}); + test("Next adds a step to the address and to history, and saves it", async () => { const view = open("/onboarding?step=welcome"); await heading(view, "Welcome to OpenDuet");