Knowledge cutoff notice A date is information; a permanent “may be outdated” banner is not. The same question answered from training data and from live sources differ by whether a source list is present, and questions about current state are detectable before the answer is written. npx shadcn@latest add button Tokens this needs: --card, --card-foreground, --primary, --muted, --muted-foreground, --border, --status-warn The status, chart, scale, state and direction names are an extension, not a rename. shadcn has --destructive and five --chart-* and nothing else in this territory. ──────────────────────────────────────────────────────────────────────── // CutoffNotice.tsx ──────────────────────────────────────────────────────────────────────── import type { ReactNode } from "react"; import { Button } from "@/components/ui/button"; import { isTimeSensitive } from "./timeSensitive"; /** A cutoff belongs to a model. A product with three models has three of * them, so the notice takes the model rather than a date from a config. */ export type Model = { name: string; cutoff: Date }; type Props = { /** The answer this notice is attached to. */ children: ReactNode; /** What was asked. Time-sensitive questions get the notice; the rest do not. */ question: string; model: Model; /** What the answer was checked against. A non-empty list suppresses the * notice: the sources are the signal, and their absence is what this line * has to say out loud. */ sources?: string[]; /** The one-click path from a recalled answer to a checked one. */ onSearch: () => void; }; const monthYear = (d: Date) => d.toLocaleDateString("en", { month: "long", year: "numeric", timeZone: "UTC" }); export function CutoffNotice({ children, question, model, sources = [], onSearch }: Props) { const show = sources.length === 0 && isTimeSensitive(question); return (
{children} {show && (
{/* A date rather than "may be outdated". It is one of the few limits that can be given exactly, and a date lets the viewer reason about whether it matters to their question. */} from training data to {monthYear(model.cutoff)}

no sources, so nothing was checked

)}
); } ──────────────────────────────────────────────────────────────────────── // timeSensitive.ts ──────────────────────────────────────────────────────────────────────── /** * The trigger keys on the question, not the answer. Current state, prices, * people in roles, versions, availability, and anything naming a recent year * are time-sensitive by construction, and every one of them can be spotted * before a token is generated. */ const CUES: RegExp[] = [ /\b(who|which)\b.*\b(runs?|leads?|owns?|heads?|ceo|founder|maintainer)\b/i, /\b(cost|costs|price|pricing|how much|per (month|seat|year))\b/i, /\b(latest|current|newest|version|release|supported|maintained|deprecated)\b/i, /\b(now|today|currently|still|yet|any ?more|these days)\b/i, /\b20[2-9]\d\b/, ]; export const isTimeSensitive = (question: string) => CUES.some((re) => re.test(question)); ──────────────────────────────────────────────────────────────────────── // demo.tsx ──────────────────────────────────────────────────────────────────────── import { CutoffNotice } from "./CutoffNotice"; /** * A question about current state, answered from training data. The question * trips the trigger, there is no source list, so the answer carries the date. * Search would rerun the question against live sources and hand back a * source list, at which point the notice goes away on its own. */ const QUESTION = "Does Vite 5 still get security fixes, or do we have to move the build to 6?"; export default function Demo() { return (
{}} >

Vite 5 is still receiving security fixes but no new features. Vite 6 changed the default environment API, so moving the build means updating any plugin that reads config.server directly. Your slow build is more likely the three unbundled icon packs than the Vite version.

); }