mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-08 22:21:23 +00:00
feat: Add Reasoning Effort setting for OpenAI Compatible provider (#2906)
This commit is contained in:
parent
21ea433b88
commit
2075f26f18
27 changed files with 318 additions and 28 deletions
5
.changeset/odd-ligers-press.md
Normal file
5
.changeset/odd-ligers-press.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"roo-cline": minor
|
||||
---
|
||||
|
||||
Add Reasoning Effort setting for OpenAI Compatible provider
|
||||
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -77,6 +77,7 @@
|
|||
"@types/jest": "^29.5.14",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "20.x",
|
||||
"@types/node-cache": "^4.1.3",
|
||||
"@types/node-ipc": "^9.2.3",
|
||||
"@types/string-similarity": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
||||
|
|
@ -9006,6 +9007,16 @@
|
|||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node-cache": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node-cache/-/node-cache-4.1.3.tgz",
|
||||
"integrity": "sha512-3hsqnv3H1zkOhjygJaJUYmgz5+FcPO3vejBX7cE9/cnuINOJYrzkfOnUCvpwGe9kMZANIHJA7J5pOdeyv52OEw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node-fetch": {
|
||||
"version": "2.6.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz",
|
||||
|
|
|
|||
|
|
@ -469,6 +469,7 @@
|
|||
"@types/jest": "^29.5.14",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "20.x",
|
||||
"@types/node-cache": "^4.1.3",
|
||||
"@types/node-ipc": "^9.2.3",
|
||||
"@types/string-similarity": "^4.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// npx jest src/api/providers/__tests__/openai.test.ts
|
||||
|
||||
import { OpenAiHandler } from "../openai"
|
||||
import { ApiHandlerOptions } from "../../../shared/api"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
|
|
@ -155,6 +157,39 @@ describe("OpenAiHandler", () => {
|
|||
expect(textChunks).toHaveLength(1)
|
||||
expect(textChunks[0].text).toBe("Test response")
|
||||
})
|
||||
it("should include reasoning_effort when reasoning effort is enabled", async () => {
|
||||
const reasoningOptions: ApiHandlerOptions = {
|
||||
...mockOptions,
|
||||
enableReasoningEffort: true,
|
||||
openAiCustomModelInfo: { contextWindow: 128_000, supportsPromptCache: false, reasoningEffort: "high" },
|
||||
}
|
||||
const reasoningHandler = new OpenAiHandler(reasoningOptions)
|
||||
const stream = reasoningHandler.createMessage(systemPrompt, messages)
|
||||
// Consume the stream to trigger the API call
|
||||
for await (const _chunk of stream) {
|
||||
}
|
||||
// Assert the mockCreate was called with reasoning_effort
|
||||
expect(mockCreate).toHaveBeenCalled()
|
||||
const callArgs = mockCreate.mock.calls[0][0]
|
||||
expect(callArgs.reasoning_effort).toBe("high")
|
||||
})
|
||||
|
||||
it("should not include reasoning_effort when reasoning effort is disabled", async () => {
|
||||
const noReasoningOptions: ApiHandlerOptions = {
|
||||
...mockOptions,
|
||||
enableReasoningEffort: false,
|
||||
openAiCustomModelInfo: { contextWindow: 128_000, supportsPromptCache: false },
|
||||
}
|
||||
const noReasoningHandler = new OpenAiHandler(noReasoningOptions)
|
||||
const stream = noReasoningHandler.createMessage(systemPrompt, messages)
|
||||
// Consume the stream to trigger the API call
|
||||
for await (const _chunk of stream) {
|
||||
}
|
||||
// Assert the mockCreate was called without reasoning_effort
|
||||
expect(mockCreate).toHaveBeenCalled()
|
||||
const callArgs = mockCreate.mock.calls[0][0]
|
||||
expect(callArgs.reasoning_effort).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe("error handling", () => {
|
||||
|
|
|
|||
1
src/exports/roo-code.d.ts
vendored
1
src/exports/roo-code.d.ts
vendored
|
|
@ -87,6 +87,7 @@ type ProviderSettings = {
|
|||
openAiUseAzure?: boolean | undefined
|
||||
azureApiVersion?: string | undefined
|
||||
openAiStreamingEnabled?: boolean | undefined
|
||||
enableReasoningEffort?: boolean | undefined
|
||||
ollamaModelId?: string | undefined
|
||||
ollamaBaseUrl?: string | undefined
|
||||
vsCodeLmModelSelector?:
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ type ProviderSettings = {
|
|||
openAiUseAzure?: boolean | undefined
|
||||
azureApiVersion?: string | undefined
|
||||
openAiStreamingEnabled?: boolean | undefined
|
||||
enableReasoningEffort?: boolean | undefined
|
||||
ollamaModelId?: string | undefined
|
||||
ollamaBaseUrl?: string | undefined
|
||||
vsCodeLmModelSelector?:
|
||||
|
|
|
|||
|
|
@ -355,6 +355,7 @@ export const providerSettingsSchema = z.object({
|
|||
openAiUseAzure: z.boolean().optional(),
|
||||
azureApiVersion: z.string().optional(),
|
||||
openAiStreamingEnabled: z.boolean().optional(),
|
||||
enableReasoningEffort: z.boolean().optional(),
|
||||
// Ollama
|
||||
ollamaModelId: z.string().optional(),
|
||||
ollamaBaseUrl: z.string().optional(),
|
||||
|
|
@ -453,6 +454,7 @@ const providerSettingsRecord: ProviderSettingsRecord = {
|
|||
openAiUseAzure: undefined,
|
||||
azureApiVersion: undefined,
|
||||
openAiStreamingEnabled: undefined,
|
||||
enableReasoningEffort: undefined,
|
||||
// Ollama
|
||||
ollamaModelId: undefined,
|
||||
ollamaBaseUrl: undefined,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ describe("enhancePrompt", () => {
|
|||
apiProvider: "openai",
|
||||
openAiApiKey: "test-key",
|
||||
openAiBaseUrl: "https://api.openai.com/v1",
|
||||
enableReasoningEffort: false,
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -97,6 +98,7 @@ describe("enhancePrompt", () => {
|
|||
apiProvider: "openrouter",
|
||||
openRouterApiKey: "test-key",
|
||||
openRouterModelId: "test-model",
|
||||
enableReasoningEffort: false,
|
||||
}
|
||||
|
||||
// Mock successful enhancement
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import React, { memo, useCallback, useEffect, useMemo, useState } from "react"
|
||||
import { useAppTranslation } from "@/i18n/TranslationContext"
|
||||
import { Trans } from "react-i18next"
|
||||
import { getRequestyAuthUrl, getOpenRouterAuthUrl, getGlamaAuthUrl } from "@src/oauth/urls"
|
||||
import { useDebounce, useEvent } from "react-use"
|
||||
import { Trans } from "react-i18next"
|
||||
import { LanguageModelChatSelector } from "vscode"
|
||||
import { Checkbox } from "vscrui"
|
||||
import { VSCodeLink, VSCodeRadio, VSCodeRadioGroup, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
|
||||
import { ExternalLinkIcon } from "@radix-ui/react-icons"
|
||||
|
||||
import { ReasoningEffort as ReasoningEffortType } from "@roo/schemas"
|
||||
import {
|
||||
ApiConfiguration,
|
||||
ModelInfo,
|
||||
|
|
@ -21,21 +20,22 @@ import {
|
|||
ApiProvider,
|
||||
} from "@roo/shared/api"
|
||||
import { ExtensionMessage } from "@roo/shared/ExtensionMessage"
|
||||
import { AWS_REGIONS } from "@roo/shared/aws_regions"
|
||||
|
||||
import { vscode } from "@src/utils/vscode"
|
||||
import { validateApiConfiguration, validateModelId, validateBedrockArn } from "@src/utils/validate"
|
||||
import { useRouterModels } from "@/components/ui/hooks/useRouterModels"
|
||||
import { useSelectedModel } from "@/components/ui/hooks/useSelectedModel"
|
||||
import { useAppTranslation } from "@src/i18n/TranslationContext"
|
||||
import { useRouterModels } from "@src/components/ui/hooks/useRouterModels"
|
||||
import { useSelectedModel } from "@src/components/ui/hooks/useSelectedModel"
|
||||
import {
|
||||
useOpenRouterModelProviders,
|
||||
OPENROUTER_DEFAULT_PROVIDER_NAME,
|
||||
} from "@src/components/ui/hooks/useOpenRouterModelProviders"
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Button } from "@src/components/ui"
|
||||
import { getRequestyAuthUrl, getOpenRouterAuthUrl, getGlamaAuthUrl } from "@src/oauth/urls"
|
||||
|
||||
import { VSCodeButtonLink } from "../common/VSCodeButtonLink"
|
||||
|
||||
import { MODELS_BY_PROVIDER, PROVIDERS, VERTEX_REGIONS, REASONING_MODELS } from "./constants"
|
||||
import { MODELS_BY_PROVIDER, PROVIDERS, VERTEX_REGIONS, REASONING_MODELS, AWS_REGIONS } from "./constants"
|
||||
import { ModelInfoView } from "./ModelInfoView"
|
||||
import { ModelPicker } from "./ModelPicker"
|
||||
import { ApiErrorMessage } from "./ApiErrorMessage"
|
||||
|
|
@ -851,6 +851,41 @@ const ApiOptions = ({
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-1">
|
||||
<Checkbox
|
||||
checked={apiConfiguration.enableReasoningEffort ?? false}
|
||||
onChange={(checked: boolean) => {
|
||||
setApiConfigurationField("enableReasoningEffort", checked)
|
||||
|
||||
if (!checked) {
|
||||
const { reasoningEffort: _, ...openAiCustomModelInfo } =
|
||||
apiConfiguration.openAiCustomModelInfo || openAiModelInfoSaneDefaults
|
||||
|
||||
setApiConfigurationField("openAiCustomModelInfo", openAiCustomModelInfo)
|
||||
}
|
||||
}}>
|
||||
{t("settings:providers.setReasoningLevel")}
|
||||
</Checkbox>
|
||||
{!!apiConfiguration.enableReasoningEffort && (
|
||||
<ReasoningEffort
|
||||
apiConfiguration={{
|
||||
...apiConfiguration,
|
||||
reasoningEffort: apiConfiguration.openAiCustomModelInfo?.reasoningEffort,
|
||||
}}
|
||||
setApiConfigurationField={(field, value) => {
|
||||
if (field === "reasoningEffort") {
|
||||
const openAiCustomModelInfo =
|
||||
apiConfiguration.openAiCustomModelInfo || openAiModelInfoSaneDefaults
|
||||
|
||||
setApiConfigurationField("openAiCustomModelInfo", {
|
||||
...openAiCustomModelInfo,
|
||||
reasoningEffort: value as ReasoningEffortType,
|
||||
})
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="text-sm text-vscode-descriptionForeground whitespace-pre-line">
|
||||
{t("settings:providers.customModel.capabilities")}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
// npx jest src/components/settings/__tests__/ApiOptions.test.ts
|
||||
|
||||
import { render, screen } from "@testing-library/react"
|
||||
import { render, screen, fireEvent } from "@testing-library/react"
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||
|
||||
import { ApiConfiguration } from "@roo/shared/api"
|
||||
|
||||
import { ExtensionStateContextProvider } from "@/context/ExtensionStateContext"
|
||||
import { openAiModelInfoSaneDefaults } from "@roo/shared/api"
|
||||
|
||||
import ApiOptions, { ApiOptionsProps } from "../ApiOptions"
|
||||
|
||||
|
|
@ -26,8 +27,13 @@ jest.mock("@vscode/webview-ui-toolkit/react", () => ({
|
|||
// Mock other components
|
||||
jest.mock("vscrui", () => ({
|
||||
Checkbox: ({ children, checked, onChange }: any) => (
|
||||
<label>
|
||||
<input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} />
|
||||
<label data-testid={`checkbox-${children?.toString().replace(/\s+/g, "-").toLowerCase()}`}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onChange={(e) => onChange(e.target.checked)}
|
||||
data-testid={`checkbox-input-${children?.toString().replace(/\s+/g, "-").toLowerCase()}`}
|
||||
/>
|
||||
{children}
|
||||
</label>
|
||||
),
|
||||
|
|
@ -51,11 +57,32 @@ jest.mock("@/components/ui", () => ({
|
|||
</option>
|
||||
),
|
||||
SelectSeparator: ({ children }: any) => <div className="select-separator-mock">{children}</div>,
|
||||
Button: ({ children, onClick }: any) => (
|
||||
<button onClick={onClick} className="button-mock">
|
||||
Button: ({ children, onClick, _variant, role, className }: any) => (
|
||||
<button onClick={onClick} className={`button-mock ${className || ""}`} role={role}>
|
||||
{children}
|
||||
</button>
|
||||
),
|
||||
// Add missing components used by ModelPicker
|
||||
Command: ({ children }: any) => <div className="command-mock">{children}</div>,
|
||||
CommandEmpty: ({ children }: any) => <div className="command-empty-mock">{children}</div>,
|
||||
CommandGroup: ({ children }: any) => <div className="command-group-mock">{children}</div>,
|
||||
CommandInput: ({ value, onValueChange, placeholder, className, _ref }: any) => (
|
||||
<input
|
||||
value={value}
|
||||
onChange={(e) => onValueChange && onValueChange(e.target.value)}
|
||||
placeholder={placeholder}
|
||||
className={className}
|
||||
/>
|
||||
),
|
||||
CommandItem: ({ children, value, onSelect }: any) => (
|
||||
<div className="command-item-mock" onClick={() => onSelect && onSelect(value)}>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
CommandList: ({ children }: any) => <div className="command-list-mock">{children}</div>,
|
||||
Popover: ({ children, _open, _onOpenChange }: any) => <div className="popover-mock">{children}</div>,
|
||||
PopoverContent: ({ children, _className }: any) => <div className="popover-content-mock">{children}</div>,
|
||||
PopoverTrigger: ({ children, _asChild }: any) => <div className="popover-trigger-mock">{children}</div>,
|
||||
Slider: ({ value, onChange }: any) => (
|
||||
<div data-testid="slider">
|
||||
<input type="range" value={value || 0} onChange={(e) => onChange(parseFloat(e.target.value))} />
|
||||
|
|
@ -136,6 +163,21 @@ jest.mock("@src/components/ui/hooks/useSelectedModel", () => ({
|
|||
}),
|
||||
}))
|
||||
|
||||
jest.mock("../ReasoningEffort", () => ({
|
||||
ReasoningEffort: ({ apiConfiguration, setApiConfigurationField, value }: any) => (
|
||||
<div data-testid="reasoning-effort-select">
|
||||
<select
|
||||
value={value ?? apiConfiguration.openAiCustomModelInfo?.reasoningEffort}
|
||||
onChange={(e) => setApiConfigurationField("reasoningEffort", e.target.value)}>
|
||||
<option value="auto">Auto</option>
|
||||
<option value="low">Low</option>
|
||||
<option value="medium">Medium</option>
|
||||
<option value="high">High</option>
|
||||
</select>
|
||||
</div>
|
||||
),
|
||||
}))
|
||||
|
||||
const renderApiOptions = (props: Partial<ApiOptionsProps> = {}) => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
|
|
@ -215,4 +257,141 @@ describe("ApiOptions", () => {
|
|||
// since we have separate tests for that component. We just need to verify that
|
||||
// it's included in the ApiOptions component when appropriate.
|
||||
})
|
||||
|
||||
describe("OpenAI provider tests", () => {
|
||||
it("removes reasoningEffort from openAiCustomModelInfo when unchecked", () => {
|
||||
const mockSetApiConfigurationField = jest.fn()
|
||||
const initialConfig = {
|
||||
apiProvider: "openai" as const,
|
||||
enableReasoningEffort: true,
|
||||
openAiCustomModelInfo: {
|
||||
...openAiModelInfoSaneDefaults, // Start with defaults
|
||||
reasoningEffort: "low" as const, // Set an initial value
|
||||
},
|
||||
// Add other necessary default fields for openai provider if needed
|
||||
}
|
||||
|
||||
renderApiOptions({
|
||||
apiConfiguration: initialConfig,
|
||||
setApiConfigurationField: mockSetApiConfigurationField,
|
||||
})
|
||||
|
||||
// Find the checkbox by its test ID instead of label text
|
||||
// This is more reliable than using the label text which might be affected by translations
|
||||
const checkbox =
|
||||
screen.getByTestId("checkbox-input-settings:providers.setreasoninglevel") ||
|
||||
screen.getByTestId("checkbox-input-set-reasoning-level")
|
||||
|
||||
// Simulate unchecking the checkbox
|
||||
fireEvent.click(checkbox)
|
||||
|
||||
// 1. Check if enableReasoningEffort was set to false
|
||||
expect(mockSetApiConfigurationField).toHaveBeenCalledWith("enableReasoningEffort", false)
|
||||
|
||||
// 2. Check if openAiCustomModelInfo was updated
|
||||
const updateCall = mockSetApiConfigurationField.mock.calls.find(
|
||||
(call) => call[0] === "openAiCustomModelInfo",
|
||||
)
|
||||
expect(updateCall).toBeDefined()
|
||||
|
||||
// 3. Check if reasoningEffort property is absent in the updated info
|
||||
const updatedInfo = updateCall[1]
|
||||
expect(updatedInfo).not.toHaveProperty("reasoningEffort")
|
||||
|
||||
// Optional: Check if other properties were preserved (example)
|
||||
expect(updatedInfo).toHaveProperty("contextWindow", openAiModelInfoSaneDefaults.contextWindow)
|
||||
})
|
||||
|
||||
it("does not render ReasoningEffort component when initially disabled", () => {
|
||||
const mockSetApiConfigurationField = jest.fn()
|
||||
const initialConfig = {
|
||||
apiProvider: "openai" as const,
|
||||
enableReasoningEffort: false, // Initially disabled
|
||||
openAiCustomModelInfo: {
|
||||
...openAiModelInfoSaneDefaults,
|
||||
},
|
||||
}
|
||||
|
||||
renderApiOptions({
|
||||
apiConfiguration: initialConfig,
|
||||
setApiConfigurationField: mockSetApiConfigurationField,
|
||||
})
|
||||
|
||||
// Check that the ReasoningEffort select component is not rendered
|
||||
expect(screen.queryByTestId("reasoning-effort-select")).not.toBeInTheDocument()
|
||||
// Or, if the mock is simpler:
|
||||
// expect(screen.queryByRole("combobox", { name: /reasoning effort/i })).not.toBeInTheDocument();
|
||||
})
|
||||
|
||||
it("renders ReasoningEffort component and sets flag when checkbox is checked", () => {
|
||||
const mockSetApiConfigurationField = jest.fn()
|
||||
const initialConfig = {
|
||||
apiProvider: "openai" as const,
|
||||
enableReasoningEffort: false, // Initially disabled
|
||||
openAiCustomModelInfo: {
|
||||
...openAiModelInfoSaneDefaults,
|
||||
},
|
||||
}
|
||||
|
||||
renderApiOptions({
|
||||
apiConfiguration: initialConfig,
|
||||
setApiConfigurationField: mockSetApiConfigurationField,
|
||||
})
|
||||
|
||||
const checkbox = screen.getByTestId("checkbox-input-settings:providers.setreasoninglevel")
|
||||
|
||||
// Simulate checking the checkbox
|
||||
fireEvent.click(checkbox)
|
||||
|
||||
// 1. Check if enableReasoningEffort was set to true
|
||||
expect(mockSetApiConfigurationField).toHaveBeenCalledWith("enableReasoningEffort", true)
|
||||
|
||||
// We can't directly test the rendering of the ReasoningEffort component after the state change
|
||||
// without a more complex setup involving state management mocks or re-rendering.
|
||||
// However, we've tested the state update call.
|
||||
})
|
||||
|
||||
it("updates reasoningEffort in openAiCustomModelInfo when select value changes", () => {
|
||||
const mockSetApiConfigurationField = jest.fn()
|
||||
const initialConfig = {
|
||||
apiProvider: "openai" as const,
|
||||
enableReasoningEffort: true, // Initially enabled
|
||||
openAiCustomModelInfo: {
|
||||
...openAiModelInfoSaneDefaults,
|
||||
reasoningEffort: "low" as const,
|
||||
},
|
||||
}
|
||||
|
||||
renderApiOptions({
|
||||
apiConfiguration: initialConfig,
|
||||
setApiConfigurationField: mockSetApiConfigurationField,
|
||||
})
|
||||
|
||||
// Find the reasoning effort select among all comboboxes by its current value
|
||||
const allSelects = screen.getAllByRole("combobox") as HTMLSelectElement[]
|
||||
const reasoningSelect = allSelects.find(
|
||||
(el) => el.value === initialConfig.openAiCustomModelInfo.reasoningEffort,
|
||||
)
|
||||
expect(reasoningSelect).toBeDefined()
|
||||
|
||||
// Simulate changing the reasoning effort to 'high'
|
||||
fireEvent.change(reasoningSelect!, { target: { value: "high" } })
|
||||
|
||||
// Check if setApiConfigurationField was called correctly for openAiCustomModelInfo
|
||||
expect(mockSetApiConfigurationField).toHaveBeenCalledWith(
|
||||
"openAiCustomModelInfo",
|
||||
expect.objectContaining({
|
||||
reasoningEffort: "high",
|
||||
}),
|
||||
)
|
||||
|
||||
// Check that other properties were preserved
|
||||
expect(mockSetApiConfigurationField).toHaveBeenCalledWith(
|
||||
"openAiCustomModelInfo",
|
||||
expect.objectContaining({
|
||||
contextWindow: openAiModelInfoSaneDefaults.contextWindow,
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import {
|
|||
|
||||
export { REASONING_MODELS, PROMPT_CACHING_MODELS } from "@roo/shared/api"
|
||||
|
||||
export { AWS_REGIONS } from "@roo/shared/aws_regions"
|
||||
|
||||
export const MODELS_BY_PROVIDER: Partial<Record<ApiProvider, Record<string, ModelInfo>>> = {
|
||||
anthropic: anthropicModels,
|
||||
bedrock: bedrockModels,
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Alt",
|
||||
"medium": "Mitjà",
|
||||
"low": "Baix"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Activa l'esforç de raonament"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Hoch",
|
||||
"medium": "Mittel",
|
||||
"low": "Niedrig"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Denkaufwand aktivieren"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "High",
|
||||
"medium": "Medium",
|
||||
"low": "Low"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Enable Reasoning Effort"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Alto",
|
||||
"medium": "Medio",
|
||||
"low": "Bajo"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Habilitar esfuerzo de razonamiento"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Élevé",
|
||||
"medium": "Moyen",
|
||||
"low": "Faible"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Activer l'effort de raisonnement"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "उच्च",
|
||||
"medium": "मध्यम",
|
||||
"low": "निम्न"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "तर्क प्रयास सक्षम करें"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Alto",
|
||||
"medium": "Medio",
|
||||
"low": "Basso"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Abilita sforzo di ragionamento"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "高",
|
||||
"medium": "中",
|
||||
"low": "低"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "推論労力を有効にする"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "높음",
|
||||
"medium": "중간",
|
||||
"low": "낮음"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "추론 노력 활성화"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Wysoki",
|
||||
"medium": "Średni",
|
||||
"low": "Niski"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Włącz wysiłek rozumowania"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Alto",
|
||||
"medium": "Médio",
|
||||
"low": "Baixo"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Habilitar esforço de raciocínio"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Высокие",
|
||||
"medium": "Средние",
|
||||
"low": "Низкие"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Включить усилие рассуждения"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Yüksek",
|
||||
"medium": "Orta",
|
||||
"low": "Düşük"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Akıl Yürütme Çabasını Etkinleştir"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "Cao",
|
||||
"medium": "Trung bình",
|
||||
"low": "Thấp"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "Kích hoạt nỗ lực suy luận"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "高",
|
||||
"medium": "中",
|
||||
"low": "低"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "启用推理工作量"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
|
|
@ -233,7 +233,8 @@
|
|||
"high": "高",
|
||||
"medium": "中",
|
||||
"low": "低"
|
||||
}
|
||||
},
|
||||
"setReasoningLevel": "啟用推理工作量"
|
||||
},
|
||||
"browser": {
|
||||
"enable": {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue