diff --git a/public/assets/prometheus-logo.svg b/public/assets/prometheus-logo.svg
new file mode 100644
index 000000000..4e7bb85b9
--- /dev/null
+++ b/public/assets/prometheus-logo.svg
@@ -0,0 +1 @@
+
diff --git a/src/app/ask-ai/page.tsx b/src/app/ask-ai/page.tsx
new file mode 100644
index 000000000..dffce159f
--- /dev/null
+++ b/src/app/ask-ai/page.tsx
@@ -0,0 +1,12 @@
+import { getPageMetadata } from "@/page-metadata";
+import KapaPageLauncher from "@/components/KapaPageLauncher";
+
+export const metadata = getPageMetadata({
+ pageTitle: "Ask AI",
+ pageDescription: "Chat with the Prometheus documentation using Kapa.ai.",
+ pagePath: "/ask-ai/",
+});
+
+export default function AskAiPage() {
+ return ;
+}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index d2dbe1d2e..02b9e96b6 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -21,6 +21,7 @@ import "@mantine/code-highlight/styles.layer.css";
import "@mantine/spotlight/styles.layer.css";
import "./globals.css";
import { Header } from "@/components/Header";
+import KapaWidget from "@/components/KapaWidget";
import {
ANNOUNCEMENT_HEIGHT_PX,
isAnnouncementActive,
@@ -74,6 +75,7 @@ export default function RootLayout({
+
diff --git a/src/components/Header.module.css b/src/components/Header.module.css
index 2ef18e08a..b12af291f 100644
--- a/src/components/Header.module.css
+++ b/src/components/Header.module.css
@@ -39,3 +39,7 @@
);
}
}
+
+.askAiButton {
+ font-weight: 500;
+}
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
index 35efb233e..f1147945f 100644
--- a/src/components/Header.tsx
+++ b/src/components/Header.tsx
@@ -8,11 +8,12 @@ import {
Container,
TextInput,
ActionIcon,
+ Button,
AppShell,
Popover,
} from "@mantine/core";
import Image from "next/image";
-import { IconSearch } from "@tabler/icons-react";
+import { IconSearch, IconSparkles } from "@tabler/icons-react";
import prometheusLogo from "../assets/prometheus-logo.svg";
import classes from "./Header.module.css";
import githubLogo from "../assets/github-logo.svg";
@@ -61,6 +62,33 @@ export const Header = ({
));
+ const renderAskAiButton = ({
+ hiddenFrom,
+ onClick,
+ }: {
+ hiddenFrom?: "sm" | "md" | "lg";
+ onClick?: () => void;
+ }) => (
+
+ }
+ hiddenFrom={hiddenFrom}
+ onClick={onClick}
+ >
+ Ask AI
+
+ );
+
const actionIcons = (
<>
{items}
+ {renderAskAiButton({})}
@@ -190,6 +219,12 @@ export const Header = ({
{items}
+
+ {renderAskAiButton({
+ hiddenFrom: "sm",
+ onClick: closeBurger,
+ })}
+
{actionIcons}
diff --git a/src/components/KapaPageLauncher.tsx b/src/components/KapaPageLauncher.tsx
new file mode 100644
index 000000000..333152bfe
--- /dev/null
+++ b/src/components/KapaPageLauncher.tsx
@@ -0,0 +1,88 @@
+"use client";
+
+import { Button, Stack, Text, Title } from "@mantine/core";
+import { useEffect, useState } from "react";
+
+declare global {
+ interface Window {
+ Kapa?: {
+ close?: () => void;
+ open?: (options?: {
+ mode?: "search" | "ai";
+ query?: string;
+ submit?: boolean;
+ }) => void;
+ render?: (options?: { onRender?: () => void }) => void;
+ unmount?: () => void;
+ };
+ }
+}
+
+export default function KapaPageLauncher() {
+ const [hasRendered, setHasRendered] = useState(false);
+
+ const openAssistant = () => {
+ if (!window.Kapa?.render) {
+ return;
+ }
+
+ window.Kapa.render({
+ onRender: () => {
+ setHasRendered(true);
+ window.Kapa?.open?.({ mode: "ai" });
+ },
+ });
+ };
+
+ useEffect(() => {
+ let cancelled = false;
+
+ const openWhenReady = () => {
+ if (cancelled) {
+ return;
+ }
+
+ if (!window.Kapa?.render) {
+ window.setTimeout(openWhenReady, 100);
+ return;
+ }
+
+ window.Kapa.render({
+ onRender: () => {
+ if (cancelled) {
+ return;
+ }
+
+ setHasRendered(true);
+ window.Kapa?.open?.({ mode: "ai" });
+ },
+ });
+ };
+
+ openWhenReady();
+
+ return () => {
+ cancelled = true;
+ window.Kapa?.close?.();
+ window.Kapa?.unmount?.();
+ };
+ }, []);
+
+ return (
+
+ Ask AI
+
+ This branch gives Kapa a dedicated route, then opens the assistant in a
+ full-screen experience so the conversation gets most of the viewport.
+
+
+ {hasRendered
+ ? "If you close the assistant, use the button below to open it again."
+ : "Loading the assistant..."}
+
+
+
+ );
+}
diff --git a/src/components/KapaWidget.tsx b/src/components/KapaWidget.tsx
new file mode 100644
index 000000000..fd7557936
--- /dev/null
+++ b/src/components/KapaWidget.tsx
@@ -0,0 +1,53 @@
+import Script from "next/script";
+import docsConfig from "../../docs-config";
+
+export type KapaWidgetVariant = "drawer" | "modal" | "page";
+
+type KapaWidgetProps = {
+ variant: KapaWidgetVariant;
+};
+
+const WEBSITE_ID = "80cbacc9-0b84-48aa-bfb8-0002270176bf";
+const PROJECT_NAME = "Prometheus";
+const PROJECT_COLOR = "#D86444";
+const ASK_AI_TRIGGER_SELECTOR = "[data-kapa-trigger='ask-ai']";
+const PROJECT_LOGO_URL = new URL(
+ "/assets/prometheus-logo.svg",
+ docsConfig.siteUrl,
+).toString();
+
+export default function KapaWidget({ variant }: KapaWidgetProps) {
+ const triggerProps =
+ variant === "page"
+ ? {}
+ : {
+ "data-modal-override-open-selector-ask-ai": ASK_AI_TRIGGER_SELECTOR,
+ };
+
+ const variantProps =
+ variant === "drawer"
+ ? {
+ "data-view-mode": "sidebar",
+ }
+ : variant === "page"
+ ? {
+ "data-render-on-load": "false",
+ "data-modal-full-screen": "true",
+ }
+ : {};
+
+ return (
+
+ );
+}