|
1 | 1 | import { useCallback, useState, useEffect, useMemo } from "react" |
2 | 2 | import { useEvent } from "react-use" |
3 | | -import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react" |
| 3 | +import { VSCodeTextField, VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react" |
4 | 4 |
|
5 | 5 | import type { ProviderSettings } from "@roo-code/types" |
6 | 6 |
|
7 | 7 | import { ExtensionMessage } from "@roo/ExtensionMessage" |
8 | 8 | import { vscode } from "@src/utils/vscode" |
9 | 9 | import { useAppTranslation } from "@src/i18n/TranslationContext" |
10 | 10 | import { VSCodeButtonLink } from "@src/components/common/VSCodeButtonLink" |
11 | | -import { SearchableSelect, type SearchableSelectOption } from "@src/components/ui" |
| 11 | +import { SearchableSelect, type SearchableSelectOption, Slider } from "@src/components/ui" |
| 12 | +import { cn } from "@src/lib/utils" |
| 13 | +import { TemperatureControl } from "../TemperatureControl" |
12 | 14 |
|
13 | 15 | import { inputEventTransform } from "../transforms" |
14 | 16 |
|
@@ -140,6 +142,49 @@ export const HuggingFace = ({ apiConfiguration, setApiConfigurationField }: Hugg |
140 | 142 | return nameMap[provider] || provider.charAt(0).toUpperCase() + provider.slice(1) |
141 | 143 | } |
142 | 144 |
|
| 145 | + // Get model capabilities |
| 146 | + const modelCapabilities = useMemo(() => { |
| 147 | + if (!currentModel) return null |
| 148 | + |
| 149 | + const supportsImages = currentModel.pipeline_tag === "image-text-to-text" |
| 150 | + const maxTokens = currentModel.config.tokenizer_config?.model_max_length |
| 151 | + |
| 152 | + return { |
| 153 | + supportsImages, |
| 154 | + maxTokens, |
| 155 | + } |
| 156 | + }, [currentModel]) |
| 157 | + |
| 158 | + // Model capabilities component |
| 159 | + const ModelCapabilities = () => { |
| 160 | + if (!modelCapabilities) return null |
| 161 | + |
| 162 | + return ( |
| 163 | + <div className="flex flex-col gap-2"> |
| 164 | + <div className="flex flex-col gap-1 text-sm"> |
| 165 | + <div |
| 166 | + className={cn( |
| 167 | + "flex items-center gap-1", |
| 168 | + modelCapabilities.supportsImages |
| 169 | + ? "text-vscode-charts-green" |
| 170 | + : "text-vscode-errorForeground", |
| 171 | + )}> |
| 172 | + <span |
| 173 | + className={cn("codicon", modelCapabilities.supportsImages ? "codicon-check" : "codicon-x")} |
| 174 | + /> |
| 175 | + {modelCapabilities.supportsImages ? "Supports images" : "Text only"} |
| 176 | + </div> |
| 177 | + {modelCapabilities.maxTokens && ( |
| 178 | + <div className="flex items-center gap-1 text-vscode-descriptionForeground"> |
| 179 | + <span className="codicon codicon-info" /> |
| 180 | + Max context: {modelCapabilities.maxTokens.toLocaleString()} tokens |
| 181 | + </div> |
| 182 | + )} |
| 183 | + </div> |
| 184 | + </div> |
| 185 | + ) |
| 186 | + } |
| 187 | + |
143 | 188 | return ( |
144 | 189 | <> |
145 | 190 | <VSCodeTextField |
@@ -202,6 +247,49 @@ export const HuggingFace = ({ apiConfiguration, setApiConfigurationField }: Hugg |
202 | 247 | </div> |
203 | 248 | )} |
204 | 249 |
|
| 250 | + {/* Model capabilities */} |
| 251 | + {currentModel && <ModelCapabilities />} |
| 252 | + |
| 253 | + {/* Temperature control */} |
| 254 | + <TemperatureControl |
| 255 | + value={apiConfiguration?.modelTemperature} |
| 256 | + onChange={(value) => setApiConfigurationField("modelTemperature", value)} |
| 257 | + maxValue={2} |
| 258 | + /> |
| 259 | + |
| 260 | + {/* Max tokens control */} |
| 261 | + <div className="flex flex-col gap-3"> |
| 262 | + <VSCodeCheckbox |
| 263 | + checked={apiConfiguration?.includeMaxTokens ?? false} |
| 264 | + onChange={(e: any) => setApiConfigurationField("includeMaxTokens", e.target.checked)}> |
| 265 | + <label className="block font-medium mb-1">Include max output tokens</label> |
| 266 | + </VSCodeCheckbox> |
| 267 | + <div className="text-sm text-vscode-descriptionForeground -mt-2"> |
| 268 | + Limit the maximum number of tokens in the response |
| 269 | + </div> |
| 270 | + |
| 271 | + {apiConfiguration?.includeMaxTokens && ( |
| 272 | + <div className="flex flex-col gap-3 pl-3 border-l-2 border-vscode-button-background"> |
| 273 | + <div> |
| 274 | + <label className="block font-medium mb-2 text-sm">Max output tokens</label> |
| 275 | + <div className="flex items-center gap-2"> |
| 276 | + <Slider |
| 277 | + min={1} |
| 278 | + max={modelCapabilities?.maxTokens || 8192} |
| 279 | + step={256} |
| 280 | + value={[apiConfiguration?.modelMaxTokens || 2048]} |
| 281 | + onValueChange={([value]) => setApiConfigurationField("modelMaxTokens", value)} |
| 282 | + /> |
| 283 | + <span className="w-16 text-sm">{apiConfiguration?.modelMaxTokens || 2048}</span> |
| 284 | + </div> |
| 285 | + <div className="text-vscode-descriptionForeground text-sm mt-1"> |
| 286 | + Maximum tokens to generate in response |
| 287 | + </div> |
| 288 | + </div> |
| 289 | + </div> |
| 290 | + )} |
| 291 | + </div> |
| 292 | + |
205 | 293 | <div className="text-sm text-vscode-descriptionForeground -mt-2"> |
206 | 294 | {t("settings:providers.apiKeyStorageNotice")} |
207 | 295 | </div> |
|
0 commit comments