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
1 change: 1 addition & 0 deletions packages/types/src/provider-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ const unboundSchema = baseProviderSettingsSchema.extend({
})

const requestySchema = baseProviderSettingsSchema.extend({
requestyBaseUrl: z.string().optional(),
requestyApiKey: z.string().optional(),
requestyModelId: z.string().optional(),
})
Expand Down
15 changes: 15 additions & 0 deletions src/api/providers/__tests__/requesty.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ describe("RequestyHandler", () => {
})
})

it("can use a base URL instead of the default", () => {
const handler = new RequestyHandler({ ...mockOptions, requestyBaseUrl: "some-base-url" })
expect(handler).toBeInstanceOf(RequestyHandler)

expect(OpenAI).toHaveBeenCalledWith({
baseURL: "some-base-url",
apiKey: mockOptions.requestyApiKey,
defaultHeaders: {
"HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline",
"X-Title": "Roo Code",
"User-Agent": `RooCode/${Package.version}`,
},
})
})
Copy link
Contributor

Choose a reason for hiding this comment

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

While the test verifies that the custom base URL is passed to the OpenAI constructor, it would be valuable to add a test that actually makes an API call with the custom URL to ensure end-to-end functionality. This could help catch any issues with how the custom URL is used in practice.

Copy link
Contributor

Choose a reason for hiding this comment

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

While the test verifies that the custom base URL is passed to the OpenAI constructor, it would be valuable to add a test that actually makes an API call with the custom URL to ensure end-to-end functionality. This could help catch any issues with how the custom URL is used in practice.


describe("fetchModel", () => {
it("returns correct model info when options are provided", async () => {
const handler = new RequestyHandler(mockOptions)
Expand Down
2 changes: 1 addition & 1 deletion src/api/providers/requesty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class RequestyHandler extends BaseProvider implements SingleCompletionHan
this.options = options

this.client = new OpenAI({
baseURL: "https://router.requesty.ai/v1",
baseURL: options.requestyBaseUrl || "https://router.requesty.ai/v1",
apiKey: this.options.requestyApiKey ?? "not-provided",
defaultHeaders: DEFAULT_HEADERS,
})
Expand Down
36 changes: 34 additions & 2 deletions webview-ui/src/components/settings/providers/Requesty.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useState } from "react"
import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { useCallback, useEffect, useState } from "react"
import { VSCodeCheckbox, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"

import { type ProviderSettings, type OrganizationAllowList, requestyDefaultModelId } from "@roo-code/types"

Expand Down Expand Up @@ -35,6 +35,13 @@ export const Requesty = ({

const [didRefetch, setDidRefetch] = useState<boolean>()

const [requestyEndpointSelected, setRequestyEndpointSelected] = useState(!!apiConfiguration.requestyBaseUrl)

// This ensures that the "Use custom URL" checkbox is hidden when the user deletes the URL.
useEffect(() => {
setRequestyEndpointSelected(!!apiConfiguration?.requestyBaseUrl)
}, [apiConfiguration?.requestyBaseUrl])

const handleInputChange = useCallback(
<K extends keyof ProviderSettings, E>(
field: K,
Expand Down Expand Up @@ -72,6 +79,31 @@ export const Requesty = ({
{t("settings:providers.getRequestyApiKey")}
</VSCodeButtonLink>
)}

<VSCodeCheckbox
checked={requestyEndpointSelected}
onChange={(e: any) => {
const isChecked = e.target.checked === true
if (!isChecked) {
setApiConfigurationField("requestyBaseUrl", undefined)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it intentional that unchecking the checkbox immediately clears the base URL value? Users might accidentally uncheck it and lose their custom URL. Consider preserving the value and only clearing it when explicitly deleted by the user, or perhaps add a confirmation dialog?

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it intentional that unchecking the checkbox immediately clears the base URL value? Users might accidentally uncheck it and lose their custom URL. Consider preserving the value and only clearing it when explicitly deleted by the user, or perhaps add a confirmation dialog?

}

setRequestyEndpointSelected(isChecked)
}}>
{t("settings:providers.requestyUseCustomBaseUrl")}
</VSCodeCheckbox>
{requestyEndpointSelected && (
<VSCodeTextField
value={apiConfiguration?.requestyBaseUrl || ""}
type="text"
onInput={handleInputChange("requestyBaseUrl")}
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider adding URL validation for the custom base URL input. Currently, any string is accepted which could lead to runtime errors if an invalid URL is provided. You could add validation similar to other providers:

Copy link
Contributor

Choose a reason for hiding this comment

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

Consider adding URL validation for the custom base URL input. Currently, any string is accepted which could lead to runtime errors if an invalid URL is provided. You could add validation similar to other providers to ensure the URL is valid before saving.

placeholder={t("settings:providers.getRequestyBaseUrl")}
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider showing the default URL as a placeholder to guide users. Instead of just the translation key, you could show:

This would help users understand the expected format.

Copy link
Contributor

Choose a reason for hiding this comment

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

Consider showing the default URL as a placeholder to guide users. Instead of just the translation key, you could show the default URL (https://router.requesty.ai/v1) to help users understand the expected format.

className="w-full">
<div className="flex justify-between items-center mb-1">
<label className="block font-medium">{t("settings:providers.getRequestyBaseUrl")}</label>
</div>
</VSCodeTextField>
)}
<Button
variant="outline"
onClick={() => {
Expand Down
2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/ca/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/de/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@
"error": "Failed to refresh models list. Please try again."
},
"getRequestyApiKey": "Get Requesty API Key",
"getRequestyBaseUrl": "Base URL",
"requestyUseCustomBaseUrl": "Use custom base URL",
"openRouterTransformsText": "Compress prompts and message chains to the context size (<a>OpenRouter Transforms</a>)",
"anthropicApiKey": "Anthropic API Key",
"getAnthropicApiKey": "Get Anthropic API Key",
Expand Down
2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/es/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/fr/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/hi/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/id/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/it/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/ja/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/ko/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/nl/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/pl/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/pt-BR/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/ru/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/tr/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/vi/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/zh-CN/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions webview-ui/src/i18n/locales/zh-TW/settings.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading