Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion src/core/config/ProviderSettingsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const providerProfilesSchema = z.object({
migrations: z
.object({
rateLimitSecondsMigrated: z.boolean().optional(),
diffSettingsMigrated: z.boolean().optional(),
})
.optional(),
})
Expand All @@ -36,6 +37,7 @@ export class ProviderSettingsManager {
modeApiConfigs: this.defaultModeApiConfigs,
migrations: {
rateLimitSecondsMigrated: true, // Mark as migrated on fresh installs
diffSettingsMigrated: true, // Mark as migrated on fresh installs
},
}

Expand Down Expand Up @@ -85,7 +87,10 @@ export class ProviderSettingsManager {

// Ensure migrations field exists
if (!providerProfiles.migrations) {
providerProfiles.migrations = { rateLimitSecondsMigrated: false } // Initialize with default values
providerProfiles.migrations = {
rateLimitSecondsMigrated: false,
diffSettingsMigrated: false,
} // Initialize with default values
isDirty = true
}

Expand All @@ -95,6 +100,12 @@ export class ProviderSettingsManager {
isDirty = true
}

if (!providerProfiles.migrations.diffSettingsMigrated) {
await this.migrateDiffSettings(providerProfiles)
providerProfiles.migrations.diffSettingsMigrated = true
isDirty = true
}

if (isDirty) {
await this.store(providerProfiles)
}
Expand Down Expand Up @@ -129,6 +140,41 @@ export class ProviderSettingsManager {
}
}

private async migrateDiffSettings(providerProfiles: ProviderProfiles) {
try {
let diffEnabled: boolean | undefined
let fuzzyMatchThreshold: number | undefined

try {
diffEnabled = await this.context.globalState.get<boolean>("diffEnabled")
fuzzyMatchThreshold = await this.context.globalState.get<number>("fuzzyMatchThreshold")
} catch (error) {
console.error("[MigrateDiffSettings] Error getting global diff settings:", error)
}

if (diffEnabled === undefined) {
// Failed to get the existing value, use the default.
diffEnabled = true
}

if (fuzzyMatchThreshold === undefined) {
// Failed to get the existing value, use the default.
fuzzyMatchThreshold = 1.0
}

for (const [name, apiConfig] of Object.entries(providerProfiles.apiConfigs)) {
if (apiConfig.diffEnabled === undefined) {
apiConfig.diffEnabled = diffEnabled
}
if (apiConfig.fuzzyMatchThreshold === undefined) {
apiConfig.fuzzyMatchThreshold = fuzzyMatchThreshold
}
}
} catch (error) {
console.error(`[MigrateDiffSettings] Failed to migrate diff settings:`, error)
}
}

