{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "context",
  "dependencies": [
    "ai"
  ],
  "registryDependencies": [
    "https://taki-ui.com/r/button.json",
    "https://taki-ui.com/r/badge.json",
    "https://taki-ui.com/r/disclosure.json",
    "https://taki-ui.com/r/tooltip.json"
  ],
  "files": [
    {
      "path": "registry/new-york/ai-elements/context.tsx",
      "content": "\"use client\"\n\nimport { createContext, useContext, type ComponentProps } from \"react\"\nimport type { LanguageModelUsage } from \"ai\"\nimport { estimateCost, type ModelId } from \"tokenlens\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/new-york/ui/button\"\nimport { HoverCard, HoverCardContent } from \"@/registry/new-york/ui/hover-card\"\nimport { ProgressBar } from \"@/registry/new-york/ui/progress-bar\"\n\nconst PERCENT_MAX = 100\nconst ICON_RADIUS = 10\nconst ICON_VIEWBOX = 24\nconst ICON_CENTER = 12\nconst ICON_STROKE_WIDTH = 2\n\ntype ContextSchema = {\n  usedTokens: number\n  maxTokens: number\n  usage?: LanguageModelUsage\n  modelId?: ModelId\n}\n\nconst ContextContext = createContext<ContextSchema | null>(null)\n\nconst useContextValue = () => {\n  const context = useContext(ContextContext)\n\n  if (!context) {\n    throw new Error(\"Context components must be used within Context\")\n  }\n\n  return context\n}\n\nexport type ContextProps = ComponentProps<typeof HoverCard> & ContextSchema\n\nexport const Context = ({\n  usedTokens,\n  maxTokens,\n  usage,\n  modelId,\n  ...props\n}: ContextProps) => (\n  <ContextContext.Provider\n    value={{\n      usedTokens,\n      maxTokens,\n      usage,\n      modelId,\n    }}\n  >\n    <HoverCard closeDelay={0} openDelay={0} {...props} />\n  </ContextContext.Provider>\n)\n\nconst ContextIcon = () => {\n  const { usedTokens, maxTokens } = useContextValue()\n  const circumference = 2 * Math.PI * ICON_RADIUS\n  const usedPercent = usedTokens / maxTokens\n  const dashOffset = circumference * (1 - usedPercent)\n\n  return (\n    <svg\n      aria-label=\"Model context usage\"\n      height=\"20\"\n      role=\"img\"\n      style={{ color: \"currentcolor\" }}\n      viewBox={`0 0 ${ICON_VIEWBOX} ${ICON_VIEWBOX}`}\n      width=\"20\"\n    >\n      <circle\n        cx={ICON_CENTER}\n        cy={ICON_CENTER}\n        fill=\"none\"\n        opacity=\"0.25\"\n        r={ICON_RADIUS}\n        stroke=\"currentColor\"\n        strokeWidth={ICON_STROKE_WIDTH}\n      />\n      <circle\n        cx={ICON_CENTER}\n        cy={ICON_CENTER}\n        fill=\"none\"\n        opacity=\"0.7\"\n        r={ICON_RADIUS}\n        stroke=\"currentColor\"\n        strokeDasharray={`${circumference} ${circumference}`}\n        strokeDashoffset={dashOffset}\n        strokeLinecap=\"round\"\n        strokeWidth={ICON_STROKE_WIDTH}\n        style={{ transformOrigin: \"center\", transform: \"rotate(-90deg)\" }}\n      />\n    </svg>\n  )\n}\n\nexport type ContextTriggerProps = ComponentProps<typeof Button>\n\nexport const ContextTrigger = ({ children, ...props }: ContextTriggerProps) => {\n  const { usedTokens, maxTokens } = useContextValue()\n  const usedPercent = usedTokens / maxTokens\n  const renderedPercent = new Intl.NumberFormat(\"en-US\", {\n    style: \"percent\",\n    maximumFractionDigits: 1,\n  }).format(usedPercent)\n\n  return (\n    children ?? (\n      <Button type=\"button\" variant=\"ghost\" {...props}>\n        <span className=\"text-muted-foreground font-medium\">\n          {renderedPercent}\n        </span>\n        <ContextIcon />\n      </Button>\n    )\n  )\n}\n\nexport type ContextContentProps = ComponentProps<typeof HoverCardContent>\n\nexport const ContextContent = ({\n  className,\n  offset = 6,\n  ...props\n}: ContextContentProps) => (\n  <HoverCardContent\n    offset={offset}\n    className={cn(\"min-w-[240px] divide-y overflow-hidden p-0\", className)}\n    {...props}\n  />\n)\n\nexport type ContextContentHeader = ComponentProps<\"div\">\n\nexport const ContextContentHeader = ({\n  children,\n  className,\n  ...props\n}: ContextContentHeader) => {\n  const { usedTokens, maxTokens } = useContextValue()\n  const usedPercent = usedTokens / maxTokens\n  const displayPct = new Intl.NumberFormat(\"en-US\", {\n    style: \"percent\",\n    maximumFractionDigits: 1,\n  }).format(usedPercent)\n  const used = new Intl.NumberFormat(\"en-US\", {\n    notation: \"compact\",\n  }).format(usedTokens)\n  const total = new Intl.NumberFormat(\"en-US\", {\n    notation: \"compact\",\n  }).format(maxTokens)\n\n  return (\n    <div className={cn(\"w-full space-y-2 p-3\", className)} {...props}>\n      {children ?? (\n        <>\n          <div className=\"flex items-center justify-between gap-3 text-xs\">\n            <p>{displayPct}</p>\n            <p className=\"text-muted-foreground font-mono\">\n              {used} / {total}\n            </p>\n          </div>\n          <div className=\"space-y-2\">\n            <ProgressBar\n              className=\"bg-muted\"\n              value={usedPercent * PERCENT_MAX}\n            />\n          </div>\n        </>\n      )}\n    </div>\n  )\n}\n\nexport type ContextContentBody = ComponentProps<\"div\">\n\nexport const ContextContentBody = ({\n  children,\n  className,\n  ...props\n}: ContextContentBody) => (\n  <div className={cn(\"w-full p-3\", className)} {...props}>\n    {children}\n  </div>\n)\n\nexport type ContextContentFooter = ComponentProps<\"div\">\n\nexport const ContextContentFooter = ({\n  children,\n  className,\n  ...props\n}: ContextContentFooter) => {\n  const { modelId, usage } = useContextValue()\n  const costUSD = modelId\n    ? estimateCost({\n        modelId,\n        usage: {\n          input: usage?.inputTokens ?? 0,\n          output: usage?.outputTokens ?? 0,\n        },\n      }).totalUSD\n    : undefined\n  const totalCost = new Intl.NumberFormat(\"en-US\", {\n    style: \"currency\",\n    currency: \"USD\",\n  }).format(costUSD ?? 0)\n\n  return (\n    <div\n      className={cn(\n        \"bg-secondary flex w-full items-center justify-between gap-3 p-3 text-xs\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? (\n        <>\n          <span className=\"text-muted-foreground\">Total cost</span>\n          <span>{totalCost}</span>\n        </>\n      )}\n    </div>\n  )\n}\n\nexport type ContextInputUsageProps = ComponentProps<\"div\">\n\nexport const ContextInputUsage = ({\n  className,\n  children,\n  ...props\n}: ContextInputUsageProps) => {\n  const { usage, modelId } = useContextValue()\n  const inputTokens = usage?.inputTokens ?? 0\n\n  if (children) {\n    return children\n  }\n\n  if (!inputTokens) {\n    return null\n  }\n\n  const inputCost = modelId\n    ? estimateCost({\n        modelId,\n        usage: { input: inputTokens, output: 0 },\n      }).totalUSD\n    : undefined\n  const inputCostText = new Intl.NumberFormat(\"en-US\", {\n    style: \"currency\",\n    currency: \"USD\",\n  }).format(inputCost ?? 0)\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-between text-xs\", className)}\n      {...props}\n    >\n      <span className=\"text-muted-foreground\">Input</span>\n      <TokensWithCost costText={inputCostText} tokens={inputTokens} />\n    </div>\n  )\n}\n\nexport type ContextOutputUsageProps = ComponentProps<\"div\">\n\nexport const ContextOutputUsage = ({\n  className,\n  children,\n  ...props\n}: ContextOutputUsageProps) => {\n  const { usage, modelId } = useContextValue()\n  const outputTokens = usage?.outputTokens ?? 0\n\n  if (children) {\n    return children\n  }\n\n  if (!outputTokens) {\n    return null\n  }\n\n  const outputCost = modelId\n    ? estimateCost({\n        modelId,\n        usage: { input: 0, output: outputTokens },\n      }).totalUSD\n    : undefined\n  const outputCostText = new Intl.NumberFormat(\"en-US\", {\n    style: \"currency\",\n    currency: \"USD\",\n  }).format(outputCost ?? 0)\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-between text-xs\", className)}\n      {...props}\n    >\n      <span className=\"text-muted-foreground\">Output</span>\n      <TokensWithCost costText={outputCostText} tokens={outputTokens} />\n    </div>\n  )\n}\n\nexport type ContextReasoningUsageProps = ComponentProps<\"div\">\n\nexport const ContextReasoningUsage = ({\n  className,\n  children,\n  ...props\n}: ContextReasoningUsageProps) => {\n  const { usage, modelId } = useContextValue()\n  const reasoningTokens = usage?.reasoningTokens ?? 0\n\n  if (children) {\n    return children\n  }\n\n  if (!reasoningTokens) {\n    return null\n  }\n\n  const reasoningCost = modelId\n    ? estimateCost({\n        modelId,\n        usage: { reasoningTokens },\n      }).totalUSD\n    : undefined\n  const reasoningCostText = new Intl.NumberFormat(\"en-US\", {\n    style: \"currency\",\n    currency: \"USD\",\n  }).format(reasoningCost ?? 0)\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-between text-xs\", className)}\n      {...props}\n    >\n      <span className=\"text-muted-foreground\">Reasoning</span>\n      <TokensWithCost costText={reasoningCostText} tokens={reasoningTokens} />\n    </div>\n  )\n}\n\nexport type ContextCacheUsageProps = ComponentProps<\"div\">\n\nexport const ContextCacheUsage = ({\n  className,\n  children,\n  ...props\n}: ContextCacheUsageProps) => {\n  const { usage, modelId } = useContextValue()\n  const cacheTokens = usage?.cachedInputTokens ?? 0\n\n  if (children) {\n    return children\n  }\n\n  if (!cacheTokens) {\n    return null\n  }\n\n  const cacheCost = modelId\n    ? estimateCost({\n        modelId,\n        usage: { cacheReads: cacheTokens, input: 0, output: 0 },\n      }).totalUSD\n    : undefined\n  const cacheCostText = new Intl.NumberFormat(\"en-US\", {\n    style: \"currency\",\n    currency: \"USD\",\n  }).format(cacheCost ?? 0)\n\n  return (\n    <div\n      className={cn(\"flex items-center justify-between text-xs\", className)}\n      {...props}\n    >\n      <span className=\"text-muted-foreground\">Cache</span>\n      <TokensWithCost costText={cacheCostText} tokens={cacheTokens} />\n    </div>\n  )\n}\n\nconst TokensWithCost = ({\n  tokens,\n  costText,\n}: {\n  tokens?: number\n  costText?: string\n}) => (\n  <span>\n    {tokens === undefined\n      ? \"—\"\n      : new Intl.NumberFormat(\"en-US\", {\n          notation: \"compact\",\n        }).format(tokens)}\n    {costText ? (\n      <span className=\"text-muted-foreground ml-2\">• {costText}</span>\n    ) : null}\n  </span>\n)\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}