mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-10 22:41:14 +00:00
add litellm reasoning effort control
This commit is contained in:
parent
8de608a0df
commit
bb9a7460b4
23 changed files with 325 additions and 18 deletions
|
|
@ -6,6 +6,8 @@ import { z } from "zod"
|
|||
|
||||
export const reasoningEfforts = ["low", "medium", "high"] as const
|
||||
|
||||
export const reasoningEffortsWithDefault = ["default", "low", "medium", "high"] as const
|
||||
|
||||
export const reasoningEffortsSchema = z.enum(reasoningEfforts)
|
||||
|
||||
export type ReasoningEffort = z.infer<typeof reasoningEffortsSchema>
|
||||
|
|
@ -37,6 +39,7 @@ export const modelInfoSchema = z.object({
|
|||
supportsReasoningBudget: z.boolean().optional(),
|
||||
requiredReasoningBudget: z.boolean().optional(),
|
||||
supportsReasoningEffort: z.boolean().optional(),
|
||||
shouldExposeDefaultReasoningEffort: z.boolean().optional(),
|
||||
supportedParameters: z.array(modelParametersSchema).optional(),
|
||||
inputPrice: z.number().optional(),
|
||||
outputPrice: z.number().optional(),
|
||||
|
|
|
|||
186
src/api/providers/__tests__/litellm.test.ts
Normal file
186
src/api/providers/__tests__/litellm.test.ts
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
import { LiteLLMHandler } from "../litellm"
|
||||
import { ApiHandlerOptions } from "../../../shared/api"
|
||||
|
||||
// Mock the getModelParams function
|
||||
jest.mock("../../transform/model-params", () => ({
|
||||
getModelParams: jest.fn(),
|
||||
}))
|
||||
|
||||
// Mock the RouterProvider's fetchModel method
|
||||
jest.mock("../router-provider", () => {
|
||||
return {
|
||||
RouterProvider: class MockRouterProvider {
|
||||
protected options: any
|
||||
protected models: any = {}
|
||||
protected client: any = {
|
||||
chat: {
|
||||
completions: {
|
||||
create: jest.fn(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
constructor(config: any) {
|
||||
this.options = config.options
|
||||
}
|
||||
|
||||
async fetchModel() {
|
||||
return { id: "test-model", info: { maxTokens: 4096 } }
|
||||
}
|
||||
|
||||
getModel() {
|
||||
return { id: "test-model", info: { maxTokens: 4096 } }
|
||||
}
|
||||
|
||||
supportsTemperature() {
|
||||
return true
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
describe("LiteLLMHandler", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("should include reasoning_effort in request when configured", async () => {
|
||||
const { getModelParams } = require("../../transform/model-params")
|
||||
getModelParams.mockReturnValue({
|
||||
maxTokens: 4096,
|
||||
temperature: 0,
|
||||
reasoningEffort: "high",
|
||||
})
|
||||
|
||||
const mockCreate = jest.fn().mockReturnValue({
|
||||
withResponse: () =>
|
||||
Promise.resolve({
|
||||
data: (async function* () {
|
||||
yield {
|
||||
choices: [{ delta: { content: "test response" } }],
|
||||
usage: { prompt_tokens: 10, completion_tokens: 5 },
|
||||
}
|
||||
})(),
|
||||
}),
|
||||
})
|
||||
|
||||
const options: ApiHandlerOptions = {
|
||||
reasoningEffort: "high",
|
||||
}
|
||||
|
||||
const handler = new LiteLLMHandler(options)
|
||||
// Override the client mock
|
||||
;(handler as any).client.chat.completions.create = mockCreate
|
||||
|
||||
// Call createMessage to trigger the request
|
||||
const generator = handler.createMessage("test system", [{ role: "user", content: "test message" }])
|
||||
|
||||
// Consume the generator
|
||||
const results = []
|
||||
for await (const chunk of generator) {
|
||||
results.push(chunk)
|
||||
}
|
||||
|
||||
// Verify that reasoning_effort was included in the request
|
||||
expect(mockCreate).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
reasoning_effort: "high",
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("should not include reasoning_effort when not configured", async () => {
|
||||
const { getModelParams } = require("../../transform/model-params")
|
||||
getModelParams.mockReturnValue({
|
||||
maxTokens: 4096,
|
||||
temperature: 0,
|
||||
reasoningEffort: undefined,
|
||||
})
|
||||
|
||||
const mockCreate = jest.fn().mockReturnValue({
|
||||
withResponse: () =>
|
||||
Promise.resolve({
|
||||
data: (async function* () {
|
||||
yield {
|
||||
choices: [{ delta: { content: "test response" } }],
|
||||
usage: { prompt_tokens: 10, completion_tokens: 5 },
|
||||
}
|
||||
})(),
|
||||
}),
|
||||
})
|
||||
|
||||
const options: ApiHandlerOptions = {}
|
||||
|
||||
const handler = new LiteLLMHandler(options)
|
||||
// Override the client mock
|
||||
;(handler as any).client.chat.completions.create = mockCreate
|
||||
|
||||
// Call createMessage to trigger the request
|
||||
const generator = handler.createMessage("test system", [{ role: "user", content: "test message" }])
|
||||
|
||||
// Consume the generator
|
||||
const results = []
|
||||
for await (const chunk of generator) {
|
||||
results.push(chunk)
|
||||
}
|
||||
|
||||
// Verify that reasoning_effort was not included in the request
|
||||
const callArgs = mockCreate.mock.calls[0][0]
|
||||
expect(callArgs).not.toHaveProperty("reasoning_effort")
|
||||
})
|
||||
|
||||
it("should handle reasoning content in response stream", async () => {
|
||||
const { getModelParams } = require("../../transform/model-params")
|
||||
getModelParams.mockReturnValue({
|
||||
maxTokens: 4096,
|
||||
temperature: 0,
|
||||
reasoningEffort: "medium",
|
||||
})
|
||||
|
||||
const mockCreate = jest.fn().mockReturnValue({
|
||||
withResponse: () =>
|
||||
Promise.resolve({
|
||||
data: (async function* () {
|
||||
yield {
|
||||
choices: [{ delta: { content: "regular content" } }],
|
||||
}
|
||||
yield {
|
||||
choices: [{ delta: { reasoning_content: "reasoning content" } }],
|
||||
}
|
||||
yield {
|
||||
choices: [{ delta: {} }],
|
||||
usage: { prompt_tokens: 10, completion_tokens: 5 },
|
||||
}
|
||||
})(),
|
||||
}),
|
||||
})
|
||||
|
||||
const options: ApiHandlerOptions = {
|
||||
reasoningEffort: "medium",
|
||||
}
|
||||
|
||||
const handler = new LiteLLMHandler(options)
|
||||
// Override the client mock
|
||||
;(handler as any).client.chat.completions.create = mockCreate
|
||||
|
||||
// Call createMessage to trigger the request
|
||||
const generator = handler.createMessage("test system", [{ role: "user", content: "test message" }])
|
||||
|
||||
// Consume the generator and collect results
|
||||
const results = []
|
||||
for await (const chunk of generator) {
|
||||
results.push(chunk)
|
||||
}
|
||||
|
||||
// Verify we got both text and reasoning content
|
||||
expect(results).toEqual([
|
||||
{ type: "text", text: "regular content" },
|
||||
{ type: "reasoning", text: "reasoning content" },
|
||||
{
|
||||
type: "usage",
|
||||
inputTokens: 10,
|
||||
outputTokens: 5,
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
|
@ -69,6 +69,8 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: true,
|
||||
supportsComputerUse: true,
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: 3,
|
||||
outputPrice: 15,
|
||||
description: "claude-3-5-sonnet via LiteLLM proxy",
|
||||
|
|
@ -79,6 +81,8 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: false,
|
||||
supportsComputerUse: false,
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: 10,
|
||||
outputPrice: 30,
|
||||
description: "gpt-4-turbo via LiteLLM proxy",
|
||||
|
|
@ -147,6 +151,8 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: true,
|
||||
supportsComputerUse: true,
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: undefined,
|
||||
outputPrice: undefined,
|
||||
description: "test-computer-model via LiteLLM proxy",
|
||||
|
|
@ -158,6 +164,8 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: false,
|
||||
supportsComputerUse: false,
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: undefined,
|
||||
outputPrice: undefined,
|
||||
description: "test-non-computer-model via LiteLLM proxy",
|
||||
|
|
@ -293,6 +301,8 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: true,
|
||||
supportsComputerUse: true, // Should be true due to fallback
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: undefined,
|
||||
outputPrice: undefined,
|
||||
description: "claude-3-5-sonnet-latest via LiteLLM proxy",
|
||||
|
|
@ -304,6 +314,8 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: false,
|
||||
supportsComputerUse: false, // Should be false as it's not in fallback list
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: undefined,
|
||||
outputPrice: undefined,
|
||||
description: "gpt-4-turbo via LiteLLM proxy",
|
||||
|
|
@ -367,6 +379,8 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: true,
|
||||
supportsComputerUse: false, // False because explicitly set to false (fallback ignored)
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: undefined,
|
||||
outputPrice: undefined,
|
||||
description: "claude-3-5-sonnet-latest via LiteLLM proxy",
|
||||
|
|
@ -378,6 +392,8 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: false,
|
||||
supportsComputerUse: true, // True because explicitly set to true
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: undefined,
|
||||
outputPrice: undefined,
|
||||
description: "custom-model via LiteLLM proxy",
|
||||
|
|
@ -389,12 +405,53 @@ describe("getLiteLLMModels", () => {
|
|||
supportsImages: false,
|
||||
supportsComputerUse: false, // False because explicitly set to false
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: false,
|
||||
shouldExposeDefaultReasoningEffort: false,
|
||||
inputPrice: undefined,
|
||||
outputPrice: undefined,
|
||||
description: "another-custom-model via LiteLLM proxy",
|
||||
})
|
||||
})
|
||||
|
||||
it("sets shouldExposeDefaultReasoningEffort when supports_reasoning is true", async () => {
|
||||
const mockResponse = {
|
||||
data: {
|
||||
data: [
|
||||
{
|
||||
model_name: "reasoning-model",
|
||||
model_info: {
|
||||
max_tokens: 4096,
|
||||
max_input_tokens: 200000,
|
||||
supports_vision: true,
|
||||
supports_prompt_caching: false,
|
||||
supports_reasoning: true, // This should set shouldExposeDefaultReasoningEffort to true
|
||||
},
|
||||
litellm_params: {
|
||||
model: "openai/o1-preview",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
mockedAxios.get.mockResolvedValue(mockResponse)
|
||||
|
||||
const result = await getLiteLLMModels("test-api-key", "http://localhost:4000")
|
||||
|
||||
expect(result["reasoning-model"]).toEqual({
|
||||
maxTokens: 4096,
|
||||
contextWindow: 200000,
|
||||
supportsImages: true,
|
||||
supportsComputerUse: false,
|
||||
supportsPromptCache: false,
|
||||
supportsReasoningEffort: true,
|
||||
shouldExposeDefaultReasoningEffort: true,
|
||||
inputPrice: undefined,
|
||||
outputPrice: undefined,
|
||||
description: "reasoning-model via LiteLLM proxy",
|
||||
})
|
||||
})
|
||||
|
||||
it("handles fallback detection with various model name formats", async () => {
|
||||
const mockResponse = {
|
||||
data: {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ export async function getLiteLLMModels(apiKey: string, baseUrl: string): Promise
|
|||
// litellm_params.model may have a prefix like openrouter/
|
||||
supportsComputerUse,
|
||||
supportsPromptCache: Boolean(modelInfo.supports_prompt_caching),
|
||||
supportsReasoningEffort: Boolean(modelInfo.supports_reasoning),
|
||||
shouldExposeDefaultReasoningEffort: Boolean(modelInfo.supports_reasoning),
|
||||
inputPrice: modelInfo.input_cost_per_token ? modelInfo.input_cost_per_token * 1000000 : undefined,
|
||||
outputPrice: modelInfo.output_cost_per_token
|
||||
? modelInfo.output_cost_per_token * 1000000
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { Anthropic } from "@anthropic-ai/sdk" // Keep for type usage only
|
|||
import { ApiHandlerOptions, litellmDefaultModelId, litellmDefaultModelInfo } from "../../shared/api"
|
||||
import { ApiStream, ApiStreamUsageChunk } from "../transform/stream"
|
||||
import { convertToOpenAiMessages } from "../transform/openai-format"
|
||||
import { getModelParams } from "../transform/model-params"
|
||||
import type { SingleCompletionHandler, ApiHandlerCreateMessageMetadata } from "../index"
|
||||
import { RouterProvider } from "./router-provider"
|
||||
|
||||
|
|
@ -26,21 +27,32 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa
|
|||
})
|
||||
}
|
||||
|
||||
override getModel() {
|
||||
const { id, info } = super.getModel()
|
||||
|
||||
const params = getModelParams({
|
||||
format: "openai",
|
||||
modelId: id,
|
||||
model: info,
|
||||
settings: this.options,
|
||||
})
|
||||
|
||||
return { id, info, ...params }
|
||||
}
|
||||
|
||||
override async *createMessage(
|
||||
systemPrompt: string,
|
||||
messages: Anthropic.Messages.MessageParam[],
|
||||
metadata?: ApiHandlerCreateMessageMetadata,
|
||||
): ApiStream {
|
||||
const { id: modelId, info } = await this.fetchModel()
|
||||
await this.fetchModel() // Ensure models are loaded
|
||||
const { id: modelId, maxTokens, temperature, reasoningEffort: reasoning_effort } = this.getModel()
|
||||
|
||||
const openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [
|
||||
{ role: "system", content: systemPrompt },
|
||||
...convertToOpenAiMessages(messages),
|
||||
]
|
||||
|
||||
// Required by some providers; others default to max tokens allowed
|
||||
let maxTokens: number | undefined = info.maxTokens ?? undefined
|
||||
|
||||
const requestOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming = {
|
||||
model: modelId,
|
||||
max_tokens: maxTokens,
|
||||
|
|
@ -49,10 +61,11 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa
|
|||
stream_options: {
|
||||
include_usage: true,
|
||||
},
|
||||
...(reasoning_effort && { reasoning_effort }),
|
||||
}
|
||||
|
||||
if (this.supportsTemperature(modelId)) {
|
||||
requestOptions.temperature = this.options.modelTemperature ?? 0
|
||||
requestOptions.temperature = temperature
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -62,12 +75,27 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa
|
|||
|
||||
for await (const chunk of completion) {
|
||||
const delta = chunk.choices[0]?.delta
|
||||
const usage = chunk.usage as OpenAI.CompletionUsage
|
||||
|
||||
// Log all available fields in delta
|
||||
console.log("[LiteLLM] Delta fields:", Object.keys(delta || {}))
|
||||
console.log("[LiteLLM] Full delta:", JSON.stringify(delta, null, 2))
|
||||
|
||||
// Check for any field that might contain reasoning
|
||||
if (delta) {
|
||||
for (const [key, value] of Object.entries(delta)) {
|
||||
if (typeof value === "string" && value.length > 0 && key.includes("reason")) {
|
||||
console.log(`[LiteLLM] Found potential reasoning field '${key}':`, value)
|
||||
yield { type: "reasoning", text: value }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (delta?.content) {
|
||||
yield { type: "text", text: delta.content }
|
||||
}
|
||||
|
||||
const usage = chunk.usage as OpenAI.CompletionUsage
|
||||
|
||||
if (usage) {
|
||||
lastUsage = usage
|
||||
}
|
||||
|
|
@ -91,20 +119,21 @@ export class LiteLLMHandler extends RouterProvider implements SingleCompletionHa
|
|||
}
|
||||
|
||||
async completePrompt(prompt: string): Promise<string> {
|
||||
const { id: modelId, info } = await this.fetchModel()
|
||||
await this.fetchModel() // Ensure models are loaded
|
||||
const { id: modelId, maxTokens, temperature, reasoningEffort: reasoning_effort } = this.getModel()
|
||||
|
||||
try {
|
||||
const requestOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = {
|
||||
model: modelId,
|
||||
messages: [{ role: "user", content: prompt }],
|
||||
max_tokens: maxTokens,
|
||||
...(reasoning_effort && { reasoning_effort }),
|
||||
}
|
||||
|
||||
if (this.supportsTemperature(modelId)) {
|
||||
requestOptions.temperature = this.options.modelTemperature ?? 0
|
||||
requestOptions.temperature = temperature
|
||||
}
|
||||
|
||||
requestOptions.max_tokens = info.maxTokens
|
||||
|
||||
const response = await this.client.chat.completions.create(requestOptions)
|
||||
return response.choices[0]?.message.content || ""
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
import { useEffect } from "react"
|
||||
import { Checkbox } from "vscrui"
|
||||
|
||||
import { type ProviderSettings, type ModelInfo, type ReasoningEffort, reasoningEfforts } from "@roo-code/types"
|
||||
import {
|
||||
type ProviderSettings,
|
||||
type ModelInfo,
|
||||
type ReasoningEffort,
|
||||
reasoningEfforts,
|
||||
reasoningEffortsWithDefault,
|
||||
} from "@roo-code/types"
|
||||
|
||||
import { DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS, DEFAULT_HYBRID_REASONING_MODEL_THINKING_TOKENS } from "@roo/api"
|
||||
|
||||
|
|
@ -20,6 +26,7 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
|
|||
const isReasoningBudgetSupported = !!modelInfo && modelInfo.supportsReasoningBudget
|
||||
const isReasoningBudgetRequired = !!modelInfo && modelInfo.requiredReasoningBudget
|
||||
const isReasoningEffortSupported = !!modelInfo && modelInfo.supportsReasoningEffort
|
||||
const shouldExposeDefaultReasoningEffort = !!modelInfo && modelInfo.shouldExposeDefaultReasoningEffort
|
||||
|
||||
const enableReasoningEffort = apiConfiguration.enableReasoningEffort
|
||||
const customMaxOutputTokens = apiConfiguration.modelMaxTokens || DEFAULT_HYBRID_REASONING_MODEL_MAX_TOKENS
|
||||
|
|
@ -95,17 +102,23 @@ export const ThinkingBudget = ({ apiConfiguration, setApiConfigurationField, mod
|
|||
<label className="block font-medium mb-1">{t("settings:providers.reasoningEffort.label")}</label>
|
||||
</div>
|
||||
<Select
|
||||
value={apiConfiguration.reasoningEffort}
|
||||
onValueChange={(value) => setApiConfigurationField("reasoningEffort", value as ReasoningEffort)}>
|
||||
value={apiConfiguration.reasoningEffort || (shouldExposeDefaultReasoningEffort ? "default" : undefined)}
|
||||
onValueChange={(value) => {
|
||||
// If "default" is selected, set reasoningEffort to undefined so it's not sent in the request
|
||||
const reasoningEffort = value === "default" ? undefined : (value as ReasoningEffort)
|
||||
setApiConfigurationField("reasoningEffort", reasoningEffort)
|
||||
}}>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue placeholder={t("settings:common.select")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{reasoningEfforts.map((value) => (
|
||||
<SelectItem key={value} value={value}>
|
||||
{t(`settings:providers.reasoningEffort.${value}`)}
|
||||
</SelectItem>
|
||||
))}
|
||||
{(shouldExposeDefaultReasoningEffort ? reasoningEffortsWithDefault : reasoningEfforts).map(
|
||||
(value) => (
|
||||
<SelectItem key={value} value={value}>
|
||||
{t(`settings:providers.reasoningEffort.${value}`)}
|
||||
</SelectItem>
|
||||
),
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Esforç de raonament del model",
|
||||
"default": "Per defecte",
|
||||
"high": "Alt",
|
||||
"medium": "Mitjà",
|
||||
"low": "Baix"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Modell-Denkaufwand",
|
||||
"default": "Standard",
|
||||
"high": "Hoch",
|
||||
"medium": "Mittel",
|
||||
"low": "Niedrig"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Model Reasoning Effort",
|
||||
"default": "Default",
|
||||
"high": "High",
|
||||
"medium": "Medium",
|
||||
"low": "Low"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Esfuerzo de razonamiento del modelo",
|
||||
"default": "Por defecto",
|
||||
"high": "Alto",
|
||||
"medium": "Medio",
|
||||
"low": "Bajo"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Effort de raisonnement du modèle",
|
||||
"default": "Par défaut",
|
||||
"high": "Élevé",
|
||||
"medium": "Moyen",
|
||||
"low": "Faible"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "मॉडल तर्क प्रयास",
|
||||
"default": "डिफ़ॉल्ट",
|
||||
"high": "उच्च",
|
||||
"medium": "मध्यम",
|
||||
"low": "निम्न"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Sforzo di ragionamento del modello",
|
||||
"default": "Predefinito",
|
||||
"high": "Alto",
|
||||
"medium": "Medio",
|
||||
"low": "Basso"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "モデル推論の労力",
|
||||
"default": "デフォルト",
|
||||
"high": "高",
|
||||
"medium": "中",
|
||||
"low": "低"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "모델 추론 노력",
|
||||
"default": "기본값",
|
||||
"high": "높음",
|
||||
"medium": "중간",
|
||||
"low": "낮음"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Model redeneervermogen",
|
||||
"default": "Standaard",
|
||||
"high": "Hoog",
|
||||
"medium": "Middel",
|
||||
"low": "Laag"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Wysiłek rozumowania modelu",
|
||||
"default": "Domyślny",
|
||||
"high": "Wysoki",
|
||||
"medium": "Średni",
|
||||
"low": "Niski"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Esforço de raciocínio do modelo",
|
||||
"default": "Padrão",
|
||||
"high": "Alto",
|
||||
"medium": "Médio",
|
||||
"low": "Baixo"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Усилия по рассуждению модели",
|
||||
"default": "По умолчанию",
|
||||
"high": "Высокие",
|
||||
"medium": "Средние",
|
||||
"low": "Низкие"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Model Akıl Yürütme Çabası",
|
||||
"default": "Varsayılan",
|
||||
"high": "Yüksek",
|
||||
"medium": "Orta",
|
||||
"low": "Düşük"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "Nỗ lực suy luận của mô hình",
|
||||
"default": "Mặc định",
|
||||
"high": "Cao",
|
||||
"medium": "Trung bình",
|
||||
"low": "Thấp"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "模型推理强度",
|
||||
"default": "默认",
|
||||
"high": "高",
|
||||
"medium": "中",
|
||||
"low": "低"
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@
|
|||
},
|
||||
"reasoningEffort": {
|
||||
"label": "模型推理強度",
|
||||
"default": "預設",
|
||||
"high": "高",
|
||||
"medium": "中",
|
||||
"low": "低"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue