From d618cc22f2b3f983b13cff250d9808f9c009d693 Mon Sep 17 00:00:00 2001 From: Jerel John Velarde Date: Mon, 26 Oct 2026 17:19:26 -0700 Subject: [PATCH] Offer enterprise early access and CopilotKit's other products in onboarding Feedback for the launch: onboarding should say enterprise deployments are available with early access, and name the other products CopilotKit makes. The organization step, which somebody trying OpenDuet on their own machine sees, now says enterprise deployments are available now in early access, its button reads Get early access, and a short More from CopilotKit list links OpenBot, OpenMuse and OpenDots, named and described as the website's Products menu has them, each tagged ref=openduet_onboarding. --- openbot/app/src/routes/_authed/onboarding.tsx | 71 +++++++++++++++++-- openbot/app/tests/onboarding-route.test.tsx | 24 +++++++ 2 files changed, 91 insertions(+), 4 deletions(-) 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");