/**
* List all available configs with metadata.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/exports/roo-code.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ type ProviderSettings = {
modelTemperature?: (number | null) | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
rateLimitSeconds?: number | undefined
diffEnabled?: boolean | undefined
fuzzyMatchThreshold?: number | undefined
fakeAi?: unknown | undefined
}

Expand Down
2 changes: 2 additions & 0 deletions src/exports/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ type ProviderSettings = {
modelTemperature?: (number | null) | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
rateLimitSeconds?: number | undefined
diffEnabled?: boolean | undefined
fuzzyMatchThreshold?: number | undefined
fakeAi?: unknown | undefined
}

Expand Down
4 changes: 4 additions & 0 deletions src/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,8 @@ export const providerSettingsSchema = z.object({
modelTemperature: z.number().nullish(),
reasoningEffort: reasoningEffortsSchema.optional(),
rateLimitSeconds: z.number().optional(),
diffEnabled: z.boolean().optional(),
fuzzyMatchThreshold: z.number().optional(),
// Fake AI
fakeAi: z.unknown().optional(),
})
Expand Down Expand Up @@ -490,6 +492,8 @@ const providerSettingsRecord: ProviderSettingsRecord = {
modelTemperature: undefined,
reasoningEffort: undefined,
rateLimitSeconds: undefined,
diffEnabled: undefined,
fuzzyMatchThreshold: undefined,
// Fake AI
fakeAi: undefined,
}
Expand Down
75 changes: 0 additions & 75 deletions webview-ui/src/components/settings/AdvancedSettings.tsx

This file was deleted.

6 changes: 6 additions & 0 deletions webview-ui/src/components/settings/ApiOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { ModelInfoView } from "./ModelInfoView"
import { ModelPicker } from "./ModelPicker"
import { TemperatureControl } from "./TemperatureControl"
import { RateLimitSecondsControl } from "./RateLimitSecondsControl"
import { DiffSettingsControl } from "./DiffSettingsControl"
import { ApiErrorMessage } from "./ApiErrorMessage"
import { ThinkingBudget } from "./ThinkingBudget"
import { R1FormatSetting } from "./R1FormatSetting"
Expand Down Expand Up @@ -1681,6 +1682,11 @@ const ApiOptions = ({

{!fromWelcomeView && (
<>
<DiffSettingsControl
diffEnabled={apiConfiguration.diffEnabled}
fuzzyMatchThreshold={apiConfiguration.fuzzyMatchThreshold}
onChange={(field, value) => setApiConfigurationField(field, value)}
/>
<TemperatureControl
value={apiConfiguration?.modelTemperature}
onChange={handleInputChange("modelTemperature", noTransform)}
Expand Down
68 changes: 68 additions & 0 deletions webview-ui/src/components/settings/DiffSettingsControl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useCallback } from "react"
import { Slider } from "@/components/ui"
import { useAppTranslation } from "@/i18n/TranslationContext"
import { VSCodeCheckbox } from "@vscode/webview-ui-toolkit/react"

interface DiffSettingsControlProps {
diffEnabled?: boolean
fuzzyMatchThreshold?: number
onChange: (field: "diffEnabled" | "fuzzyMatchThreshold", value: any) => void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The onChange prop currently uses an any type for its value. Consider refining it so that when field is 'diffEnabled', value is a boolean, and when field is 'fuzzyMatchThreshold', value is a number. This would improve type-safety.

}

export const DiffSettingsControl: React.FC<DiffSettingsControlProps> = ({
diffEnabled = true,
fuzzyMatchThreshold = 1.0,
onChange,
}) => {
const { t } = useAppTranslation()

const handleDiffEnabledChange = useCallback(
(e: any) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider replacing the generic type for the event parameter with a more specific type (e.g., React.ChangeEvent<HTMLInputElement>) to improve type safety.

Suggested change
(e: any) => {
(e: React.ChangeEvent<HTMLInputElement>) => {

onChange("diffEnabled", e.target.checked)
},
[onChange],
)

const handleThresholdChange = useCallback(
(newValue: number[]) => {
onChange("fuzzyMatchThreshold", newValue[0])
},
[onChange],
)

return (
<div className="flex flex-col gap-1">
<div>
<VSCodeCheckbox checked={diffEnabled} onChange={handleDiffEnabledChange}>
<span className="font-medium">{t("settings:advanced.diff.label")}</span>
</VSCodeCheckbox>
<div className="text-vscode-descriptionForeground text-sm">
{t("settings:advanced.diff.description")}
</div>
</div>

{diffEnabled && (
<div className="flex flex-col gap-3 pl-3 border-l-2 border-vscode-button-background">
<div>
<label className="block font-medium mb-1">
{t("settings:advanced.diff.matchPrecision.label")}
</label>
<div className="flex items-center gap-2">
<Slider
min={0.8}
max={1}
step={0.005}
value={[fuzzyMatchThreshold]}
onValueChange={handleThresholdChange}
/>
<span className="w-10">{Math.round(fuzzyMatchThreshold * 100)}%</span>
</div>
<div className="text-vscode-descriptionForeground text-sm mt-1">
{t("settings:advanced.diff.matchPrecision.description")}
</div>
</div>
</div>
)}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import { Section } from "./Section"
import { ExperimentalFeature } from "./ExperimentalFeature"

type ExperimentalSettingsProps = HTMLAttributes<HTMLDivElement> & {
setCachedStateField: SetCachedStateField<
"terminalOutputLineLimit" | "maxOpenTabsContext" | "diffEnabled" | "fuzzyMatchThreshold"
>
setCachedStateField: SetCachedStateField<"terminalOutputLineLimit" | "maxOpenTabsContext">
experiments: Record<ExperimentId, boolean>
setExperimentEnabled: SetExperimentEnabled
}
Expand Down
14 changes: 0 additions & 14 deletions webview-ui/src/components/settings/SettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
Bell,
Database,
SquareTerminal,
Cog,
FlaskConical,
AlertTriangle,
Globe,
Expand Down Expand Up @@ -52,7 +51,6 @@ import { InterfaceSettings } from "./InterfaceSettings"
import { NotificationSettings } from "./NotificationSettings"
import { ContextManagementSettings } from "./ContextManagementSettings"
import { TerminalSettings } from "./TerminalSettings"
import { AdvancedSettings } from "./AdvancedSettings"
import { ExperimentalSettings } from "./ExperimentalSettings"
import { LanguageSettings } from "./LanguageSettings"
import { About } from "./About"
Expand All @@ -71,7 +69,6 @@ const sectionNames = [
"notifications",
"contextManagement",
"terminal",
"advanced",
"experimental",
"language",
"about",
Expand Down Expand Up @@ -299,7 +296,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
const notificationsRef = useRef<HTMLDivElement>(null)
const contextManagementRef = useRef<HTMLDivElement>(null)
const terminalRef = useRef<HTMLDivElement>(null)
const advancedRef = useRef<HTMLDivElement>(null)
const experimentalRef = useRef<HTMLDivElement>(null)
const languageRef = useRef<HTMLDivElement>(null)
const aboutRef = useRef<HTMLDivElement>(null)
Expand All @@ -314,7 +310,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
{ id: "notifications", icon: Bell, ref: notificationsRef },
{ id: "contextManagement", icon: Database, ref: contextManagementRef },
{ id: "terminal", icon: SquareTerminal, ref: terminalRef },
{ id: "advanced", icon: Cog, ref: advancedRef },
{ id: "experimental", icon: FlaskConical, ref: experimentalRef },
{ id: "language", icon: Globe, ref: languageRef },
{ id: "about", icon: Info, ref: aboutRef },
Expand All @@ -328,7 +323,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
notificationsRef,
contextManagementRef,
terminalRef,
advancedRef,
experimentalRef,
],
)
Expand Down Expand Up @@ -515,14 +509,6 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
/>
</div>

<div ref={advancedRef}>
<AdvancedSettings
diffEnabled={diffEnabled}
fuzzyMatchThreshold={fuzzyMatchThreshold}
setCachedStateField={setCachedStateField}
/>
</div>

<div ref={experimentalRef}>
<ExperimentalSettings
setCachedStateField={setCachedStateField}
Expand Down
Loading