@@ -5,10 +5,20 @@ import { map, pipe, flatMap, entries, filter, isDeepEqual, sortBy } from "remeda
55import { DialogSelect , type DialogSelectRef } from "@tui/ui/dialog-select"
66import { useDialog } from "@tui/ui/dialog"
77import { useTheme } from "../context/theme"
8+ import { createDialogProviderOptions , DialogProvider } from "./dialog-provider"
89
910function Free ( ) {
1011 const { theme } = useTheme ( )
11- return < span style = { { fg : theme . secondary } } > Free</ span >
12+ return < span style = { { fg : theme . text } } > Free</ span >
13+ }
14+ const PROVIDER_PRIORITY : Record < string , number > = {
15+ opencode : 0 ,
16+ anthropic : 1 ,
17+ "github-copilot" : 2 ,
18+ openai : 3 ,
19+ google : 4 ,
20+ openrouter : 5 ,
21+ vercel : 6 ,
1222}
1323
1424export function DialogModel ( ) {
@@ -17,9 +27,16 @@ export function DialogModel() {
1727 const dialog = useDialog ( )
1828 const [ ref , setRef ] = createSignal < DialogSelectRef < unknown > > ( )
1929
30+ const connected = createMemo ( ( ) =>
31+ sync . data . provider . some ( ( x ) => x . id !== "opencode" || Object . values ( x . models ) . some ( ( y ) => y . cost ?. input !== 0 ) ) ,
32+ )
33+
34+ const showRecent = createMemo ( ( ) => ! ref ( ) ?. filter && local . model . recent ( ) . length > 0 && connected ( ) )
35+ const providers = createDialogProviderOptions ( )
36+
2037 const options = createMemo ( ( ) => {
2138 return [
22- ...( ! ref ( ) ?. filter
39+ ...( showRecent ( )
2340 ? local . model . recent ( ) . flatMap ( ( item ) => {
2441 const provider = sync . data . provider . find ( ( x ) => x . id === item . providerID ) !
2542 if ( ! provider ) return [ ]
@@ -35,7 +52,17 @@ export function DialogModel() {
3552 title : model . name ?? item . modelID ,
3653 description : provider . name ,
3754 category : "Recent" ,
38- footer : model . cost ?. input === 0 && provider . id === "opencode" ? < Free /> : undefined ,
55+ footer : model . cost ?. input === 0 && provider . id === "opencode" ? "Free" : undefined ,
56+ onSelect : ( ) => {
57+ dialog . clear ( )
58+ local . model . set (
59+ {
60+ providerID : provider . id ,
61+ modelID : model . id ,
62+ } ,
63+ { recent : true } ,
64+ )
65+ } ,
3966 } ,
4067 ]
4168 } )
@@ -56,28 +83,56 @@ export function DialogModel() {
5683 modelID : model ,
5784 } ,
5885 title : info . name ?? model ,
59- description : provider . name ,
60- category : provider . name ,
61- footer : info . cost ?. input === 0 && provider . id === "opencode" ? < Free /> : undefined ,
86+ description : connected ( ) ? provider . name : undefined ,
87+ category : connected ( ) ? provider . name : undefined ,
88+ footer : info . cost ?. input === 0 && provider . id === "opencode" ? "Free" : undefined ,
89+ onSelect ( ) {
90+ dialog . clear ( )
91+ local . model . set (
92+ {
93+ providerID : provider . id ,
94+ modelID : model ,
95+ } ,
96+ { recent : true } ,
97+ )
98+ } ,
6299 } ) ) ,
63- filter ( ( x ) => Boolean ( ref ( ) ?. filter ) || ! local . model . recent ( ) . find ( ( y ) => isDeepEqual ( y , x . value ) ) ) ,
100+ filter ( ( x ) => ! showRecent ( ) || ! local . model . recent ( ) . find ( ( y ) => isDeepEqual ( y , x . value ) ) ) ,
64101 sortBy ( ( x ) => x . title ) ,
65102 ) ,
66103 ) ,
67104 ) ,
105+ ...( ! connected ( )
106+ ? pipe (
107+ providers ( ) ,
108+ map ( ( option ) => {
109+ return {
110+ ...option ,
111+ category : "Popular providers" ,
112+ }
113+ } ) ,
114+ filter ( ( x ) => PROVIDER_PRIORITY [ x . value ] !== undefined ) ,
115+ sortBy ( ( x ) => PROVIDER_PRIORITY [ x . value ] ?? 99 ) ,
116+ )
117+ : [ ] ) ,
68118 ]
69119 } )
70120
71121 return (
72122 < DialogSelect
123+ keybind = { [
124+ {
125+ keybind : { ctrl : true , name : "a" , meta : false , shift : false , leader : false } ,
126+ title : connected ( ) ? "Connect provider" : "More providers" ,
127+ onTrigger ( ) {
128+ dialog . replace ( ( ) => < DialogProvider /> )
129+ } ,
130+ } ,
131+ ] }
73132 ref = { setRef }
74133 title = "Select model"
75134 current = { local . model . current ( ) }
76135 options = { options ( ) }
77- onSelect = { ( option ) => {
78- dialog . clear ( )
79- local . model . set ( option . value , { recent : true } )
80- } }
81136 />
82137 )
83138}
0 commit comments