Skip to content
Agent UI
Provider composesCopy-paste blockkimi-composeLive stage

Kimi Compose

A copy-paste block that recreates the Kimi prompt stage with Kimi's rail, brand mark, prompt surface, model menu, and tool toggles. The block is not a package component: copy the file, or install it with the shadcn CLI, then edit the layout like any other file in your project. It is assembled entirely from Agent UI compose primitives, and every control is keyboard accessible.

Source you own: install the block with the shadcn CLI or copy components/blocks/composes/kimi-compose.tsx. The preview below is the real file, and the code tab is the exact source.

components/blocks/composes/kimi-compose.tsx

KIMI

Choose project Plugins

Explore inspiration · AI-generated, for reference only

The code tab contains the full block, ready to copy.

Installation

Add the block with the shadcn CLI. It writes components/blocks/composes/kimi-compose.tsx and installs its dependencies.

bash
npx shadcn@latest add https://agent-ui-27t.pages.dev/r/kimi-compose.json

Prefer to own the file manually? Install the dependencies, then copy the source from the Files section.

bash
pnpm add @agent-ui/react lucide-react

Tailwind CSS v4 users: add @source "../node_modules/@agent-ui/react/src" to the global stylesheet so the library utilities are generated.

Usage

Import the copied file and render it anywhere. The block accepts onSend, disabled, and className; wire onSend to any backend.

tsx
import { KimiCompose } from "@/components/blocks/composes/kimi-compose";
 
<KimiCompose onSend={(text) => console.log(text)} />

Files

One file. The same source is served by the shadcn registry endpoint, so the CLI and the docs can never drift.

components/blocks/composes/kimi-compose.tsxtsx
tsx
"use client";
 
import * as React from "react";
import {
ArrowUp,
Bookmark,
ChevronDown,
Command,
Download,
Folder,
Lightbulb,
Mic,
MoreHorizontal,
PanelLeft,
Plus,
Puzzle,
Search,
Sparkles,
} from "lucide-react";
import {
ComposeSendButton,
ComposeTextarea,
ModelChip,
createCompose,
type ComposeProps,
} from "@agent-ui/react";
 
const Root = createCompose({
id: "kimi",
maxWidth: "max-w-none",
placeholder: "Ask anything, or task an agent...",
models: [
{ id: "k3-high", name: "K3 High", hint: "Best quality" },
{ id: "k3", name: "K3", hint: "Balanced" },
{ id: "k2", name: "K2", hint: "Fast" },
],
defaultModelId: "k3-high",
});
 
const NAV = [
{ icon: Sparkles, label: "My Kimi" },
{ icon: Puzzle, label: "Plugins" },
{ icon: Bookmark, label: "Scheduled" },
{ icon: Lightbulb, label: "Inspiration" },
{ icon: PanelLeft, label: "Slides" },
{ icon: Command, label: "3D Make" },
];
 
