diff --git a/studio/frontend/src/components/app-sidebar.tsx b/studio/frontend/src/components/app-sidebar.tsx index b1dc286df5..88a0b03a21 100644 --- a/studio/frontend/src/components/app-sidebar.tsx +++ b/studio/frontend/src/components/app-sidebar.tsx @@ -31,16 +31,14 @@ import { import { useAnimatedThemeToggle } from "@/components/ui/animated-theme-toggler"; import { cn } from "@/lib/utils"; import { - Book03Icon, ChefHatIcon, ColumnInsertIcon, CursorInfo02Icon, Delete02Icon, Download03Icon, GemIcon, - MessageSearch01Icon, + Key01Icon, Search01Icon, - NewReleasesIcon, PowerIcon, PencilEdit02Icon, LayoutAlignLeftIcon, @@ -547,6 +545,15 @@ export function AppSidebar() { Settings ⌘, + useSettingsDialogStore.getState().openDialog("api-keys")} + > + + API Keys + + New + + } onSelect={(e) => { e.preventDefault(); toggleTheme(); }} @@ -571,47 +578,6 @@ export function AppSidebar() { - - - - - Learn More - - - - - - What's New - - - - - - Feedback - - - - setShutdownOpen(true)}> Shutdown diff --git a/studio/frontend/src/features/settings/components/usage-examples.tsx b/studio/frontend/src/features/settings/components/usage-examples.tsx index a2dc2c3774..a8f8ce31a6 100644 --- a/studio/frontend/src/features/settings/components/usage-examples.tsx +++ b/studio/frontend/src/features/settings/components/usage-examples.tsx @@ -4,12 +4,11 @@ import { cn } from "@/lib/utils"; import { copyToClipboard } from "@/lib/copy-to-clipboard"; import { - ArrowDown01Icon, + ArrowUpRight01Icon, Copy01Icon, Tick02Icon, } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; -import { AnimatePresence, motion } from "motion/react"; import { useMemo, useState } from "react"; type Lang = "curl" | "python" | "tools"; @@ -20,6 +19,29 @@ const TABS: { id: Lang; label: string }[] = [ { id: "tools", label: "Tools" }, ]; +const DOC_LINKS = [ + { + label: "Claude Code", + href: "https://unsloth.ai/docs/basics/claude-code", + }, + { + label: "Codex", + href: "https://unsloth.ai/docs/basics/codex", + }, + { + label: "OpenClaw", + href: "https://unsloth.ai/docs/integrations/openclaw", + }, + { + label: "OpenCode", + href: "https://unsloth.ai/docs/integrations/opencode", + }, + { + label: "Hermes Agent", + href: "https://unsloth.ai/docs/integrations/hermes-agent", + }, +]; + function buildSnippets(base: string) { return { curl: `curl ${base}/v1/chat/completions \\ @@ -56,7 +78,6 @@ for chunk in response: } export function UsageExamples() { - const [open, setOpen] = useState(false); const [lang, setLang] = useState("curl"); const [copied, setCopied] = useState(false); const snippets = useMemo( @@ -76,71 +97,62 @@ export function UsageExamples() { return ( - setOpen((o) => !o)} - className="flex w-fit items-center gap-1.5 rounded text-xs font-medium text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" - aria-expanded={open} - > - - {open ? "Hide usage examples" : "Show usage examples"} - - - - {open && ( - - - - - {TABS.map((t) => { - const active = lang === t.id; - return ( - setLang(t.id)} - aria-pressed={active} - className={cn( - "rounded px-2 py-1 text-[11px] font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", - active - ? "bg-background text-foreground shadow-border" - : "text-muted-foreground hover:text-foreground", - )} - > - {t.label} - - ); - })} - + Usage examples + + + + {TABS.map((t) => { + const active = lang === t.id; + return ( setLang(t.id)} + aria-pressed={active} + className={cn( + "rounded px-2 py-1 text-[11px] font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", + active + ? "bg-background text-foreground shadow-border" + : "text-muted-foreground hover:text-foreground", + )} > - - {copied ? "Copied" : "Copy"} + {t.label} - - - {snippets[lang]} - - - - )} - + ); + })} + + + + {copied ? "Copied" : "Copy"} + + + + {snippets[lang]} + + + Setup docs: + {DOC_LINKS.map((link) => ( + + {link.label} + + + ))} + + ); } diff --git a/studio/frontend/src/features/settings/settings-dialog.tsx b/studio/frontend/src/features/settings/settings-dialog.tsx index bb22fcb89c..423b5c74f0 100644 --- a/studio/frontend/src/features/settings/settings-dialog.tsx +++ b/studio/frontend/src/features/settings/settings-dialog.tsx @@ -31,6 +31,7 @@ interface TabDef { id: SettingsTab; label: string; icon: typeof Settings02Icon; + badge?: string; } const TABS: TabDef[] = [ @@ -38,8 +39,8 @@ const TABS: TabDef[] = [ { id: "profile", label: "Profile", icon: UserIcon }, { id: "appearance", label: "Appearance", icon: PaintBrush02Icon }, { id: "chat", label: "Chat", icon: Message01Icon }, - { id: "api-keys", label: "API Keys", icon: Key01Icon }, - { id: "about", label: "About", icon: SparklesIcon }, + { id: "api-keys", label: "API Keys", icon: Key01Icon, badge: "New" }, + { id: "about", label: "Help", icon: SparklesIcon }, ]; function renderTab(tab: SettingsTab) { @@ -121,7 +122,12 @@ export function SettingsDialog() { strokeWidth={1.5} className="relative z-10 size-[18px]" /> - {tab.label} + {tab.label} + {tab.badge ? ( + + {tab.badge} + + ) : null} ); })} diff --git a/studio/frontend/src/features/settings/tabs/about-tab.tsx b/studio/frontend/src/features/settings/tabs/about-tab.tsx index bb4454aa43..9629900237 100644 --- a/studio/frontend/src/features/settings/tabs/about-tab.tsx +++ b/studio/frontend/src/features/settings/tabs/about-tab.tsx @@ -12,6 +12,7 @@ import { Book03Icon, Cancel01Icon, MessageNotification01Icon, + NewReleasesIcon, } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; import { useEffect, useState } from "react"; @@ -48,9 +49,9 @@ export function AboutTab() { return ( - About + Help - Unsloth Studio build info and support. + Documentation, release notes, feedback, and Studio build info. @@ -79,6 +80,18 @@ export function AboutTab() { + + + + What's new + + + API Keys - Access Unsloth Studio programmatically via the OpenAI-compatible API. + Access Unsloth programmatically via the OpenAI-compatible API.{" "} + + Read the API docs + + .
- {snippets[lang]} -
+ {snippets[lang]} +
- Unsloth Studio build info and support. + Documentation, release notes, feedback, and Studio build info.
- Access Unsloth Studio programmatically via the OpenAI-compatible API. + Access Unsloth programmatically via the OpenAI-compatible API.{" "} + + Read the API docs + + .