forked from RooCodeInc/Roo-Code
-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathModelPicker.tsx
More file actions
114 lines (99 loc) · 3.84 KB
/
ModelPicker.tsx
File metadata and controls
114 lines (99 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { useMemo, useState, useCallback, useEffect, useRef } from "react"
import { VSCodeLink } from "@vscode/webview-ui-toolkit/react"
import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem } from "@/components/ui/combobox"
import { ApiConfiguration, ModelInfo } from "../../../../src/shared/api"
import { normalizeApiConfiguration } from "./ApiOptions"
import { usePearAiModels } from "../../hooks/usePearAiModels"
import { ThinkingBudget } from "./ThinkingBudget"
import { ModelInfoView } from "./ModelInfoView"
type ExtractType<T> = NonNullable<
{ [K in keyof ApiConfiguration]: Required<ApiConfiguration>[K] extends T ? K : never }[keyof ApiConfiguration]
>
type ModelIdKeys = NonNullable<
{ [K in keyof ApiConfiguration]: K extends `${string}ModelId` ? K : never }[keyof ApiConfiguration]
>
interface ModelPickerProps {
defaultModelId: string
defaultModelInfo?: ModelInfo
models: Record<string, ModelInfo> | null
modelIdKey: ModelIdKeys
modelInfoKey: ExtractType<ModelInfo>
serviceName: string
serviceUrl: string
apiConfiguration: ApiConfiguration
setApiConfigurationField: <K extends keyof ApiConfiguration>(field: K, value: ApiConfiguration[K]) => void
}
export const ModelPicker = ({
defaultModelId,
models,
modelIdKey,
modelInfoKey,
serviceName,
serviceUrl,
apiConfiguration,
setApiConfigurationField,
defaultModelInfo,
}: ModelPickerProps) => {
const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false)
const isInitialized = useRef(false)
const modelIds = useMemo(() => Object.keys(models ?? {}).sort((a, b) => a.localeCompare(b)), [models])
const pearAiModels = usePearAiModels(apiConfiguration)
const { selectedModelId, selectedModelInfo } = useMemo(
() => normalizeApiConfiguration(apiConfiguration, pearAiModels),
[apiConfiguration, pearAiModels],
)
const onSelect = useCallback(
(modelId: string) => {
const modelInfo = models?.[modelId]
setApiConfigurationField(modelIdKey, modelId)
setApiConfigurationField(modelInfoKey, modelInfo ?? defaultModelInfo)
},
[modelIdKey, modelInfoKey, models, setApiConfigurationField, defaultModelInfo],
)
const inputValue = apiConfiguration[modelIdKey]
useEffect(() => {
if (!inputValue && !isInitialized.current) {
const initialValue = modelIds.includes(selectedModelId) ? selectedModelId : defaultModelId
setApiConfigurationField(modelIdKey, initialValue)
}
isInitialized.current = true
}, [inputValue, modelIds, setApiConfigurationField, modelIdKey, selectedModelId, defaultModelId])
return (
<>
<div className="font-semibold">Model</div>
<Combobox type="single" inputValue={inputValue} onInputValueChange={onSelect}>
<ComboboxInput placeholder="Search model..." data-testid="model-input" />
<ComboboxContent>
<ComboboxEmpty>No model found.</ComboboxEmpty>
{modelIds.map((model) => (
<ComboboxItem key={model} value={model}>
{model}
</ComboboxItem>
))}
</ComboboxContent>
</Combobox>
<ThinkingBudget
apiConfiguration={apiConfiguration}
setApiConfigurationField={setApiConfigurationField}
modelInfo={selectedModelInfo}
/>
{selectedModelId && selectedModelInfo && selectedModelId === inputValue && (
<ModelInfoView
selectedModelId={selectedModelId}
modelInfo={selectedModelInfo}
isDescriptionExpanded={isDescriptionExpanded}
setIsDescriptionExpanded={setIsDescriptionExpanded}
/>
)}
<p>
The extension automatically fetches the latest list of models available on{" "}
<VSCodeLink style={{ display: "inline", fontSize: "inherit" }} href={serviceUrl}>
{serviceName}.
</VSCodeLink>
If you're unsure which model to choose, Roo Code works best with{" "}
<VSCodeLink onClick={() => onSelect(defaultModelId)}>{defaultModelId}.</VSCodeLink>
You can also try searching "free" for no-cost options currently available.
</p>
</>
)
}