Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
34 changes: 25 additions & 9 deletions src/core/config/ContextProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ import * as vscode from "vscode"

import {
PROVIDER_SETTINGS_KEYS,
GLOBAL_SETTINGS_KEYS,
SECRET_STATE_KEYS,
GLOBAL_STATE_KEYS,
ProviderSettings,
providerSettingsSchema,
GlobalSettings,
globalSettingsSchema,
RooCodeSettings,
SECRET_STATE_KEYS,
SecretState,
isSecretStateKey,
GLOBAL_STATE_KEYS,
GlobalState,
RooCodeSettings,
providerSettingsSchema,
globalSettingsSchema,
isSecretStateKey,
} from "../../schemas"
import { logger } from "../../utils/logging"

Expand Down Expand Up @@ -151,15 +152,31 @@ export class ContextProxy {
*/

public getGlobalSettings(): GlobalSettings {
return globalSettingsSchema.parse({ ...this.stateCache })
const values = this.getValues()

try {
return globalSettingsSchema.parse(values)
} catch (error) {
// Log to Posthog?
// We'll want to know about bad type assumptions or bad ExtensionState data.
return GLOBAL_SETTINGS_KEYS.reduce((acc, key) => ({ ...acc, [key]: values[key] }), {} as GlobalSettings)
}
}

/**
* ProviderSettings
*/

public getProviderSettings(): ProviderSettings {
return providerSettingsSchema.parse(this.getValues())
const values = this.getValues()

try {
return providerSettingsSchema.parse(values)
} catch (error) {
// Log to Posthog?
// We'll want to know about bad type assumptions or bad ExtensionState data.
return PROVIDER_SETTINGS_KEYS.reduce((acc, key) => ({ ...acc, [key]: values[key] }), {} as ProviderSettings)
}
}

public async setProviderSettings(values: ProviderSettings) {
Expand Down Expand Up @@ -206,7 +223,6 @@ export class ContextProxy {
public async export(): Promise<GlobalSettings | undefined> {
try {
const globalSettings = globalSettingsExportSchema.parse(this.getValues())

return Object.fromEntries(Object.entries(globalSettings).filter(([_, value]) => value !== undefined))
} catch (error) {
console.log(error.message)
Expand Down
14 changes: 1 addition & 13 deletions src/core/config/ProviderSettingsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,6 @@ export const providerProfilesSchema = z.object({

export type ProviderProfiles = z.infer<typeof providerProfilesSchema>

const providerProfilesExportSchema = providerProfilesSchema.extend({
apiConfigs: z.record(
z.string(),
providerSettingsWithIdSchema.omit({
glamaModelInfo: true,
openRouterModelInfo: true,
unboundModelInfo: true,
requestyModelInfo: true,
}),
),
})

export class ProviderSettingsManager {
private static readonly SCOPE_PREFIX = "roo_cline_config_"

Expand Down Expand Up @@ -246,7 +234,7 @@ export class ProviderSettingsManager {

public async export() {
try {
return await this.lock(async () => providerProfilesExportSchema.parse(await this.load()))
return await this.lock(async () => providerProfilesSchema.parse(await this.load()))
} catch (error) {
throw new Error(`Failed to export provider profiles: ${error}`)
}
Expand Down
20 changes: 10 additions & 10 deletions src/exports/roo-code.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type ProviderSettings = {
anthropicBaseUrl?: string | undefined
glamaModelId?: string | undefined
glamaModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -40,13 +40,13 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
glamaApiKey?: string | undefined
openRouterApiKey?: string | undefined
openRouterModelId?: string | undefined
openRouterModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -59,7 +59,7 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
openRouterBaseUrl?: string | undefined
openRouterSpecificProvider?: string | undefined
Expand All @@ -83,7 +83,7 @@ type ProviderSettings = {
openAiR1FormatEnabled?: boolean | undefined
openAiModelId?: string | undefined
openAiCustomModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -96,7 +96,7 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
openAiUseAzure?: boolean | undefined
azureApiVersion?: string | undefined
Expand Down Expand Up @@ -125,7 +125,7 @@ type ProviderSettings = {
unboundApiKey?: string | undefined
unboundModelId?: string | undefined
unboundModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -138,12 +138,12 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
requestyApiKey?: string | undefined
requestyModelId?: string | undefined
requestyModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -156,7 +156,7 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
modelTemperature?: (number | null) | undefined
modelMaxTokens?: number | undefined
Expand Down
20 changes: 10 additions & 10 deletions src/exports/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type ProviderSettings = {
anthropicBaseUrl?: string | undefined
glamaModelId?: string | undefined
glamaModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -41,13 +41,13 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
glamaApiKey?: string | undefined
openRouterApiKey?: string | undefined
openRouterModelId?: string | undefined
openRouterModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -60,7 +60,7 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
openRouterBaseUrl?: string | undefined
openRouterSpecificProvider?: string | undefined
Expand All @@ -84,7 +84,7 @@ type ProviderSettings = {
openAiR1FormatEnabled?: boolean | undefined
openAiModelId?: string | undefined
openAiCustomModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -97,7 +97,7 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
openAiUseAzure?: boolean | undefined
azureApiVersion?: string | undefined
Expand Down Expand Up @@ -126,7 +126,7 @@ type ProviderSettings = {
unboundApiKey?: string | undefined
unboundModelId?: string | undefined
unboundModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -139,12 +139,12 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
requestyApiKey?: string | undefined
requestyModelId?: string | undefined
requestyModelInfo?:
| {
| ({
maxTokens?: number | undefined
contextWindow: number
supportsImages?: boolean | undefined
Expand All @@ -157,7 +157,7 @@ type ProviderSettings = {
description?: string | undefined
reasoningEffort?: ("low" | "medium" | "high") | undefined
thinking?: boolean | undefined
}
} | null)
| undefined
modelTemperature?: (number | null) | undefined
modelMaxTokens?: number | undefined
Expand Down
10 changes: 5 additions & 5 deletions src/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,12 @@ export const providerSettingsSchema = z.object({
anthropicBaseUrl: z.string().optional(),
// Glama
glamaModelId: z.string().optional(),
glamaModelInfo: modelInfoSchema.optional(),
glamaModelInfo: modelInfoSchema.nullish(),
glamaApiKey: z.string().optional(),
// OpenRouter
openRouterApiKey: z.string().optional(),
openRouterModelId: z.string().optional(),
openRouterModelInfo: modelInfoSchema.optional(),
openRouterModelInfo: modelInfoSchema.nullish(),
openRouterBaseUrl: z.string().optional(),
openRouterSpecificProvider: z.string().optional(),
openRouterUseMiddleOutTransform: z.boolean().optional(),
Expand All @@ -344,7 +344,7 @@ export const providerSettingsSchema = z.object({
openAiApiKey: z.string().optional(),
openAiR1FormatEnabled: z.boolean().optional(),
openAiModelId: z.string().optional(),
openAiCustomModelInfo: modelInfoSchema.optional(),
openAiCustomModelInfo: modelInfoSchema.nullish(),
openAiUseAzure: z.boolean().optional(),
azureApiVersion: z.string().optional(),
openAiStreamingEnabled: z.boolean().optional(),
Expand Down Expand Up @@ -379,11 +379,11 @@ export const providerSettingsSchema = z.object({
// Unbound
unboundApiKey: z.string().optional(),
unboundModelId: z.string().optional(),
unboundModelInfo: modelInfoSchema.optional(),
unboundModelInfo: modelInfoSchema.nullish(),
// Requesty
requestyApiKey: z.string().optional(),
requestyModelId: z.string().optional(),
requestyModelInfo: modelInfoSchema.optional(),
requestyModelInfo: modelInfoSchema.nullish(),
// Claude 3.7 Sonnet Thinking
modelTemperature: z.number().nullish(),
modelMaxTokens: z.number().optional(),
Expand Down
45 changes: 5 additions & 40 deletions webview-ui/src/components/settings/ApiOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { Checkbox } from "vscrui"
import { VSCodeLink, VSCodeRadio, VSCodeRadioGroup, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { ExternalLinkIcon } from "@radix-ui/react-icons"

import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectSeparator, Button } from "@/components/ui"

import {
ApiConfiguration,
ModelInfo,
Expand Down Expand Up @@ -42,56 +40,23 @@ import {
import { ExtensionMessage } from "../../../../src/shared/ExtensionMessage"

import { vscode } from "@/utils/vscode"
import { validateApiConfiguration, validateModelId, validateBedrockArn } from "@/utils/validate"
import {
useOpenRouterModelProviders,
OPENROUTER_DEFAULT_PROVIDER_NAME,
} from "@/components/ui/hooks/useOpenRouterModelProviders"
import { useOpenRouterKeyInfo } from "@/components/ui/hooks/useOpenRouterKeyInfo"
import { useRequestyKeyInfo } from "@/components/ui/hooks/useRequestyKeyInfo"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectSeparator, Button } from "@/components/ui"

import { MODELS_BY_PROVIDER, PROVIDERS, AWS_REGIONS, VERTEX_REGIONS } from "./constants"
import { VSCodeButtonLink } from "../common/VSCodeButtonLink"
import { ModelInfoView } from "./ModelInfoView"
import { ModelPicker } from "./ModelPicker"
import { TemperatureControl } from "./TemperatureControl"
import { validateApiConfiguration, validateModelId, validateBedrockArn } from "@/utils/validate"
import { ApiErrorMessage } from "./ApiErrorMessage"
import { ThinkingBudget } from "./ThinkingBudget"
import { R1FormatSetting } from "./R1FormatSetting"

// Component to display OpenRouter API key balance
const OpenRouterBalanceDisplay = ({ apiKey, baseUrl }: { apiKey: string; baseUrl?: string }) => {
const { data: keyInfo } = useOpenRouterKeyInfo(apiKey, baseUrl)

if (!keyInfo || !keyInfo.limit) {
return null
}

const formattedBalance = (keyInfo.limit - keyInfo.usage).toFixed(2)

return (
<VSCodeLink href="https://openrouter.ai/settings/keys" className="text-vscode-foreground hover:underline">
${formattedBalance}
</VSCodeLink>
)
}

const RequestyBalanceDisplay = ({ apiKey }: { apiKey: string }) => {
const { data: keyInfo } = useRequestyKeyInfo(apiKey)

if (!keyInfo) {
return null
}

// Parse the balance to a number and format it to 2 decimal places
const balance = parseFloat(keyInfo.org_balance)
const formattedBalance = balance.toFixed(2)

return (
<VSCodeLink href="https://app.requesty.ai/settings" className="text-vscode-foreground hover:underline">
${formattedBalance}
</VSCodeLink>
)
}
import { OpenRouterBalanceDisplay } from "./OpenRouterBalanceDisplay"
import { RequestyBalanceDisplay } from "./RequestyBalanceDisplay"

interface ApiOptionsProps {
uriScheme: string | undefined
Expand Down
Loading