From 8d753f1d649fb38ee05d9eda8600e3af869ca6f0 Mon Sep 17 00:00:00 2001 From: MaxLashk Date: Wed, 28 May 2025 15:39:11 +0300 Subject: [PATCH 1/8] API LLM Timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Roo Code often emits API socket-timeout errors when using self-hosted, slow LLMs — either while reading a large file or even during the initial prompt phase. Yet these slow models can be usable in autonomous (e.g. overnight) scenarios for working on some private code source. It would be great to have a user-tunable setting to configure the API timeout for self-hosted providers (OpenAI-compatible, Ollama, LMStudio, etc.). The timeout can be up to 30 minutes to allow big file chunks or prompts to be fully processed. This way, even an older laptop could produce meaningful results overnight with roo code. --- packages/types/src/provider-settings.ts | 6 +++++ src/api/providers/lm-studio.ts | 2 ++ src/api/providers/ollama.ts | 2 ++ src/api/providers/openai.ts | 4 ++++ .../settings/providers/LMStudio.tsx | 22 +++++++++++++++++++ .../components/settings/providers/Ollama.tsx | 22 +++++++++++++++++++ .../settings/providers/OpenAICompatible.tsx | 22 +++++++++++++++++++ webview-ui/src/i18n/locales/ca/settings.json | 2 ++ webview-ui/src/i18n/locales/de/settings.json | 2 ++ webview-ui/src/i18n/locales/en/settings.json | 2 ++ webview-ui/src/i18n/locales/es/settings.json | 2 ++ webview-ui/src/i18n/locales/fr/settings.json | 2 ++ webview-ui/src/i18n/locales/hi/settings.json | 2 ++ webview-ui/src/i18n/locales/it/settings.json | 2 ++ webview-ui/src/i18n/locales/ja/settings.json | 2 ++ webview-ui/src/i18n/locales/ko/settings.json | 2 ++ webview-ui/src/i18n/locales/nl/settings.json | 2 ++ webview-ui/src/i18n/locales/pl/settings.json | 2 ++ .../src/i18n/locales/pt-BR/settings.json | 2 ++ webview-ui/src/i18n/locales/ru/settings.json | 2 ++ webview-ui/src/i18n/locales/tr/settings.json | 2 ++ webview-ui/src/i18n/locales/vi/settings.json | 2 ++ .../src/i18n/locales/zh-CN/settings.json | 2 ++ .../src/i18n/locales/zh-TW/settings.json | 2 ++ 24 files changed, 114 insertions(+) diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 65e3f9b5b6..86a1f63524 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -123,11 +123,13 @@ const openAiSchema = baseProviderSettingsSchema.extend({ openAiStreamingEnabled: z.boolean().optional(), openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration. openAiHeaders: z.record(z.string(), z.string()).optional(), + openAiApiTimeout: z.number().optional().describe("Timeout in milliseconds for OpenAI API requests"), }) const ollamaSchema = baseProviderSettingsSchema.extend({ ollamaModelId: z.string().optional(), ollamaBaseUrl: z.string().optional(), + ollamaApiTimeout: z.number().optional().describe("Timeout in minutes for Ollama API requests"), }) const vsCodeLmSchema = baseProviderSettingsSchema.extend({ @@ -146,6 +148,7 @@ const lmStudioSchema = baseProviderSettingsSchema.extend({ lmStudioBaseUrl: z.string().optional(), lmStudioDraftModelId: z.string().optional(), lmStudioSpeculativeDecodingEnabled: z.boolean().optional(), + lmStudioApiTimeout: z.number().optional().describe("Timeout in minutes for LMStudio API requests"), }) const geminiSchema = apiModelIdProviderModelSchema.extend({ @@ -265,9 +268,12 @@ export const MODEL_ID_KEYS: Partial[] = [ "glamaModelId", "openRouterModelId", "openAiModelId", + "openAiApiTimeout", "ollamaModelId", + "ollamaApiTimeout", "lmStudioModelId", "lmStudioDraftModelId", + "lmStudioApiTimeout", "unboundModelId", "requestyModelId", "litellmModelId", diff --git a/src/api/providers/lm-studio.ts b/src/api/providers/lm-studio.ts index f032e2d560..f3cd0c0719 100644 --- a/src/api/providers/lm-studio.ts +++ b/src/api/providers/lm-studio.ts @@ -21,9 +21,11 @@ export class LmStudioHandler extends BaseProvider implements SingleCompletionHan constructor(options: ApiHandlerOptions) { super() this.options = options + const timeoutMs = (this.options.lmStudioApiTimeout ?? 10) * 60 * 1000 this.client = new OpenAI({ baseURL: (this.options.lmStudioBaseUrl || "http://localhost:1234") + "/v1", apiKey: "noop", + timeout: timeoutMs, }) } diff --git a/src/api/providers/ollama.ts b/src/api/providers/ollama.ts index 7f384e9a98..85843ecd2e 100644 --- a/src/api/providers/ollama.ts +++ b/src/api/providers/ollama.ts @@ -24,9 +24,11 @@ export class OllamaHandler extends BaseProvider implements SingleCompletionHandl constructor(options: ApiHandlerOptions) { super() this.options = options + const timeoutMs = (this.options.ollamaApiTimeout ?? 10) * 60 * 1000 this.client = new OpenAI({ baseURL: (this.options.ollamaBaseUrl || "http://localhost:11434") + "/v1", apiKey: "ollama", + timeout: timeoutMs, }) } diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index b4f256f43a..81896ba2d4 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -40,6 +40,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl const isAzureAiInference = this._isAzureAiInference(this.options.openAiBaseUrl) const urlHost = this._getUrlHost(this.options.openAiBaseUrl) const isAzureOpenAi = urlHost === "azure.com" || urlHost.endsWith(".azure.com") || options.openAiUseAzure + const timeoutMs = (this.options.openAiApiTimeout ?? 10) * 60 * 1000 // Timeout is provided in minutes, convert to ms const headers = { ...DEFAULT_HEADERS, @@ -52,6 +53,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl baseURL, apiKey, defaultHeaders: headers, + timeout: timeoutMs, defaultQuery: { "api-version": this.options.azureApiVersion || "2024-05-01-preview" }, }) } else if (isAzureOpenAi) { @@ -62,12 +64,14 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl apiKey, apiVersion: this.options.azureApiVersion || azureOpenAiDefaultApiVersion, defaultHeaders: headers, + timeout: timeoutMs, }) } else { this.client = new OpenAI({ baseURL, apiKey, defaultHeaders: headers, + timeout: timeoutMs, }) } } diff --git a/webview-ui/src/components/settings/providers/LMStudio.tsx b/webview-ui/src/components/settings/providers/LMStudio.tsx index 9177457039..1cd3cc26ae 100644 --- a/webview-ui/src/components/settings/providers/LMStudio.tsx +++ b/webview-ui/src/components/settings/providers/LMStudio.tsx @@ -64,6 +64,28 @@ export const LMStudio = ({ apiConfiguration, setApiConfigurationField }: LMStudi className="w-full"> + { + const value = parseInt((e.target as HTMLInputElement).value) + return isNaN(value) ? undefined : value + })} + type="text" + inputMode="numeric" + placeholder={t("settings:placeholders.numbers.maxTokens")} + style={{ + borderColor: (() => { + const value = apiConfiguration?.lmStudioApiTimeout + if (!value) return "var(--vscode-input-border)" + return value > 0 ? "var(--vscode-charts-green)" : "var(--vscode-errorForeground)" + })(), + }} + className="w-full mt-4"> + + +
+ {t("settings:providers.openAiApiTimeoutDescription")} +
{lmStudioModels.length > 0 && ( + { + const value = parseInt((e.target as HTMLInputElement).value) + return isNaN(value) ? undefined : value + })} + type="text" + inputMode="numeric" + placeholder={t("settings:placeholders.numbers.maxTokens")} + style={{ + borderColor: (() => { + const value = apiConfiguration?.ollamaApiTimeout + if (!value) return "var(--vscode-input-border)" + return value > 0 ? "var(--vscode-charts-green)" : "var(--vscode-errorForeground)" + })(), + }} + className="w-full mt-4"> + + +
+ {t("settings:providers.openAiApiTimeoutDescription")} +
{ollamaModels.length > 0 && ( + { + const value = parseInt((e.target as HTMLInputElement).value) + return isNaN(value) ? undefined : value + })} + type="text" + inputMode="numeric" + placeholder={t("settings:placeholders.numbers.maxTokens")} + style={{ + borderColor: (() => { + const value = apiConfiguration?.openAiApiTimeout + if (!value) return "var(--vscode-input-border)" + return value > 0 ? "var(--vscode-charts-green)" : "var(--vscode-errorForeground)" + })(), + }} + className="w-full mt-4"> + + +
+ {t("settings:providers.openAiApiTimeoutDescription")} +
) } diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index c88005ea61..170b315285 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -184,6 +184,8 @@ "apiKey": "Clau API", "openAiBaseUrl": "URL base", "getOpenAiApiKey": "Obtenir clau API d'OpenAI", + "openAiApiTimeout": "Temps d'espera (minuts)", + "openAiApiTimeoutDescription": "Temps d'espera per a sol·licituds d'API al proveïdor (mín. 5 min). Si no hi ha resposta en aquest període, la sol·licitud es reintenta. Augmenta el valor per a models més lents.", "mistralApiKey": "Clau API de Mistral", "getMistralApiKey": "Obtenir clau API de Mistral / Codestral", "codestralBaseUrl": "URL base de Codestral (opcional)", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 27a7486436..6b09e2c1c8 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -184,6 +184,8 @@ "apiKey": "API-Schlüssel", "openAiBaseUrl": "Basis-URL", "getOpenAiApiKey": "OpenAI API-Schlüssel erhalten", + "openAiApiTimeout": "Zeitlimit (Minuten)", + "openAiApiTimeoutDescription": "Zeitlimit für API-Anfragen an den Anbieter (mind. 5 Min.). Wenn innerhalb dieses Zeitraums keine Antwort erfolgt, wird die Anfrage wiederholt. Erhöhen Sie den Wert für langsamere Modelle.", "mistralApiKey": "Mistral API-Schlüssel", "getMistralApiKey": "Mistral / Codestral API-Schlüssel erhalten", "codestralBaseUrl": "Codestral Basis-URL (Optional)", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index b8e51afc50..20bd23abe3 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -183,6 +183,8 @@ "openAiApiKey": "OpenAI API Key", "apiKey": "API Key", "openAiBaseUrl": "Base URL", + "openAiApiTimeout": "Timeout (minutes)", + "openAiApiTimeoutDescription": "Timeout for API requests to Provider (min 5 min). if no response within this period, the request is retried. Increase for slower models.", "getOpenAiApiKey": "Get OpenAI API Key", "mistralApiKey": "Mistral API Key", "getMistralApiKey": "Get Mistral / Codestral API Key", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index db8b4736eb..31dc11a9fd 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -183,6 +183,8 @@ "openAiApiKey": "Clave API de OpenAI", "apiKey": "Clave API", "openAiBaseUrl": "URL base", + "openAiApiTimeout": "Tiempo de espera (minutos)", + "openAiApiTimeoutDescription": "Tiempo de espera para solicitudes de API al proveedor (mín. 5 min). Si no hay respuesta en este período, la solicitud se reintentará. Aumente este valor para modelos más lentos.", "getOpenAiApiKey": "Obtener clave API de OpenAI", "mistralApiKey": "Clave API de Mistral", "getMistralApiKey": "Obtener clave API de Mistral / Codestral", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index 0bf837accb..5154967619 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -183,6 +183,8 @@ "openAiApiKey": "Clé API OpenAI", "apiKey": "Clé API", "openAiBaseUrl": "URL de base", + "openAiApiTimeout": "Délai d'attente (minutes)", + "openAiApiTimeoutDescription": "Délai d'attente pour les requêtes API au fournisseur (min. 5 min). Si aucune réponse dans ce délai, la requête sera réessayée. Augmentez cette valeur pour les modèles plus lents.", "getOpenAiApiKey": "Obtenir la clé API OpenAI", "mistralApiKey": "Clé API Mistral", "getMistralApiKey": "Obtenir la clé API Mistral / Codestral", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index fec1b27007..19dc21ac53 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -183,6 +183,8 @@ "openAiApiKey": "OpenAI API कुंजी", "apiKey": "API कुंजी", "openAiBaseUrl": "बेस URL", + "openAiApiTimeout": "Timeout (मिनट)", + "openAiApiTimeoutDescription": "Timeout for API requests to Provider (min 5 min). if no response within this period, the request is retried. Increase for slower models.", "getOpenAiApiKey": "OpenAI API कुंजी प्राप्त करें", "mistralApiKey": "Mistral API कुंजी", "getMistralApiKey": "Mistral / Codestral API कुंजी प्राप्त करें", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index fcb389a4a7..823c88f56c 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -183,6 +183,8 @@ "openAiApiKey": "Chiave API OpenAI", "apiKey": "Chiave API", "openAiBaseUrl": "URL base", + "openAiApiTimeout": "Timeout (minuti)", + "openAiApiTimeoutDescription": "Timeout per le richieste API al provider (min. 5 min). Se non c'è risposta entro questo periodo, la richiesta viene ripetuta. Aumentare per modelli più lenti.", "getOpenAiApiKey": "Ottieni chiave API OpenAI", "mistralApiKey": "Chiave API Mistral", "getMistralApiKey": "Ottieni chiave API Mistral / Codestral", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index eabd751308..ba37265db7 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -184,6 +184,8 @@ "apiKey": "APIキー", "openAiBaseUrl": "ベースURL", "getOpenAiApiKey": "OpenAI APIキーを取得", + "openAiApiTimeout": "タイムアウト(分)", + "openAiApiTimeoutDescription": "プロバイダーへのAPIリクエストのタイムアウト(最小5分)。この期間内に応答がない場合、リクエストが再試行されます。遅いモデルの場合は値を増やしてください。", "mistralApiKey": "Mistral APIキー", "getMistralApiKey": "Mistral / Codestral APIキーを取得", "codestralBaseUrl": "Codestral ベースURL(オプション)", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 68ca2a963c..fca2a08630 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -184,6 +184,8 @@ "openAiApiKey": "OpenAI API 키", "openAiBaseUrl": "기본 URL", "getOpenAiApiKey": "OpenAI API 키 받기", + "openAiApiTimeout": "타임아웃(분)", + "openAiApiTimeoutDescription": "제공자에 대한 API 요청의 타임아웃(최소 5분). 이 기간 내에 응답이 없으면 요청이 재시도됩니다. 느린 모델의 경우 값을 늘리세요.", "mistralApiKey": "Mistral API 키", "getMistralApiKey": "Mistral / Codestral API 키 받기", "codestralBaseUrl": "Codestral 기본 URL (선택사항)", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index 996c0c673c..e8fdfeb240 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -183,6 +183,8 @@ "apiKey": "API-sleutel", "openAiApiKey": "OpenAI API-sleutel", "openAiBaseUrl": "Basis-URL", + "openAiApiTimeout": "Timeout (minuten)", + "openAiApiTimeoutDescription": "Timeout voor API-verzoeken aan de provider (min. 5 min). Als er binnen deze periode geen antwoord is, wordt het verzoek opnieuw geprobeerd. Verhoog deze waarde voor tragere modellen.", "getOpenAiApiKey": "OpenAI API-sleutel ophalen", "mistralApiKey": "Mistral API-sleutel", "getMistralApiKey": "Mistral / Codestral API-sleutel ophalen", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index cf4421e00e..8e671472f2 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -184,6 +184,8 @@ "openAiApiKey": "Klucz API OpenAI", "openAiBaseUrl": "URL bazowy", "getOpenAiApiKey": "Uzyskaj klucz API OpenAI", + "openAiApiTimeout": "Limit czasu (minuty)", + "openAiApiTimeoutDescription": "Limit czasu dla zapytań API do dostawcy (min. 5 min). Jeśli w tym czasie nie ma odpowiedzi, zapytanie jest ponawiane. Zwiększ dla wolniejszych modeli.", "mistralApiKey": "Klucz API Mistral", "getMistralApiKey": "Uzyskaj klucz API Mistral / Codestral", "codestralBaseUrl": "URL bazowy Codestral (opcjonalnie)", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index 229419dd23..9a6582821e 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -183,6 +183,8 @@ "apiKey": "Chave de API", "openAiApiKey": "Chave de API OpenAI", "openAiBaseUrl": "URL Base", + "openAiApiTimeout": "Tempo limite (minutos)", + "openAiApiTimeoutDescription": "Tempo limite para solicitações de API ao provedor (mín. 5 min). Se não houver resposta neste período, a solicitação será repetida. Aumente este valor para modelos mais lentos.", "getOpenAiApiKey": "Obter chave de API OpenAI", "mistralApiKey": "Chave de API Mistral", "getMistralApiKey": "Obter chave de API Mistral / Codestral", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index dcce5e5b1a..bfe57ee7b3 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -183,6 +183,8 @@ "apiKey": "API-ключ", "openAiApiKey": "OpenAI API-ключ", "openAiBaseUrl": "Базовый URL", + "openAiApiTimeout": "Таймаут (минуты)", + "openAiApiTimeoutDescription": "Таймаут для запросов к провайдеру API (минимум 5 мин). Если нет ответа за это время, запрос будет повторён. Увеличьте значение для медленных моделей.", "getOpenAiApiKey": "Получить OpenAI API-ключ", "mistralApiKey": "Mistral API-ключ", "getMistralApiKey": "Получить Mistral / Codestral API-ключ", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index f8f53ae21c..2113b36927 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -183,6 +183,8 @@ "openAiApiKey": "OpenAI API Anahtarı", "apiKey": "API Anahtarı", "openAiBaseUrl": "Temel URL", + "openAiApiTimeout": "Zaman aşımı (dakika)", + "openAiApiTimeoutDescription": "Sağlayıcıya yapılan API istekleri için zaman aşımı (min. 5 dk). Bu süre içinde yanıt yoksa, istek yeniden denenir. Daha yavaş modeller için bu değeri artırın.", "getOpenAiApiKey": "OpenAI API Anahtarı Al", "mistralApiKey": "Mistral API Anahtarı", "getMistralApiKey": "Mistral / Codestral API Anahtarı Al", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index edb2b386b2..4ce4e631a7 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -183,6 +183,8 @@ "openAiApiKey": "Khóa API OpenAI", "apiKey": "Khóa API", "openAiBaseUrl": "URL cơ sở", + "openAiApiTimeout": "Thời gian chờ (phút)", + "openAiApiTimeoutDescription": "Thời gian chờ cho các yêu cầu API đến nhà cung cấp (tối thiểu 5 phút). Nếu không có phản hồi trong khoảng thời gian này, yêu cầu sẽ được thử lại. Tăng giá trị này cho các mô hình chậm hơn.", "getOpenAiApiKey": "Lấy khóa API OpenAI", "mistralApiKey": "Khóa API Mistral", "getMistralApiKey": "Lấy khóa API Mistral / Codestral", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 51ae2269e4..f400948a13 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -184,6 +184,8 @@ "apiKey": "API 密钥", "openAiBaseUrl": "OpenAI 基础 URL", "getOpenAiApiKey": "获取 OpenAI API 密钥", + "openAiApiTimeout": "超时时间(分钟)", + "openAiApiTimeoutDescription": "对提供者的 API 请求超时时间(最少 5 分钟)。若在此期间无响应,将重试请求。对于较慢的模型请增加此值。", "mistralApiKey": "Mistral API 密钥", "getMistralApiKey": "获取 Mistral / Codestral API 密钥", "codestralBaseUrl": "Codestral 基础 URL(可选)", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 07544879cd..7ca26d955f 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -184,6 +184,8 @@ "apiKey": "API 金鑰", "openAiBaseUrl": "基礎 URL", "getOpenAiApiKey": "取得 OpenAI API 金鑰", + "openAiApiTimeout": "逾時(分鐘)", + "openAiApiTimeoutDescription": "對提供者的 API 請求逾時(最少 5 分鐘)。若在此期間無回應,請求將會重試。對於較慢的模型請增加此值。", "mistralApiKey": "Mistral API 金鑰", "getMistralApiKey": "取得 Mistral/Codestral API 金鑰", "codestralBaseUrl": "Codestral 基礎 URL(選用)", From 5b3964dbe0592b97112e65d008324835245568eb Mon Sep 17 00:00:00 2001 From: MaxLashk Date: Wed, 28 May 2025 23:01:10 +0300 Subject: [PATCH 2/8] Placeholder text bugfix --- webview-ui/src/components/settings/providers/LMStudio.tsx | 2 +- webview-ui/src/components/settings/providers/Ollama.tsx | 2 +- .../src/components/settings/providers/OpenAICompatible.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/webview-ui/src/components/settings/providers/LMStudio.tsx b/webview-ui/src/components/settings/providers/LMStudio.tsx index 1cd3cc26ae..cde628425c 100644 --- a/webview-ui/src/components/settings/providers/LMStudio.tsx +++ b/webview-ui/src/components/settings/providers/LMStudio.tsx @@ -72,7 +72,7 @@ export const LMStudio = ({ apiConfiguration, setApiConfigurationField }: LMStudi })} type="text" inputMode="numeric" - placeholder={t("settings:placeholders.numbers.maxTokens")} + placeholder="10" style={{ borderColor: (() => { const value = apiConfiguration?.lmStudioApiTimeout diff --git a/webview-ui/src/components/settings/providers/Ollama.tsx b/webview-ui/src/components/settings/providers/Ollama.tsx index d6897fa533..bcd1338f43 100644 --- a/webview-ui/src/components/settings/providers/Ollama.tsx +++ b/webview-ui/src/components/settings/providers/Ollama.tsx @@ -71,7 +71,7 @@ export const Ollama = ({ apiConfiguration, setApiConfigurationField }: OllamaPro })} type="text" inputMode="numeric" - placeholder={t("settings:placeholders.numbers.maxTokens")} + placeholder="10" style={{ borderColor: (() => { const value = apiConfiguration?.ollamaApiTimeout diff --git a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx index cdb810b604..beba0e870b 100644 --- a/webview-ui/src/components/settings/providers/OpenAICompatible.tsx +++ b/webview-ui/src/components/settings/providers/OpenAICompatible.tsx @@ -624,7 +624,7 @@ export const OpenAICompatible = ({ })} type="text" inputMode="numeric" - placeholder={t("settings:placeholders.numbers.maxTokens")} + placeholder="10" style={{ borderColor: (() => { const value = apiConfiguration?.openAiApiTimeout From 665f0c9660cc053c078fc56dbcfede4772db7287 Mon Sep 17 00:00:00 2001 From: MaxLashk Date: Fri, 30 May 2025 15:25:28 +0300 Subject: [PATCH 3/8] test(openai): add timeout check to OpenAI client initialization test Update the test to verify that the OpenAI client is initialized with a timeout parameter, while maintaining the existing test structure and assertions for other configuration options. --- src/api/providers/__tests__/openai.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/providers/__tests__/openai.spec.ts b/src/api/providers/__tests__/openai.spec.ts index fc809819e8..6b1ac31ff0 100644 --- a/src/api/providers/__tests__/openai.spec.ts +++ b/src/api/providers/__tests__/openai.spec.ts @@ -101,6 +101,7 @@ describe("OpenAiHandler", () => { expect(vi.mocked(OpenAI)).toHaveBeenCalledWith({ baseURL: expect.any(String), apiKey: expect.any(String), + timeout: expect.any(Number), defaultHeaders: { "HTTP-Referer": "https://github.com/RooVetGit/Roo-Cline", "X-Title": "Roo Code", From 0e9c2fb595c9378f8a918b3440c41082548e047f Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 30 May 2025 14:09:49 -0500 Subject: [PATCH 4/8] refactor: remove describe --- packages/types/src/provider-settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 86a1f63524..97695a845f 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -123,7 +123,7 @@ const openAiSchema = baseProviderSettingsSchema.extend({ openAiStreamingEnabled: z.boolean().optional(), openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration. openAiHeaders: z.record(z.string(), z.string()).optional(), - openAiApiTimeout: z.number().optional().describe("Timeout in milliseconds for OpenAI API requests"), + openAiApiTimeout: z.number().optional(), }) const ollamaSchema = baseProviderSettingsSchema.extend({ From 6aa0163a37a6754997fe2de2686709fd14fd3374 Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 30 May 2025 14:10:30 -0500 Subject: [PATCH 5/8] refactor: remove describe --- packages/types/src/provider-settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 97695a845f..530197b518 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -129,7 +129,7 @@ const openAiSchema = baseProviderSettingsSchema.extend({ const ollamaSchema = baseProviderSettingsSchema.extend({ ollamaModelId: z.string().optional(), ollamaBaseUrl: z.string().optional(), - ollamaApiTimeout: z.number().optional().describe("Timeout in minutes for Ollama API requests"), + ollamaApiTimeout: z.number().optional(), }) const vsCodeLmSchema = baseProviderSettingsSchema.extend({ From 0bd84b79607248fac7fd1e1478842b1b70b6321d Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Fri, 30 May 2025 14:10:47 -0500 Subject: [PATCH 6/8] refactor: remove describe --- packages/types/src/provider-settings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index 530197b518..205a039a02 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -148,7 +148,7 @@ const lmStudioSchema = baseProviderSettingsSchema.extend({ lmStudioBaseUrl: z.string().optional(), lmStudioDraftModelId: z.string().optional(), lmStudioSpeculativeDecodingEnabled: z.boolean().optional(), - lmStudioApiTimeout: z.number().optional().describe("Timeout in minutes for LMStudio API requests"), + lmStudioApiTimeout: z.number().optional(), }) const geminiSchema = apiModelIdProviderModelSchema.extend({ From f3237a618926343b4964a777987624c8216e6eba Mon Sep 17 00:00:00 2001 From: MaxLashk Date: Fri, 30 May 2025 23:12:47 +0300 Subject: [PATCH 7/8] fixed Hindi translation for openAiApiTimeoutDescription --- webview-ui/src/i18n/locales/hi/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 19dc21ac53..5dc7cd46af 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -184,7 +184,7 @@ "apiKey": "API कुंजी", "openAiBaseUrl": "बेस URL", "openAiApiTimeout": "Timeout (मिनट)", - "openAiApiTimeoutDescription": "Timeout for API requests to Provider (min 5 min). if no response within this period, the request is retried. Increase for slower models.", + "openAiApiTimeoutDescription": "प्रदाता को API अनुरोधों के लिए समय सीमा (न्यूनतम 5 मिनट)। यदि इस अवधि के भीतर कोई प्रतिक्रिया नहीं मिलती है, तो अनुरोध को फिर से भेजा जाता है। धीमे मॉडल के लिए समय सीमा बढ़ाएं।", "getOpenAiApiKey": "OpenAI API कुंजी प्राप्त करें", "mistralApiKey": "Mistral API कुंजी", "getMistralApiKey": "Mistral / Codestral API कुंजी प्राप्त करें", From 70e9ab6e16df766aff8ed7381a2c69259dd9afd6 Mon Sep 17 00:00:00 2001 From: MaxLashk Date: Thu, 19 Jun 2025 16:35:56 +0300 Subject: [PATCH 8/8] fixed Indonesian translation for openAiApiTimeoutDescription --- webview-ui/src/i18n/locales/id/settings.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index 6d6a8e93b1..fbccc1b2fc 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -187,6 +187,8 @@ "openAiApiKey": "OpenAI API Key", "apiKey": "API Key", "openAiBaseUrl": "Base URL", + "openAiApiTimeout": "Batas waktu (menit)", + "openAiApiTimeoutDescription": "Batas waktu untuk permintaan API ke Provider (minimal 5 menit). Jika tidak ada respons dalam periode ini, permintaan akan dicoba lagi. Tingkatkan untuk model yang lebih lambat.", "getOpenAiApiKey": "Dapatkan OpenAI API Key", "mistralApiKey": "Mistral API Key", "getMistralApiKey": "Dapatkan Mistral / Codestral API Key",