/** Kimi: quiet grey rail, monolithic wordmark, composer with attached action tray. */
function KimiComposeLayout() {
return (
<div className="flex min-h-[400px] w-full bg-white text-[13px] text-[#141414]">
<aside className="hidden w-[176px] shrink-0 flex-col @[560px]:flex bg-[#f7f7f7] px-2 py-2.5">
<div className="flex items-center gap-2 px-1">
<span className="grid h-6 w-6 place-items-center rounded-md bg-[#141414] text-[13px] font-black text-white">
K
</span>
<PanelLeft className="ml-auto h-4 w-4 text-black/40" aria-hidden="true" />
</div>
 
<button
type="button"
className="mt-3 flex w-full items-center gap-2 rounded-lg border border-black/[0.07] bg-white px-2 py-1.5 text-[11.5px] text-black/60 shadow-[0_1px_1px_rgba(0,0,0,0.02)]"
>
<Search className="h-3.5 w-3.5" aria-hidden="true" /> New chat
<span className="ml-auto flex items-center gap-0.5 text-[9px] text-black/35">
<Command className="h-2.5 w-2.5" aria-hidden="true" />K
</span>
</button>
 
<nav className="mt-2 flex flex-col gap-0.5">
{NAV.map(({ icon: Icon, label }) => (
<button
key={label}
type="button"
className="flex items-center gap-2.5 rounded-lg px-1.5 py-[5px] text-left text-[11.5px] hover:bg-black/[0.04]"
>
<Icon className="h-[14px] w-[14px] text-black/55" aria-hidden="true" />
{label}
{label === "3D Make" ? (
<span className="ml-1 rounded bg-[#e7efff] px-1 py-px text-[7.5px] font-semibold uppercase text-[#2f6bff]">
New
</span>
) : null}
</button>
))}
</nav>
 
<p className="mt-3 px-1.5 text-[9.5px] font-medium uppercase tracking-wide text-black/30">
Projects
</p>
<button
type="button"
className="flex items-center gap-2 rounded-lg px-1.5 py-1 text-left text-[11px] hover:bg-black/[0.04]"
>
<Folder className="h-3.5 w-3.5 text-black/50" aria-hidden="true" /> New project
</button>
<p className="mt-3 px-1.5 text-[9.5px] font-medium uppercase tracking-wide text-black/30">
Chats
</p>
<p className="px-1.5 py-1 text-[10px] text-black/35">Log in to sync chat history</p>
 
<div className="mt-auto flex flex-col gap-0.5">
{["Get App", "About us", "Language", "Get help"].map((label) => (
<button
key={label}
type="button"
className="flex items-center gap-2 rounded-lg px-1.5 py-[5px] text-left text-[10.5px] text-black/60 hover:bg-black/[0.04]"
>
{label}
<ChevronDown
className="ml-auto h-2.5 w-2.5 -rotate-90 opacity-30"
aria-hidden="true"
/>
</button>
))}
<button
type="button"
className="mt-1 flex items-center gap-2 rounded-lg px-1.5 py-1 text-[11px] font-medium hover:bg-black/[0.04]"
>
<Download className="h-3.5 w-3.5" aria-hidden="true" /> Log in
</button>
</div>
</aside>
 
<div className="relative flex min-w-0 flex-1 flex-col items-center px-5 pb-5 pt-3">
<div className="flex items-center gap-2 self-end">
<button
type="button"
className="rounded-full bg-[#f2f2f2] px-3 py-1.5 text-[10.5px] font-medium"
>
Log in
</button>
<button
type="button"
className="flex items-center gap-1.5 rounded-full bg-[#141414] px-3 py-1.5 text-[10.5px] font-medium text-white"
>
<Download className="h-3 w-3" aria-hidden="true" /> Download for Desktop
</button>
</div>
 
<div className="my-auto flex w-full flex-col items-center">
<h1 className="text-[40px] font-black leading-none tracking-[0.06em]">KIMI</h1>
 
<div
data-agent-id="compose-card"
className="mt-5 w-full max-w-[470px] overflow-hidden rounded-2xl border border-black/[0.08] bg-white shadow-[0_2px_14px_rgba(0,0,0,0.05)] transition-[border-color,box-shadow] duration-200 focus-within:border-black/20 focus-within:shadow-[0_4px_22px_rgba(0,0,0,0.09)]"
>
<div className="p-3">
<ComposeTextarea
aria-label="Ask anything, or task an agent"
placeholder="Ask anything, or task an agent..."
rows={2}
className="min-h-[44px] px-0.5 py-1 text-[14px] leading-6 placeholder:text-black/35"
/>
<div className="mt-1 flex items-center justify-between">
<button
type="button"
aria-label="Attach"
className="relative grid h-7 w-7 place-items-center rounded-full text-black/70 hover:bg-black/5"
>
<Plus className="h-4 w-4" aria-hidden="true" />
<span className="absolute right-0.5 top-0.5 h-1.5 w-1.5 rounded-full bg-[#2f6bff]" />
</button>
<div className="flex items-center gap-1">
<ModelChip
tone="light"
className="[&>button]:h-7 [&>button]:px-1 [&>button]:text-[11px] [&>button]:text-black/60 [&>button]:hover:bg-black/5"
/>
<button
type="button"
aria-label="Dictation"
className="grid h-7 w-7 place-items-center rounded-full text-black/50 hover:bg-black/5"
>
<Mic className="h-3.5 w-3.5" aria-hidden="true" />
</button>
<ComposeSendButton
aria-label="Send message"
className="h-7 w-7 bg-[#e6e6e6] text-black/40 hover:bg-[#dcdcdc] disabled:bg-[#e6e6e6] disabled:text-black/40 disabled:opacity-100"
icon={<ArrowUp className="h-3.5 w-3.5" strokeWidth={2.3} />}
/>
</div>
</div>
</div>
<div className="flex items-center gap-4 border-t border-black/[0.05] bg-[#f7f7f7] px-3 py-1.5 text-[10px] text-black/55">
<span className="flex items-center gap-1">
<Folder className="h-3 w-3" aria-hidden="true" /> Choose project
</span>
<span className="flex items-center gap-1">
<Puzzle className="h-3 w-3" aria-hidden="true" /> Plugins
</span>
</div>
</div>
 
<div className="mt-3 flex w-full max-w-[470px] flex-wrap items-center justify-center gap-1.5">
{["3D Make", "Slides", "Deep Research", "Docs", "Build", "Sheets"].map((label) => (
<button
key={label}
type="button"
className="rounded-full border border-black/[0.08] bg-white px-2.5 py-1 text-[10px] text-black/60 hover:bg-black/[0.03]"
>
{label}
</button>
))}
<button
type="button"
aria-label="More tools"
className="grid h-5 w-5 place-items-center rounded-full border border-black/[0.08] bg-white text-black/40"
>
<MoreHorizontal className="h-3 w-3" aria-hidden="true" />
</button>
</div>
</div>
 
<p className="flex items-center gap-1 text-[9px] text-black/35">
<Lightbulb className="h-3 w-3" aria-hidden="true" /> Explore inspiration · AI-generated,
for reference only
</p>
</div>
</div>
);
}
 
export function KimiCompose(props: ComposeProps) {
return (
<Root {...props}>
<KimiComposeLayout />
</Root>
);
}
 

Built with

The block imports these Agent UI primitives. Each one is a package export with its own docs page, so you can change the layout without giving up the behaviour.

Accessibility

All controls expose accessible names; the textarea supports Enter to send and Shift+Enter for a new line.

Kimi also has a full product page.

Metadata, model list, and the same block in a dedicated route.

Open Kimi
Use it with the rest of the library

KimiCompose composes with MessageList, ChatShell, useChat, and the provider compose blocks. Browse the full reference or see all components in the gallery.

231 lines · copy-ready