Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 55 additions & 47 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@mdx-js/react": "^3.1.1",
"@next/mdx": "^15.5.4",
"@next/third-parties": "^15.5.4",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
Expand Down
12 changes: 10 additions & 2 deletions src/app/docs/kagent/examples/telegram-bot/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,23 @@ No webhooks. No public endpoints. Just polling from inside the cluster.


<div style={{ display: "flex", alignItems: "center", gap: "16px", flexWrap: "wrap" }}>
<img src="/images/telegram-bot/telegram.gif" alt="Telegram Demo" style={{ width: "55%", minWidth: "300px" }} />
<MdxFigure
src="/images/telegram-bot/telegram.gif"
alt="Telegram Demo"
style={{ width: "55%", minWidth: "300px" }}
/>
</div>

## Architecture Overview

Here’s what we’re building:

<div style={{ display: "flex", alignItems: "center", gap: "16px", flexWrap: "wrap" }}>
<img src="/images/telegram-bot/arch.png" alt="Architecture" style={{ width: "40%", minWidth: "250px" }} />
<MdxFigure
src="/images/telegram-bot/arch.png"
alt="Architecture"
style={{ width: "40%", minWidth: "250px" }}
/>
</div>

---
Expand Down
2 changes: 1 addition & 1 deletion src/blogContent/kagent-celebrating-100-days.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Fast forward 100 days, and today we’re celebrating a major milestone: **100 da

What began as a tool to address our own customer challenges has grown into a thriving open-source project. Kagent is now a **CNCF Sandbox project**, and it's evolving into a powerful **declarative agentic AI framework**—enabling like-minded engineers to run AI agents in Kubernetes, automating complex operations and streamlining troubleshooting workflows.

<img src="/images/blog/100days/cncf-sandbox.png" alt="LinkedIn post from Peter Jausovec" width="600"/>
![LinkedIn post from Peter Jausovec](/images/blog/100days/cncf-sandbox.png)

## 🌟 100 contributors & 1000+ GitHub stars!

Expand Down
39 changes: 39 additions & 0 deletions src/components/mdx/mdx-figure-lightbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use client"

import {
Dialog,
DialogContent,
DialogTitle,
} from "@/components/ui/dialog"

export type MdxFigureLightboxProps = {
open: boolean
onOpenChange: (open: boolean) => void
src: string
alt: string
label: string
}

export function MdxFigureLightbox({
open,
onOpenChange,
src,
alt,
label,
}: MdxFigureLightboxProps) {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="w-auto max-h-[90vh] max-w-[min(96vw,1200px)] gap-0 overflow-hidden p-0 motion-reduce:animate-none sm:max-w-[min(96vw,1200px)] [&>button]:z-[60]">
<DialogTitle className="sr-only">{label}</DialogTitle>
<div className="px-4 pb-4 pt-12">
{/* eslint-disable-next-line @next/next/no-img-element -- lightbox needs intrinsic image sizing */}
<img
src={src}
alt={alt}
className="mx-auto block h-auto max-h-[min(80vh,85dvh)] w-auto max-w-[min(92vw,1160px)] object-contain"
/>
</div>
</DialogContent>
</Dialog>
)
}
81 changes: 81 additions & 0 deletions src/components/mdx/mdx-figure.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"use client"

import * as React from "react"
import dynamic from "next/dynamic"
import Image from "next/image"
import { cn } from "@/lib/utils"

const MdxFigureLightbox = dynamic(
() =>
import("./mdx-figure-lightbox").then((mod) => ({
default: mod.MdxFigureLightbox,
})),
{ ssr: false }
)

type MdxFigureProps = React.ImgHTMLAttributes<HTMLImageElement>

export function MdxFigure({
src,
alt = "",
title,
className,
style,
}: MdxFigureProps) {
const [open, setOpen] = React.useState(false)
const [hasOpened, setHasOpened] = React.useState(false)

if (!src || typeof src !== "string") {
return null
}

const caption = title
const label = alt || (typeof caption === "string" ? caption : "") || "documentation image"

const handleOpenChange = (next: boolean) => {
setOpen(next)
if (next) {
setHasOpened(true)
}
}

const hasLayoutOverride = className != null || style != null

return (
<figure className={cn(hasLayoutOverride && className)} style={hasLayoutOverride ? style : undefined}>
<button
type="button"
className={cn(
"block w-full cursor-zoom-in text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 motion-reduce:transition-none",
hasLayoutOverride && "mx-0"
)}
aria-label={`View larger image: ${label}`}
aria-haspopup="dialog"
aria-expanded={open}
onClick={() => handleOpenChange(true)}
>
<Image
src={src}
alt={alt}
width={0}
height={0}
sizes="100vw"
className="h-auto w-full"
loading="lazy"
/>
</button>
{hasOpened ? (
<MdxFigureLightbox
open={open}
onOpenChange={handleOpenChange}
src={src}
alt={alt}
label={label}
/>
) : null}
{caption ? (
<figcaption className="text-xs text-center italic">{caption}</figcaption>
) : null}
</figure>
)
}
122 changes: 122 additions & 0 deletions src/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
"use client"

import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"

import { cn } from "@/lib/utils"

const Dialog = DialogPrimitive.Root

const DialogTrigger = DialogPrimitive.Trigger

const DialogPortal = DialogPrimitive.Portal

const DialogClose = DialogPrimitive.Close

const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
/>
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName

const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
)}
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
))
DialogContent.displayName = DialogPrimitive.Content.displayName

const DialogHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className
)}
{...props}
/>
)
DialogHeader.displayName = "DialogHeader"

const DialogFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
DialogFooter.displayName = "DialogFooter"

const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
DialogTitle.displayName = DialogPrimitive.Title.displayName

const DialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
DialogDescription.displayName = DialogPrimitive.Description.displayName

export {
Dialog,
DialogPortal,
DialogOverlay,
DialogTrigger,
DialogClose,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
}
10 changes: 3 additions & 7 deletions src/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import SmartLink from "./components/mdx/smart-link";
import { CodeBlock } from "./components/mdx/code-block";
import { LabCTA } from "./components/mdx/lab-cta";
import { Aside } from "./components/mdx/aside";
import Image from "next/image";
import { MdxFigure } from "./components/mdx/mdx-figure";
import { generateAnchorId } from "@/lib/utils";

function YouTube ({ id } : { id : string }){
Expand Down Expand Up @@ -166,12 +166,7 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
{children}
</td>
),
img: ({ ...props }) => (
<figure>
<Image src={props.src} alt={props.title} width="0" height="0" sizes="100vw" className="w-full h-auto" />
{props.title && <figcaption className="text-xs text-center italic">{props.title}</figcaption>}
</figure>
),
img: (props) => <MdxFigure {...props} />,
// Pre (for code blocks)
pre: ({ children }) => <>{children}</>,
PlatformTabs,
Expand All @@ -181,6 +176,7 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
YouTube,
LabCTA,
Aside,
MdxFigure,
...components,
}),
[components]
Expand Down