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");