1- import { FC , type ReactNode } from "react" ;
1+ import { FC , useCallback , type ReactNode } from "react" ;
22import { View } from "react-native" ;
33
44import { Icon , IconName } from "../ui/icon" ;
@@ -33,6 +33,19 @@ import {
3333} from "./attachment" ;
3434import { WeatherToolRegistration } from "../tools/weather-tool-ui" ;
3535import { Reasoning , ReasoningGroup } from "./reasoning" ;
36+ import { Divider } from "../ui/divider" ;
37+ import {
38+ ActionSheetSelect ,
39+ ActionSheetSelectContent ,
40+ ActionSheetSelectItem ,
41+ ActionSheetSelectTrigger ,
42+ ActionSheetSelectValue ,
43+ } from "../ui/action-sheet-select" ;
44+ import { AI_MODELS , DEFAULT_AI_MODEL } from "~/lib/ai-constants" ;
45+ import {
46+ useAiContext ,
47+ useAiContextStore ,
48+ } from "@creatorem/ai-chat/ai-provider" ;
3649
3750export const Thread : React . FC = ( ) => {
3851 return (
@@ -208,6 +221,91 @@ const Composer: React.FC = () => {
208221 ) ;
209222} ;
210223
224+ const modelLabels : Record < ( typeof AI_MODELS ) [ number ] , React . ReactNode > = {
225+ [ DEFAULT_AI_MODEL ] : (
226+ < View className = "flex-1 p-2" >
227+ < View className = "mb-1 flex flex-row gap-2 text-lg" >
228+ < Text > { DEFAULT_AI_MODEL } </ Text >
229+ < Icon name = "Gauge" size = { 20 } />
230+ </ View >
231+ < Text className = "text-muted-foreground text-sm" >
232+ Optimized for a wide range of natural language tasks.
233+ </ Text >
234+ </ View >
235+ ) ,
236+ "meta-llama/llama-4-scout-17b-16e-instruct" : (
237+ < View className = "flex-1 p-2" >
238+ < View className = "mb-1 flex flex-row gap-2 text-lg" >
239+ < Text > meta-llama/llama-4-scout-17b-16e-instruct</ Text >
240+ < Icon name = "Image" size = { 20 } />
241+ </ View >
242+ < Text className = "text-muted-foreground text-sm" >
243+ Designed for high-capability agentic use.
244+ </ Text >
245+ </ View >
246+ ) ,
247+ "openai/gpt-oss-120b" : (
248+ < View className = "flex-1 p-2" >
249+ < View className = "mb-1 flex flex-row gap-2 text-lg" >
250+ < Text > openai/gpt-oss-120b</ Text >
251+ < Icon name = "Brain" size = { 20 } />
252+ </ View >
253+ < Text className = "text-muted-foreground text-sm" >
254+ Competitive math/coding performance
255+ </ Text >
256+ </ View >
257+ ) ,
258+ "qwen/qwen3-32b" : (
259+ < View className = "flex-1 p-2" >
260+ < View className = "mb-1 flex flex-row gap-2 text-lg" >
261+ < Text > qwen/qwen3-32b</ Text >
262+ < Icon name = "Brain" size = { 20 } />
263+ </ View >
264+ < Text className = "text-muted-foreground text-sm" >
265+ Groundbreaking advancements in reasoning
266+ </ Text >
267+ </ View >
268+ ) ,
269+ } ;
270+
271+ const ModelSelector : React . FC = ( ) => {
272+ const aiContextStore = useAiContextStore ( ) ;
273+ const selectedModel = useAiContext ( ( s ) => s . selectedModel ) ;
274+
275+ const handleChange = useCallback (
276+ ( value : string ) => {
277+ aiContextStore . setState ( { selectedModel : value } ) ;
278+ } ,
279+ [ aiContextStore ] ,
280+ ) ;
281+
282+ return (
283+ < ActionSheetSelect
284+ value = { selectedModel }
285+ onValueChange = { handleChange }
286+ labels = { modelLabels }
287+ >
288+ < View className = "flex gap-1" >
289+ < Text className = "font-bold" > Model</ Text >
290+ < ActionSheetSelectTrigger className = "border-none" >
291+ < ActionSheetSelectValue
292+ placeholder = { selectedModel ?? DEFAULT_AI_MODEL }
293+ />
294+ </ ActionSheetSelectTrigger >
295+ </ View >
296+ < ActionSheetSelectContent >
297+ { Object . keys ( modelLabels ) . map ( ( model ) => (
298+ < ActionSheetSelectItem
299+ key = { model }
300+ value = { model }
301+ checkClassName = "absolute top-2 right-2"
302+ />
303+ ) ) }
304+ </ ActionSheetSelectContent >
305+ </ ActionSheetSelect >
306+ ) ;
307+ } ;
308+
211309const ComposerAction : FC = ( ) => {
212310 const textMutedForeground = useCSSVariable ( "--color-muted-foreground" ) ;
213311 const borderColor = useCSSVariable ( "--color-border" ) ;
@@ -227,7 +325,11 @@ const ComposerAction: FC = () => {
227325 backgroundColor : backgroundColor ,
228326 } }
229327 >
230- < ComposerAddAttachmentSheet />
328+ < View className = "flex gap-4 p-6 pt-2" >
329+ < ComposerAddAttachmentSheet />
330+ < Divider />
331+ < ModelSelector />
332+ </ View >
231333 { /* <View className="h-40 px-4">
232334 <ComposerAddAttachmentFile />
233335 <ComposerAddAttachmentImage />
0 commit comments