@@ -5,6 +5,7 @@ import { useDebounce, useEvent } from "react-use"
55import { Checkbox , Dropdown , type DropdownOption } from "vscrui"
66import { VSCodeLink , VSCodeRadio , VSCodeRadioGroup , VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
77import * as vscodemodels from "vscode"
8+ import { ExternalLinkIcon } from "@radix-ui/react-icons"
89
910import { Select , SelectContent , SelectGroup , SelectItem , SelectTrigger , SelectValue , Button } from "@/components/ui"
1011
@@ -38,7 +39,12 @@ import {
3839} from "../../../../src/shared/api"
3940import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"
4041
41- import { vscode } from "../../utils/vscode"
42+ import { vscode } from "@/utils/vscode"
43+ import {
44+ useOpenRouterModelProviders ,
45+ OPENROUTER_DEFAULT_PROVIDER_NAME ,
46+ } from "@/components/ui/hooks/useOpenRouterModelProviders"
47+
4248import { VSCodeButtonLink } from "../common/VSCodeButtonLink"
4349import { ModelInfoView } from "./ModelInfoView"
4450import { ModelPicker } from "./ModelPicker"
@@ -94,6 +100,7 @@ const ApiOptions = ({
94100 setErrorMessage,
95101} : ApiOptionsProps ) => {
96102 const { t } = useAppTranslation ( )
103+
97104 const [ ollamaModels , setOllamaModels ] = useState < string [ ] > ( [ ] )
98105 const [ lmStudioModels , setLmStudioModels ] = useState < string [ ] > ( [ ] )
99106 const [ vsCodeLmModels , setVsCodeLmModels ] = useState < vscodemodels . LanguageModelChatSelector [ ] > ( [ ] )
@@ -192,6 +199,13 @@ const ApiOptions = ({
192199 setErrorMessage ( apiValidationResult )
193200 } , [ apiConfiguration , glamaModels , openRouterModels , setErrorMessage , unboundModels , requestyModels ] )
194201
202+ const { data : openRouterModelProviders } = useOpenRouterModelProviders ( apiConfiguration ?. openRouterModelId , {
203+ enabled :
204+ selectedProvider === "openrouter" &&
205+ ! ! apiConfiguration ?. openRouterModelId &&
206+ apiConfiguration . openRouterModelId in openRouterModels ,
207+ } )
208+
195209 const onMessage = useCallback ( ( event : MessageEvent ) => {
196210 const message : ExtensionMessage = event . data
197211
@@ -1365,6 +1379,52 @@ const ApiOptions = ({
13651379 />
13661380 ) }
13671381
1382+ { openRouterModelProviders && (
1383+ < >
1384+ < div className = "dropdown-container" style = { { marginTop : 3 } } >
1385+ < div className = "flex items-center gap-1" >
1386+ < label htmlFor = "provider-routing" className = "font-medium" >
1387+ { t ( "settings:providers.openRouter.providerRouting.title" ) }
1388+ </ label >
1389+ < a href = { `https://openrouter.ai/${ selectedModelId } /providers` } >
1390+ < ExternalLinkIcon className = "w-4 h-4" />
1391+ </ a >
1392+ </ div >
1393+ < Dropdown
1394+ id = "provider-routing"
1395+ value = { apiConfiguration ?. openRouterSpecificProvider || "" }
1396+ onChange = { ( event ) => {
1397+ const provider = typeof event == "string" ? event : event ?. value
1398+ const providerModelInfo = provider ? openRouterModelProviders [ provider ] : undefined
1399+
1400+ if ( providerModelInfo ) {
1401+ setApiConfigurationField ( "openRouterModelInfo" , {
1402+ ...apiConfiguration . openRouterModelInfo ,
1403+ ...providerModelInfo ,
1404+ } )
1405+ }
1406+
1407+ setApiConfigurationField ( "openRouterSpecificProvider" , provider )
1408+ } }
1409+ options = { [
1410+ { value : OPENROUTER_DEFAULT_PROVIDER_NAME , label : OPENROUTER_DEFAULT_PROVIDER_NAME } ,
1411+ ...Object . entries ( openRouterModelProviders ) . map ( ( [ value , { label } ] ) => ( {
1412+ value,
1413+ label,
1414+ } ) ) ,
1415+ ] }
1416+ className = "w-full"
1417+ />
1418+ </ div >
1419+ < div className = "text-sm text-vscode-descriptionForeground" >
1420+ { t ( "settings:providers.openRouter.providerRouting.description" ) } { " " }
1421+ < a href = "https://openrouter.ai/docs/features/provider-routing" >
1422+ { t ( "settings:providers.openRouter.providerRouting.learnMore" ) } .
1423+ </ a >
1424+ </ div >
1425+ </ >
1426+ ) }
1427+
13681428 { selectedProvider === "glama" && (
13691429 < ModelPicker
13701430 apiConfiguration = { apiConfiguration }
0 commit comments