diff --git a/apps/www/content/3.components/1.chatbot/model-selector.md b/apps/www/content/3.components/1.chatbot/model-selector.md
new file mode 100644
index 0000000..11174c1
--- /dev/null
+++ b/apps/www/content/3.components/1.chatbot/model-selector.md
@@ -0,0 +1,344 @@
+---
+title: Model Selector
+description: A searchable command palette for selecting AI models in your chat interface.
+icon: lucide:square-mouse-pointer
+---
+
+The `Model Selector` component provides a searchable command palette interface for selecting AI models. It's built on top of the cmdk library and provides a keyboard-navigable interface with search functionality.
+
+:::ComponentLoader{label="Preview" componentName="ModelSelector"}
+:::
+
+## Install using CLI
+
+::tabs{variant="card"}
+ ::div{label="ai-elements-vue"}
+ ```sh
+ npx ai-elements-vue@latest add model-selector
+ ```
+ ::
+ ::div{label="shadcn-vue"}
+
+ ```sh
+ npx shadcn-vue@latest add https://registry.ai-elements-vue.com/model-selector.json
+ ```
+ ::
+::
+
+## Install Manually
+
+Copy and paste the following code in the same folder.
+
+:::code-group
+```vue [ModelSelector.vue] height=260 collapse
+
+
+
+
+
+```
+
+```vue [ModelSelectorTrigger.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorContent.vue] height=260 collapse
+
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorDialog.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorInput.vue] height=260 collapse
+
+
+
+
+
+```
+
+```vue [ModelSelectorList.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorEmpty.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorGroup.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorItem.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorShortcut.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorSeparator.vue] height=260 collapse
+
+
+
+
+
+```
+
+```vue [ModelSelectorLogo.vue] height=260 collapse
+
+
+
+
+
+```
+
+```vue [ModelSelectorLogoGroup.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```vue [ModelSelectorName.vue] height=260 collapse
+
+
+
+
+
+
+
+```
+
+```ts [index.ts] height=260 collapse
+export { default as ModelSelector } from './ModelSelector.vue'
+export { default as ModelSelectorContent } from './ModelSelectorContent.vue'
+export { default as ModelSelectorDialog } from './ModelSelectorDialog.vue'
+export { default as ModelSelectorEmpty } from './ModelSelectorEmpty.vue'
+export { default as ModelSelectorGroup } from './ModelSelectorGroup.vue'
+export { default as ModelSelectorInput } from './ModelSelectorInput.vue'
+export { default as ModelSelectorItem } from './ModelSelectorItem.vue'
+export { default as ModelSelectorList } from './ModelSelectorList.vue'
+export { default as ModelSelectorLogo } from './ModelSelectorLogo.vue'
+export { default as ModelSelectorLogoGroup } from './ModelSelectorLogoGroup.vue'
+export { default as ModelSelectorName } from './ModelSelectorName.vue'
+export { default as ModelSelectorSeparator } from './ModelSelectorSeparator.vue'
+export { default as ModelSelectorShortcut } from './ModelSelectorShortcut.vue'
+export { default as ModelSelectorTrigger } from './ModelSelectorTrigger.vue'
+```
+:::
+
+## Features
+
+- Searchable interface with keyboard navigation
+- Fuzzy search filtering across model names
+- Grouped model organization by provider
+- Keyboard shortcuts support
+- Empty state handling
+- Customizable styling with Tailwind CSS
+- Built on cmdk for excellent accessibility
+- Support for both inline and dialog modes
+- TypeScript support with proper type definitions
+
+## Props
+
+### ``
+
+:::field-group
+ ::field{name="title" type="string" defaultValue="'Model Selector'"}
+ Title of the model selector.
+ ::
+
+ ::field{name="class" type="string"}
+ Additional classes applied to the component.
+ ::
+:::
+
+### ``
+
+:::field-group
+ ::field{name="class" type="string"}
+ Additional classes applied to the component.
+ ::
+:::
+
+### ``
+
+:::field-group
+ ::field{name="provider" type="string"}
+ The AI provider name. Supports major providers like "openai", "anthropic", "google", "mistral", etc.
+ ::
+
+ ::field{name="class" type="string"}
+ Additional classes applied to the component.
+ ::
+:::
+
+### ``
+
+:::field-group
+ ::field{name="class" type="string"}
+ Additional classes applied to the component.
+ ::
+:::
+
+### ``
+
+:::field-group
+ ::field{name="class" type="string"}
+ Additional classes applied to the component.
+ ::
+:::
diff --git a/apps/www/plugins/ai-elements.ts b/apps/www/plugins/ai-elements.ts
index 85a6203..ecc51da 100644
--- a/apps/www/plugins/ai-elements.ts
+++ b/apps/www/plugins/ai-elements.ts
@@ -20,6 +20,7 @@ import {
LoaderSizes,
Message,
MessageMarkdown,
+ ModelSelector,
OpenInChat,
Plan,
PromptInput,
@@ -79,6 +80,7 @@ export default defineNuxtPlugin((nuxtApp) => {
vueApp.component('CodeBlockDark', CodeBlockDark)
vueApp.component('Checkpoint', Checkpoint)
vueApp.component('Workflow', Workflow)
+ vueApp.component('ModelSelector', ModelSelector)
vueApp.component('Context', Context)
vueApp.component('Confirmation', Confirmation)
vueApp.component('ConfirmationAccepted', ConfirmationAccepted)
diff --git a/packages/elements/src/index.ts b/packages/elements/src/index.ts
index 7634bc1..a570bc5 100644
--- a/packages/elements/src/index.ts
+++ b/packages/elements/src/index.ts
@@ -11,6 +11,7 @@ export * from './image'
export * from './inline-citation'
export * from './loader'
export * from './message'
+export * from './model-selector'
export * from './open-in-chat'
export * from './plan'
export * from './prompt-input'
diff --git a/packages/elements/src/model-selector/ModelSelector.vue b/packages/elements/src/model-selector/ModelSelector.vue
new file mode 100644
index 0000000..772b021
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelector.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorContent.vue b/packages/elements/src/model-selector/ModelSelectorContent.vue
new file mode 100644
index 0000000..62dd3e1
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorContent.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+ {{ props.title }}
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorDialog.vue b/packages/elements/src/model-selector/ModelSelectorDialog.vue
new file mode 100644
index 0000000..bb18879
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorDialog.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorEmpty.vue b/packages/elements/src/model-selector/ModelSelectorEmpty.vue
new file mode 100644
index 0000000..abcdd7d
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorEmpty.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorGroup.vue b/packages/elements/src/model-selector/ModelSelectorGroup.vue
new file mode 100644
index 0000000..e894040
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorGroup.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorInput.vue b/packages/elements/src/model-selector/ModelSelectorInput.vue
new file mode 100644
index 0000000..352ff7f
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorInput.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorItem.vue b/packages/elements/src/model-selector/ModelSelectorItem.vue
new file mode 100644
index 0000000..0df3de2
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorItem.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorList.vue b/packages/elements/src/model-selector/ModelSelectorList.vue
new file mode 100644
index 0000000..9f61b70
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorList.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorLogo.vue b/packages/elements/src/model-selector/ModelSelectorLogo.vue
new file mode 100644
index 0000000..c074f3d
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorLogo.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorLogoGroup.vue b/packages/elements/src/model-selector/ModelSelectorLogoGroup.vue
new file mode 100644
index 0000000..3f14262
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorLogoGroup.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorName.vue b/packages/elements/src/model-selector/ModelSelectorName.vue
new file mode 100644
index 0000000..e94cd25
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorName.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorSeparator.vue b/packages/elements/src/model-selector/ModelSelectorSeparator.vue
new file mode 100644
index 0000000..e916066
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorSeparator.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorShortcut.vue b/packages/elements/src/model-selector/ModelSelectorShortcut.vue
new file mode 100644
index 0000000..5539093
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorShortcut.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/ModelSelectorTrigger.vue b/packages/elements/src/model-selector/ModelSelectorTrigger.vue
new file mode 100644
index 0000000..b2de0a2
--- /dev/null
+++ b/packages/elements/src/model-selector/ModelSelectorTrigger.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/packages/elements/src/model-selector/index.ts b/packages/elements/src/model-selector/index.ts
new file mode 100644
index 0000000..35233e4
--- /dev/null
+++ b/packages/elements/src/model-selector/index.ts
@@ -0,0 +1,14 @@
+export { default as ModelSelector } from './ModelSelector.vue'
+export { default as ModelSelectorContent } from './ModelSelectorContent.vue'
+export { default as ModelSelectorDialog } from './ModelSelectorDialog.vue'
+export { default as ModelSelectorEmpty } from './ModelSelectorEmpty.vue'
+export { default as ModelSelectorGroup } from './ModelSelectorGroup.vue'
+export { default as ModelSelectorInput } from './ModelSelectorInput.vue'
+export { default as ModelSelectorItem } from './ModelSelectorItem.vue'
+export { default as ModelSelectorList } from './ModelSelectorList.vue'
+export { default as ModelSelectorLogo } from './ModelSelectorLogo.vue'
+export { default as ModelSelectorLogoGroup } from './ModelSelectorLogoGroup.vue'
+export { default as ModelSelectorName } from './ModelSelectorName.vue'
+export { default as ModelSelectorSeparator } from './ModelSelectorSeparator.vue'
+export { default as ModelSelectorShortcut } from './ModelSelectorShortcut.vue'
+export { default as ModelSelectorTrigger } from './ModelSelectorTrigger.vue'
diff --git a/packages/examples/src/index.ts b/packages/examples/src/index.ts
index e7c0beb..56e8c68 100644
--- a/packages/examples/src/index.ts
+++ b/packages/examples/src/index.ts
@@ -19,6 +19,7 @@ export { default as LoaderSizes } from './loader-sizes.vue'
export { default as Loader } from './loader.vue'
export { default as MessageMarkdown } from './message-markdown.vue'
export { default as Message } from './message.vue'
+export { default as ModelSelector } from './model-selector.vue'
export { default as OpenInChat } from './open-in-chat.vue'
export { default as Plan } from './plan.vue'
export { default as PromptInput } from './prompt-input.vue'
diff --git a/packages/examples/src/model-selector.vue b/packages/examples/src/model-selector.vue
new file mode 100644
index 0000000..004a5c9
--- /dev/null
+++ b/packages/examples/src/model-selector.vue
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No models found.
+
+
+
+
+ {{ model.name }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/Command.vue b/packages/shadcn-vue/components/ui/command/Command.vue
new file mode 100644
index 0000000..51f1f75
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/Command.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/CommandDialog.vue b/packages/shadcn-vue/components/ui/command/CommandDialog.vue
new file mode 100644
index 0000000..711b9f9
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/CommandDialog.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/CommandEmpty.vue b/packages/shadcn-vue/components/ui/command/CommandEmpty.vue
new file mode 100644
index 0000000..a761b7c
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/CommandEmpty.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/CommandGroup.vue b/packages/shadcn-vue/components/ui/command/CommandGroup.vue
new file mode 100644
index 0000000..8b4c1f1
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/CommandGroup.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+ {{ heading }}
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/CommandInput.vue b/packages/shadcn-vue/components/ui/command/CommandInput.vue
new file mode 100644
index 0000000..95079f7
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/CommandInput.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/CommandItem.vue b/packages/shadcn-vue/components/ui/command/CommandItem.vue
new file mode 100644
index 0000000..c69a54e
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/CommandItem.vue
@@ -0,0 +1,76 @@
+
+
+
+ {
+ filterState.search = ''
+ }"
+ >
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/CommandList.vue b/packages/shadcn-vue/components/ui/command/CommandList.vue
new file mode 100644
index 0000000..483bc4c
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/CommandList.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/CommandSeparator.vue b/packages/shadcn-vue/components/ui/command/CommandSeparator.vue
new file mode 100644
index 0000000..410bca0
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/CommandSeparator.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/CommandShortcut.vue b/packages/shadcn-vue/components/ui/command/CommandShortcut.vue
new file mode 100644
index 0000000..fda5ac8
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/CommandShortcut.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/packages/shadcn-vue/components/ui/command/index.ts b/packages/shadcn-vue/components/ui/command/index.ts
new file mode 100644
index 0000000..cb48e1e
--- /dev/null
+++ b/packages/shadcn-vue/components/ui/command/index.ts
@@ -0,0 +1,25 @@
+import type { Ref } from 'vue'
+import { createContext } from 'reka-ui'
+
+export { default as Command } from './Command.vue'
+export { default as CommandDialog } from './CommandDialog.vue'
+export { default as CommandEmpty } from './CommandEmpty.vue'
+export { default as CommandGroup } from './CommandGroup.vue'
+export { default as CommandInput } from './CommandInput.vue'
+export { default as CommandItem } from './CommandItem.vue'
+export { default as CommandList } from './CommandList.vue'
+export { default as CommandSeparator } from './CommandSeparator.vue'
+export { default as CommandShortcut } from './CommandShortcut.vue'
+
+export const [useCommand, provideCommandContext] = createContext<{
+ allItems: Ref