model-selector.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import {
  2. Command,
  3. CommandDialog,
  4. CommandEmpty,
  5. CommandGroup,
  6. CommandInput,
  7. CommandItem,
  8. CommandList,
  9. CommandSeparator,
  10. CommandShortcut,
  11. } from '@/components/ui/command';
  12. import { Dialog, DialogContent, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
  13. import { cn } from '@/lib/utils';
  14. import type { ComponentProps, ReactNode } from 'react';
  15. export type ModelSelectorProps = ComponentProps<typeof Dialog>;
  16. export const ModelSelector = (props: ModelSelectorProps) => <Dialog {...props} />;
  17. export type ModelSelectorTriggerProps = ComponentProps<typeof DialogTrigger>;
  18. export const ModelSelectorTrigger = (props: ModelSelectorTriggerProps) => (
  19. <DialogTrigger {...props} />
  20. );
  21. export type ModelSelectorContentProps = ComponentProps<typeof DialogContent> & {
  22. title?: ReactNode;
  23. };
  24. export const ModelSelectorContent = ({
  25. className,
  26. children,
  27. title = 'Model Selector',
  28. ...props
  29. }: ModelSelectorContentProps) => (
  30. <DialogContent className={cn('p-0', className)} {...props}>
  31. <DialogTitle className="sr-only">{title}</DialogTitle>
  32. <Command className="**:data-[slot=command-input-wrapper]:h-auto">{children}</Command>
  33. </DialogContent>
  34. );
  35. export type ModelSelectorDialogProps = ComponentProps<typeof CommandDialog>;
  36. export const ModelSelectorDialog = (props: ModelSelectorDialogProps) => (
  37. <CommandDialog {...props} />
  38. );
  39. export type ModelSelectorInputProps = ComponentProps<typeof CommandInput>;
  40. export const ModelSelectorInput = ({ className, ...props }: ModelSelectorInputProps) => (
  41. <CommandInput className={cn('h-auto py-3.5', className)} {...props} />
  42. );
  43. export type ModelSelectorListProps = ComponentProps<typeof CommandList>;
  44. export const ModelSelectorList = (props: ModelSelectorListProps) => <CommandList {...props} />;
  45. export type ModelSelectorEmptyProps = ComponentProps<typeof CommandEmpty>;
  46. export const ModelSelectorEmpty = (props: ModelSelectorEmptyProps) => <CommandEmpty {...props} />;
  47. export type ModelSelectorGroupProps = ComponentProps<typeof CommandGroup>;
  48. export const ModelSelectorGroup = (props: ModelSelectorGroupProps) => <CommandGroup {...props} />;
  49. export type ModelSelectorItemProps = ComponentProps<typeof CommandItem>;
  50. export const ModelSelectorItem = (props: ModelSelectorItemProps) => <CommandItem {...props} />;
  51. export type ModelSelectorShortcutProps = ComponentProps<typeof CommandShortcut>;
  52. export const ModelSelectorShortcut = (props: ModelSelectorShortcutProps) => (
  53. <CommandShortcut {...props} />
  54. );
  55. export type ModelSelectorSeparatorProps = ComponentProps<typeof CommandSeparator>;
  56. export const ModelSelectorSeparator = (props: ModelSelectorSeparatorProps) => (
  57. <CommandSeparator {...props} />
  58. );
  59. export type ModelSelectorLogoProps = Omit<ComponentProps<'img'>, 'src' | 'alt'> & {
  60. provider:
  61. | 'moonshotai-cn'
  62. | 'lucidquery'
  63. | 'moonshotai'
  64. | 'zai-coding-plan'
  65. | 'alibaba'
  66. | 'xai'
  67. | 'vultr'
  68. | 'nvidia'
  69. | 'upstage'
  70. | 'groq'
  71. | 'github-copilot'
  72. | 'mistral'
  73. | 'vercel'
  74. | 'nebius'
  75. | 'deepseek'
  76. | 'alibaba-cn'
  77. | 'google-vertex-anthropic'
  78. | 'venice'
  79. | 'chutes'
  80. | 'cortecs'
  81. | 'github-models'
  82. | 'togetherai'
  83. | 'azure'
  84. | 'baseten'
  85. | 'huggingface'
  86. | 'opencode'
  87. | 'fastrouter'
  88. | 'google'
  89. | 'google-vertex'
  90. | 'cloudflare-workers-ai'
  91. | 'inception'
  92. | 'wandb'
  93. | 'openai'
  94. | 'zhipuai-coding-plan'
  95. | 'perplexity'
  96. | 'openrouter'
  97. | 'zenmux'
  98. | 'v0'
  99. | 'iflowcn'
  100. | 'synthetic'
  101. | 'deepinfra'
  102. | 'zhipuai'
  103. | 'submodel'
  104. | 'zai'
  105. | 'inference'
  106. | 'requesty'
  107. | 'morph'
  108. | 'lmstudio'
  109. | 'anthropic'
  110. | 'aihubmix'
  111. | 'fireworks-ai'
  112. | 'modelscope'
  113. | 'llama'
  114. | 'scaleway'
  115. | 'amazon-bedrock'
  116. | 'cerebras'
  117. | (string & {});
  118. };
  119. export const ModelSelectorLogo = ({ provider, className, ...props }: ModelSelectorLogoProps) => (
  120. <img
  121. {...props}
  122. alt={`${provider} logo`}
  123. className={cn('size-3 dark:invert', className)}
  124. height={12}
  125. src={`https://models.dev/logos/${provider}.svg`}
  126. width={12}
  127. />
  128. );
  129. export type ModelSelectorLogoGroupProps = ComponentProps<'div'>;
  130. export const ModelSelectorLogoGroup = ({ className, ...props }: ModelSelectorLogoGroupProps) => (
  131. <div
  132. className={cn(
  133. '-space-x-1 flex shrink-0 items-center [&>img]:rounded-full [&>img]:bg-background [&>img]:p-px [&>img]:ring-1 dark:[&>img]:bg-foreground',
  134. className,
  135. )}
  136. {...props}
  137. />
  138. );
  139. export type ModelSelectorNameProps = ComponentProps<'span'>;
  140. export const ModelSelectorName = ({ className, ...props }: ModelSelectorNameProps) => (
  141. <span className={cn('flex-1 truncate text-left', className)} {...props} />
  142. );