diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 92ea6aa957e..226661537ad 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -311,6 +311,7 @@ export class Task extends EventEmitter implements TaskLike { consecutiveMistakeLimit: number consecutiveMistakeCountForApplyDiff: Map = new Map() consecutiveNoToolUseCount: number = 0 + consecutiveNoAssistantMessagesCount: number = 0 toolUsage: ToolUsage = {} // Checkpoints @@ -1985,6 +1986,7 @@ export class Task extends EventEmitter implements TaskLike { // Reset consecutive error counters on abort (manual intervention) this.consecutiveNoToolUseCount = 0 + this.consecutiveNoAssistantMessagesCount = 0 // Force final token usage update before abort event this.emitFinalTokenUsageUpdate() @@ -3158,6 +3160,8 @@ export class Task extends EventEmitter implements TaskLike { ) if (hasTextContent || hasToolUses) { + // Reset counter when we get a successful response with content + this.consecutiveNoAssistantMessagesCount = 0 // Display grounding sources to the user if they exist if (pendingGroundingSources.length > 0) { const citationLinks = pendingGroundingSources.map((source, i) => `[${i + 1}](${source.url})`) @@ -3291,6 +3295,15 @@ export class Task extends EventEmitter implements TaskLike { // or tool_use content blocks from API which we should assume is // an error. + // Increment consecutive no-assistant-messages counter + this.consecutiveNoAssistantMessagesCount++ + + // Only show error and count toward mistake limit after 2 consecutive failures + // This provides a "grace retry" - first failure retries silently + if (this.consecutiveNoAssistantMessagesCount >= 2) { + await this.say("error", "MODEL_NO_ASSISTANT_MESSAGES") + } + // IMPORTANT: For native tool protocol, we already added the user message to // apiConversationHistory at line 1876. Since the assistant failed to respond, // we need to remove that message before retrying to avoid having two consecutive diff --git a/src/core/task/__tests__/grace-retry-errors.spec.ts b/src/core/task/__tests__/grace-retry-errors.spec.ts new file mode 100644 index 00000000000..5ea0e1ddb36 --- /dev/null +++ b/src/core/task/__tests__/grace-retry-errors.spec.ts @@ -0,0 +1,443 @@ +// npx vitest core/task/__tests__/grace-retry-errors.spec.ts + +import * as os from "os" +import * as path from "path" +import * as vscode from "vscode" + +import type { GlobalState, ProviderSettings } from "@roo-code/types" +import { TelemetryService } from "@roo-code/telemetry" + +import { Task } from "../Task" +import { ClineProvider } from "../../webview/ClineProvider" +import { ContextProxy } from "../../config/ContextProxy" + +// Mock @roo-code/core +vi.mock("@roo-code/core", () => ({ + customToolRegistry: { + getTools: vi.fn().mockReturnValue([]), + hasTool: vi.fn().mockReturnValue(false), + getTool: vi.fn().mockReturnValue(undefined), + }, +})) + +// Mock delay before any imports that might use it +vi.mock("delay", () => ({ + __esModule: true, + default: vi.fn().mockResolvedValue(undefined), +})) + +vi.mock("execa", () => ({ + execa: vi.fn(), +})) + +vi.mock("fs/promises", async (importOriginal) => { + const actual = (await importOriginal()) as Record + const mockFunctions = { + mkdir: vi.fn().mockResolvedValue(undefined), + writeFile: vi.fn().mockResolvedValue(undefined), + readFile: vi.fn().mockImplementation(() => Promise.resolve("[]")), + unlink: vi.fn().mockResolvedValue(undefined), + rmdir: vi.fn().mockResolvedValue(undefined), + } + + return { + ...actual, + ...mockFunctions, + default: mockFunctions, + } +}) + +vi.mock("p-wait-for", () => ({ + default: vi.fn().mockImplementation(async () => Promise.resolve()), +})) + +vi.mock("vscode", () => { + const mockDisposable = { dispose: vi.fn() } + const mockEventEmitter = { event: vi.fn(), fire: vi.fn() } + const mockTextDocument = { uri: { fsPath: "/mock/workspace/path/file.ts" } } + const mockTextEditor = { document: mockTextDocument } + const mockTab = { input: { uri: { fsPath: "/mock/workspace/path/file.ts" } } } + const mockTabGroup = { tabs: [mockTab] } + + return { + TabInputTextDiff: vi.fn(), + CodeActionKind: { + QuickFix: { value: "quickfix" }, + RefactorRewrite: { value: "refactor.rewrite" }, + }, + window: { + createTextEditorDecorationType: vi.fn().mockReturnValue({ + dispose: vi.fn(), + }), + visibleTextEditors: [mockTextEditor], + tabGroups: { + all: [mockTabGroup], + close: vi.fn(), + onDidChangeTabs: vi.fn(() => ({ dispose: vi.fn() })), + }, + showErrorMessage: vi.fn(), + }, + workspace: { + workspaceFolders: [ + { + uri: { fsPath: "/mock/workspace/path" }, + name: "mock-workspace", + index: 0, + }, + ], + createFileSystemWatcher: vi.fn(() => ({ + onDidCreate: vi.fn(() => mockDisposable), + onDidDelete: vi.fn(() => mockDisposable), + onDidChange: vi.fn(() => mockDisposable), + dispose: vi.fn(), + })), + fs: { + stat: vi.fn().mockResolvedValue({ type: 1 }), + }, + onDidSaveTextDocument: vi.fn(() => mockDisposable), + getConfiguration: vi.fn(() => ({ get: (key: string, defaultValue: any) => defaultValue })), + }, + env: { + uriScheme: "vscode", + language: "en", + }, + EventEmitter: vi.fn().mockImplementation(() => mockEventEmitter), + Disposable: { + from: vi.fn(), + }, + TabInputText: vi.fn(), + } +}) + +vi.mock("../../mentions", () => ({ + parseMentions: vi.fn().mockImplementation((text) => { + return Promise.resolve(`processed: ${text}`) + }), + openMention: vi.fn(), + getLatestTerminalOutput: vi.fn(), +})) + +vi.mock("../../../integrations/misc/extract-text", () => ({ + extractTextFromFile: vi.fn().mockResolvedValue("Mock file content"), +})) + +vi.mock("../../environment/getEnvironmentDetails", () => ({ + getEnvironmentDetails: vi.fn().mockResolvedValue(""), +})) + +vi.mock("../../ignore/RooIgnoreController") + +vi.mock("../../../utils/storage", () => ({ + getTaskDirectoryPath: vi + .fn() + .mockImplementation((globalStoragePath, taskId) => Promise.resolve(`${globalStoragePath}/tasks/${taskId}`)), + getSettingsDirectoryPath: vi + .fn() + .mockImplementation((globalStoragePath) => Promise.resolve(`${globalStoragePath}/settings`)), +})) + +vi.mock("../../../utils/fs", () => ({ + fileExistsAtPath: vi.fn().mockImplementation(() => false), +})) + +describe("Grace Retry Error Handling", () => { + let mockProvider: any + let mockApiConfig: ProviderSettings + let mockOutputChannel: any + let mockExtensionContext: vscode.ExtensionContext + + beforeEach(() => { + if (!TelemetryService.hasInstance()) { + TelemetryService.createInstance([]) + } + + const storageUri = { + fsPath: path.join(os.tmpdir(), "test-storage"), + } + + mockExtensionContext = { + globalState: { + get: vi.fn().mockImplementation((_key: keyof GlobalState) => undefined), + update: vi.fn().mockImplementation((_key, _value) => Promise.resolve()), + keys: vi.fn().mockReturnValue([]), + }, + globalStorageUri: storageUri, + workspaceState: { + get: vi.fn().mockImplementation((_key) => undefined), + update: vi.fn().mockImplementation((_key, _value) => Promise.resolve()), + keys: vi.fn().mockReturnValue([]), + }, + secrets: { + get: vi.fn().mockImplementation((_key) => Promise.resolve(undefined)), + store: vi.fn().mockImplementation((_key, _value) => Promise.resolve()), + delete: vi.fn().mockImplementation((_key) => Promise.resolve()), + }, + extensionUri: { + fsPath: "/mock/extension/path", + }, + extension: { + packageJSON: { + version: "1.0.0", + }, + }, + } as unknown as vscode.ExtensionContext + + mockOutputChannel = { + appendLine: vi.fn(), + append: vi.fn(), + clear: vi.fn(), + show: vi.fn(), + hide: vi.fn(), + dispose: vi.fn(), + } + + mockProvider = new ClineProvider( + mockExtensionContext, + mockOutputChannel, + "sidebar", + new ContextProxy(mockExtensionContext), + ) as any + + mockApiConfig = { + apiProvider: "anthropic", + apiModelId: "claude-3-5-sonnet-20241022", + apiKey: "test-api-key", + } + + mockProvider.postMessageToWebview = vi.fn().mockResolvedValue(undefined) + mockProvider.postStateToWebview = vi.fn().mockResolvedValue(undefined) + mockProvider.getState = vi.fn().mockResolvedValue({}) + }) + + describe("consecutiveNoAssistantMessagesCount", () => { + it("should initialize to 0", () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + expect(task.consecutiveNoAssistantMessagesCount).toBe(0) + }) + + it("should reset to 0 when abortTask is called", async () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + // Manually set the counter to simulate consecutive failures + task.consecutiveNoAssistantMessagesCount = 5 + + // Mock dispose to prevent actual cleanup + vi.spyOn(task, "dispose").mockImplementation(() => {}) + + await task.abortTask() + + expect(task.consecutiveNoAssistantMessagesCount).toBe(0) + }) + + it("should reset consecutiveNoToolUseCount when abortTask is called", async () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + // Manually set both counters + task.consecutiveNoAssistantMessagesCount = 3 + task.consecutiveNoToolUseCount = 4 + + // Mock dispose to prevent actual cleanup + vi.spyOn(task, "dispose").mockImplementation(() => {}) + + await task.abortTask() + + // Both counters should be reset + expect(task.consecutiveNoAssistantMessagesCount).toBe(0) + expect(task.consecutiveNoToolUseCount).toBe(0) + }) + }) + + describe("consecutiveNoToolUseCount", () => { + it("should initialize to 0", () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + expect(task.consecutiveNoToolUseCount).toBe(0) + }) + }) + + describe("Grace Retry Pattern", () => { + it("should not show error on first failure (grace retry)", async () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + const saySpy = vi.spyOn(task, "say").mockResolvedValue(undefined) + + // Simulate first empty response - should NOT show error + task.consecutiveNoAssistantMessagesCount = 0 + task.consecutiveNoAssistantMessagesCount++ + expect(task.consecutiveNoAssistantMessagesCount).toBe(1) + + // First failure: grace retry (silent) + if (task.consecutiveNoAssistantMessagesCount >= 2) { + await task.say("error", "MODEL_NO_ASSISTANT_MESSAGES") + } + + // Verify error was NOT called (grace retry on first failure) + expect(saySpy).not.toHaveBeenCalledWith("error", "MODEL_NO_ASSISTANT_MESSAGES") + }) + + it("should show error after 2 consecutive failures", async () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + const saySpy = vi.spyOn(task, "say").mockResolvedValue(undefined) + + // Simulate second consecutive empty response + task.consecutiveNoAssistantMessagesCount = 1 + task.consecutiveNoAssistantMessagesCount++ + expect(task.consecutiveNoAssistantMessagesCount).toBe(2) + + // Second failure: should show error + if (task.consecutiveNoAssistantMessagesCount >= 2) { + await task.say("error", "MODEL_NO_ASSISTANT_MESSAGES") + } + + // Verify error was called (after 2 consecutive failures) + expect(saySpy).toHaveBeenCalledWith("error", "MODEL_NO_ASSISTANT_MESSAGES") + }) + + it("should show error on third consecutive failure", async () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + const saySpy = vi.spyOn(task, "say").mockResolvedValue(undefined) + + // Simulate third consecutive empty response + task.consecutiveNoAssistantMessagesCount = 2 + task.consecutiveNoAssistantMessagesCount++ + expect(task.consecutiveNoAssistantMessagesCount).toBe(3) + + // Third failure: should also show error + if (task.consecutiveNoAssistantMessagesCount >= 2) { + await task.say("error", "MODEL_NO_ASSISTANT_MESSAGES") + } + + // Verify error was called + expect(saySpy).toHaveBeenCalledWith("error", "MODEL_NO_ASSISTANT_MESSAGES") + }) + }) + + describe("Counter Reset on Success", () => { + it("should be able to simulate counter reset when valid content is received", () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + // Simulate some consecutive failures + task.consecutiveNoAssistantMessagesCount = 3 + + // Simulate receiving valid content + const hasTextContent = true + const hasToolUses = false + + if (hasTextContent || hasToolUses) { + task.consecutiveNoAssistantMessagesCount = 0 + } + + expect(task.consecutiveNoAssistantMessagesCount).toBe(0) + }) + + it("should reset counter when tool uses are present", () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + // Simulate some consecutive failures + task.consecutiveNoAssistantMessagesCount = 2 + + // Simulate receiving tool uses + const hasTextContent = false + const hasToolUses = true + + if (hasTextContent || hasToolUses) { + task.consecutiveNoAssistantMessagesCount = 0 + } + + expect(task.consecutiveNoAssistantMessagesCount).toBe(0) + }) + }) + + describe("Error Marker", () => { + it("should use MODEL_NO_ASSISTANT_MESSAGES marker for error display", async () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + const saySpy = vi.spyOn(task, "say").mockResolvedValue(undefined) + + // Simulate the error condition (2 consecutive failures) + task.consecutiveNoAssistantMessagesCount = 2 + + if (task.consecutiveNoAssistantMessagesCount >= 2) { + await task.say("error", "MODEL_NO_ASSISTANT_MESSAGES") + } + + // Verify the exact marker is used + expect(saySpy).toHaveBeenCalledWith("error", "MODEL_NO_ASSISTANT_MESSAGES") + }) + }) + + describe("Parallel with noToolsUsed error handling", () => { + it("should have separate counters for noToolsUsed and noAssistantMessages", () => { + const task = new Task({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "test task", + startTask: false, + }) + + // Both counters should start at 0 + expect(task.consecutiveNoToolUseCount).toBe(0) + expect(task.consecutiveNoAssistantMessagesCount).toBe(0) + + // Incrementing one should not affect the other + task.consecutiveNoToolUseCount = 3 + expect(task.consecutiveNoAssistantMessagesCount).toBe(0) + + task.consecutiveNoAssistantMessagesCount = 2 + expect(task.consecutiveNoToolUseCount).toBe(3) + }) + }) +}) diff --git a/webview-ui/src/components/chat/ChatRow.tsx b/webview-ui/src/components/chat/ChatRow.tsx index e6fd26a3801..fee93f68a6f 100644 --- a/webview-ui/src/components/chat/ChatRow.tsx +++ b/webview-ui/src/components/chat/ChatRow.tsx @@ -1261,6 +1261,7 @@ export const ChatRowContent = ({ case "error": // Check if this is a model response error based on marker strings from backend const isNoToolsUsedError = message.text === "MODEL_NO_TOOLS_USED" + const isNoAssistantMessagesError = message.text === "MODEL_NO_ASSISTANT_MESSAGES" if (isNoToolsUsedError) { return ( @@ -1273,6 +1274,17 @@ export const ChatRowContent = ({ ) } + if (isNoAssistantMessagesError) { + return ( + + ) + } + // Fallback for generic errors return case "completion_result": diff --git a/webview-ui/src/i18n/locales/ca/chat.json b/webview-ui/src/i18n/locales/ca/chat.json index 73df09a299a..c6250279275 100644 --- a/webview-ui/src/i18n/locales/ca/chat.json +++ b/webview-ui/src/i18n/locales/ca/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "Resposta del model incompleta", "modelResponseErrors": { "noToolsUsed": "El model no ha utilitzat cap eina en la seva resposta. Això sol passar quan el model només proporciona text/raonament sense cridar les eines necessàries per completar la tasca.", - "noToolsUsedDetails": "El model ha proporcionat text/raonament però no ha cridat cap de les eines necessàries. Això sol indicar que el model ha entès malament la tasca o té dificultats per determinar quina eina utilitzar. El model ha estat sol·licitat automàticament per tornar-ho a provar amb l'ús adequat de les eines." + "noToolsUsedDetails": "El model ha proporcionat text/raonament però no ha cridat cap de les eines necessàries. Això sol indicar que el model ha entès malament la tasca o té dificultats per determinar quina eina utilitzar. El model ha estat sol·licitat automàticament per tornar-ho a provar amb l'ús adequat de les eines.", + "noAssistantMessages": "El model no ha proporcionat cap contingut de resposta. Això pot indicar un problema amb l'API o la sortida del model.", + "noAssistantMessagesDetails": "El model de llenguatge ha retornat una resposta buida sense text ni crides a eines. Això pot passar a causa de problemes d'API, limitació de velocitat o problemes específics del model. El model ha estat sol·licitat automàticament per tornar-ho a provar." }, "errorDetails": { "link": "Details", diff --git a/webview-ui/src/i18n/locales/de/chat.json b/webview-ui/src/i18n/locales/de/chat.json index 759d4dba912..934c941cad5 100644 --- a/webview-ui/src/i18n/locales/de/chat.json +++ b/webview-ui/src/i18n/locales/de/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "Modellantwort unvollständig", "modelResponseErrors": { "noToolsUsed": "Das Modell hat in seiner Antwort keine Tools verwendet. Dies passiert normalerweise, wenn das Modell nur Text/Überlegungen liefert, ohne die erforderlichen Tools aufzurufen, um die Aufgabe zu erledigen.", - "noToolsUsedDetails": "Das Modell hat Text/Überlegungen geliefert, aber keine der erforderlichen Tools aufgerufen. Dies deutet normalerweise darauf hin, dass das Modell die Aufgabe missverstanden hat oder Schwierigkeiten hat zu bestimmen, welches Tool verwendet werden soll. Das Modell wurde automatisch aufgefordert, es erneut mit der richtigen Tool-Verwendung zu versuchen." + "noToolsUsedDetails": "Das Modell hat Text/Überlegungen geliefert, aber keine der erforderlichen Tools aufgerufen. Dies deutet normalerweise darauf hin, dass das Modell die Aufgabe missverstanden hat oder Schwierigkeiten hat zu bestimmen, welches Tool verwendet werden soll. Das Modell wurde automatisch aufgefordert, es erneut mit der richtigen Tool-Verwendung zu versuchen.", + "noAssistantMessages": "Das Modell hat keinen Antwortinhalt geliefert. Dies kann auf ein Problem mit der API oder der Modellausgabe hindeuten.", + "noAssistantMessagesDetails": "Das Sprachmodell hat eine leere Antwort ohne Text oder Tool-Aufrufe zurückgegeben. Dies kann aufgrund von API-Problemen, Ratenbegrenzung oder modellspezifischen Problemen passieren. Das Modell wurde automatisch aufgefordert, es erneut zu versuchen." }, "errorDetails": { "link": "Details", diff --git a/webview-ui/src/i18n/locales/en/chat.json b/webview-ui/src/i18n/locales/en/chat.json index 4a4d0cf3e8b..021944a317d 100644 --- a/webview-ui/src/i18n/locales/en/chat.json +++ b/webview-ui/src/i18n/locales/en/chat.json @@ -288,7 +288,9 @@ "modelResponseIncomplete": "Model Response Incomplete", "modelResponseErrors": { "noToolsUsed": "The model failed to use any tools in its response. This typically happens when the model provides only text/reasoning without calling the required tools to complete the task.", - "noToolsUsedDetails": "The model provided text/reasoning but did not call any of the required tools. This usually indicates the model misunderstood the task or is having difficulty determining which tool to use. The model has been automatically prompted to retry with proper tool usage." + "noToolsUsedDetails": "The model provided text/reasoning but did not call any of the required tools. This usually indicates the model misunderstood the task or is having difficulty determining which tool to use. The model has been automatically prompted to retry with proper tool usage.", + "noAssistantMessages": "The model did not provide any response content. This may indicate an issue with the API or the model's output.", + "noAssistantMessagesDetails": "The language model returned an empty response without any text or tool calls. This can happen due to API issues, rate limiting, or model-specific problems. The model has been automatically prompted to retry." }, "errorDetails": { "link": "Details", diff --git a/webview-ui/src/i18n/locales/es/chat.json b/webview-ui/src/i18n/locales/es/chat.json index eede12a4416..61fdf458643 100644 --- a/webview-ui/src/i18n/locales/es/chat.json +++ b/webview-ui/src/i18n/locales/es/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "Respuesta del modelo incompleta", "modelResponseErrors": { "noToolsUsed": "El modelo no utilizó ninguna herramienta en su respuesta. Esto suele ocurrir cuando el modelo solo proporciona texto/razonamiento sin llamar a las herramientas necesarias para completar la tarea.", - "noToolsUsedDetails": "El modelo proporcionó texto/razonamiento pero no llamó a ninguna de las herramientas necesarias. Esto generalmente indica que el modelo malinterpretó la tarea o tiene dificultades para determinar qué herramienta usar. El modelo ha sido solicitado automáticamente para reintentar con el uso adecuado de herramientas." + "noToolsUsedDetails": "El modelo proporcionó texto/razonamiento pero no llamó a ninguna de las herramientas necesarias. Esto generalmente indica que el modelo malinterpretó la tarea o tiene dificultades para determinar qué herramienta usar. El modelo ha sido solicitado automáticamente para reintentar con el uso adecuado de herramientas.", + "noAssistantMessages": "El modelo no proporcionó ningún contenido de respuesta. Esto puede indicar un problema con la API o la salida del modelo.", + "noAssistantMessagesDetails": "El modelo de lenguaje devolvió una respuesta vacía sin texto ni llamadas a herramientas. Esto puede ocurrir debido a problemas de API, limitación de velocidad o problemas específicos del modelo. El modelo ha sido solicitado automáticamente para reintentar." }, "errorDetails": { "link": "Detalles", diff --git a/webview-ui/src/i18n/locales/fr/chat.json b/webview-ui/src/i18n/locales/fr/chat.json index 99f2ddd226e..214d7165e07 100644 --- a/webview-ui/src/i18n/locales/fr/chat.json +++ b/webview-ui/src/i18n/locales/fr/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "Réponse du modèle incomplète", "modelResponseErrors": { "noToolsUsed": "Le modèle n'a utilisé aucun outil dans sa réponse. Cela se produit généralement lorsque le modèle fournit uniquement du texte/raisonnement sans appeler les outils nécessaires pour accomplir la tâche.", - "noToolsUsedDetails": "Le modèle a fourni du texte/raisonnement mais n'a appelé aucun des outils requis. Cela indique généralement que le modèle a mal compris la tâche ou a des difficultés à déterminer quel outil utiliser. Le modèle a été automatiquement invité à réessayer avec l'utilisation appropriée des outils." + "noToolsUsedDetails": "Le modèle a fourni du texte/raisonnement mais n'a appelé aucun des outils requis. Cela indique généralement que le modèle a mal compris la tâche ou a des difficultés à déterminer quel outil utiliser. Le modèle a été automatiquement invité à réessayer avec l'utilisation appropriée des outils.", + "noAssistantMessages": "Le modèle n'a fourni aucun contenu de réponse. Cela peut indiquer un problème avec l'API ou la sortie du modèle.", + "noAssistantMessagesDetails": "Le modèle de langage a renvoyé une réponse vide sans aucun texte ni appel d'outil. Cela peut se produire en raison de problèmes d'API, de limitation de débit ou de problèmes spécifiques au modèle. Le modèle a été automatiquement invité à réessayer." }, "errorDetails": { "link": "Détails", diff --git a/webview-ui/src/i18n/locales/hi/chat.json b/webview-ui/src/i18n/locales/hi/chat.json index 7e2c985ad7c..d0540bcb78d 100644 --- a/webview-ui/src/i18n/locales/hi/chat.json +++ b/webview-ui/src/i18n/locales/hi/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "मॉडल प्रतिक्रिया अपूर्ण", "modelResponseErrors": { "noToolsUsed": "मॉडल ने अपनी प्रतिक्रिया में कोई टूल का उपयोग नहीं किया। यह आमतौर पर तब होता है जब मॉडल केवल टेक्स्ट/तर्क प्रदान करता है बिना कार्य पूरा करने के लिए आवश्यक टूल को कॉल किए।", - "noToolsUsedDetails": "मॉडल ने टेक्स्ट/तर्क प्रदान किया लेकिन किसी भी आवश्यक टूल को कॉल नहीं किया। यह आमतौर पर संकेत देता है कि मॉडल ने कार्य को गलत समझा या किस टूल का उपयोग करना है यह निर्धारित करने में कठिनाई हो रही है। मॉडल को स्वचालित रूप से उचित टूल उपयोग के साथ पुनः प्रयास करने के लिए कहा गया है।" + "noToolsUsedDetails": "मॉडल ने टेक्स्ट/तर्क प्रदान किया लेकिन किसी भी आवश्यक टूल को कॉल नहीं किया। यह आमतौर पर संकेत देता है कि मॉडल ने कार्य को गलत समझा या किस टूल का उपयोग करना है यह निर्धारित करने में कठिनाई हो रही है। मॉडल को स्वचालित रूप से उचित टूल उपयोग के साथ पुनः प्रयास करने के लिए कहा गया है।", + "noAssistantMessages": "मॉडल ने कोई प्रतिक्रिया सामग्री प्रदान नहीं की। यह API या मॉडल के आउटपुट में समस्या का संकेत दे सकता है।", + "noAssistantMessagesDetails": "भाषा मॉडल ने बिना किसी टेक्स्ट या टूल कॉल के खाली प्रतिक्रिया लौटाई। यह API समस्याओं, दर सीमित करने, या मॉडल-विशिष्ट समस्याओं के कारण हो सकता है। मॉडल को स्वचालित रूप से पुनः प्रयास करने के लिए कहा गया है।" }, "errorDetails": { "link": "विवरण", diff --git a/webview-ui/src/i18n/locales/id/chat.json b/webview-ui/src/i18n/locales/id/chat.json index d7f8b33ae15..fb2f7e62753 100644 --- a/webview-ui/src/i18n/locales/id/chat.json +++ b/webview-ui/src/i18n/locales/id/chat.json @@ -293,7 +293,9 @@ "modelResponseIncomplete": "Respons Model Tidak Lengkap", "modelResponseErrors": { "noToolsUsed": "Model gagal menggunakan alat apa pun dalam responsnya. Ini biasanya terjadi ketika model hanya memberikan teks/penalaran tanpa memanggil alat yang diperlukan untuk menyelesaikan tugas.", - "noToolsUsedDetails": "Model memberikan teks/penalaran tetapi tidak memanggil alat yang diperlukan. Ini biasanya menunjukkan bahwa model salah memahami tugas atau mengalami kesulitan menentukan alat mana yang akan digunakan. Model telah secara otomatis diminta untuk mencoba lagi dengan penggunaan alat yang tepat." + "noToolsUsedDetails": "Model memberikan teks/penalaran tetapi tidak memanggil alat yang diperlukan. Ini biasanya menunjukkan bahwa model salah memahami tugas atau mengalami kesulitan menentukan alat mana yang akan digunakan. Model telah secara otomatis diminta untuk mencoba lagi dengan penggunaan alat yang tepat.", + "noAssistantMessages": "Model tidak memberikan konten respons apa pun. Ini mungkin menunjukkan masalah dengan API atau output model.", + "noAssistantMessagesDetails": "Model bahasa mengembalikan respons kosong tanpa teks atau panggilan alat apa pun. Ini dapat terjadi karena masalah API, pembatasan laju, atau masalah khusus model. Model telah secara otomatis diminta untuk mencoba lagi." }, "diffError": { "title": "Edit Tidak Berhasil" diff --git a/webview-ui/src/i18n/locales/it/chat.json b/webview-ui/src/i18n/locales/it/chat.json index 638d9765667..f7dba07a161 100644 --- a/webview-ui/src/i18n/locales/it/chat.json +++ b/webview-ui/src/i18n/locales/it/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "Risposta del modello incompleta", "modelResponseErrors": { "noToolsUsed": "Il modello non ha utilizzato alcuno strumento nella sua risposta. Questo accade tipicamente quando il modello fornisce solo testo/ragionamento senza chiamare gli strumenti necessari per completare l'attività.", - "noToolsUsedDetails": "Il modello ha fornito testo/ragionamento ma non ha chiamato nessuno degli strumenti richiesti. Questo di solito indica che il modello ha frainteso l'attività o ha difficoltà a determinare quale strumento utilizzare. Il modello è stato automaticamente sollecitato a riprovare con l'uso appropriato degli strumenti." + "noToolsUsedDetails": "Il modello ha fornito testo/ragionamento ma non ha chiamato nessuno degli strumenti richiesti. Questo di solito indica che il modello ha frainteso l'attività o ha difficoltà a determinare quale strumento utilizzare. Il modello è stato automaticamente sollecitato a riprovare con l'uso appropriato degli strumenti.", + "noAssistantMessages": "Il modello non ha fornito alcun contenuto di risposta. Questo potrebbe indicare un problema con l'API o l'output del modello.", + "noAssistantMessagesDetails": "Il modello linguistico ha restituito una risposta vuota senza testo o chiamate a strumenti. Questo può accadere a causa di problemi API, limitazione della velocità o problemi specifici del modello. Il modello è stato automaticamente sollecitato a riprovare." }, "errorDetails": { "link": "Dettagli", diff --git a/webview-ui/src/i18n/locales/ja/chat.json b/webview-ui/src/i18n/locales/ja/chat.json index 35eddef57be..71a81c54639 100644 --- a/webview-ui/src/i18n/locales/ja/chat.json +++ b/webview-ui/src/i18n/locales/ja/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "モデルの応答が不完全", "modelResponseErrors": { "noToolsUsed": "モデルは応答でツールを使用しませんでした。これは通常、モデルがタスクを完了するために必要なツールを呼び出さずに、テキスト/推論のみを提供する場合に発生します。", - "noToolsUsedDetails": "モデルはテキスト/推論を提供しましたが、必要なツールを呼び出しませんでした。これは通常、モデルがタスクを誤解したか、どのツールを使用するかを決定するのに苦労していることを示しています。モデルは適切なツールの使用で再試行するよう自動的に促されました。" + "noToolsUsedDetails": "モデルはテキスト/推論を提供しましたが、必要なツールを呼び出しませんでした。これは通常、モデルがタスクを誤解したか、どのツールを使用するかを決定するのに苦労していることを示しています。モデルは適切なツールの使用で再試行するよう自動的に促されました。", + "noAssistantMessages": "モデルは応答コンテンツを提供しませんでした。これはAPIまたはモデルの出力に問題がある可能性を示しています。", + "noAssistantMessagesDetails": "言語モデルはテキストやツール呼び出しのない空の応答を返しました。これはAPI問題、レート制限、またはモデル固有の問題により発生する可能性があります。モデルは自動的に再試行するよう促されました。" }, "errorDetails": { "link": "詳細", diff --git a/webview-ui/src/i18n/locales/ko/chat.json b/webview-ui/src/i18n/locales/ko/chat.json index 1b2f0973da6..6c92171e0da 100644 --- a/webview-ui/src/i18n/locales/ko/chat.json +++ b/webview-ui/src/i18n/locales/ko/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "모델 응답 불완전", "modelResponseErrors": { "noToolsUsed": "모델이 응답에서 도구를 사용하지 않았습니다. 이는 일반적으로 모델이 작업을 완료하는 데 필요한 도구를 호출하지 않고 텍스트/추론만 제공할 때 발생합니다.", - "noToolsUsedDetails": "모델이 텍스트/추론을 제공했지만 필요한 도구를 호출하지 않았습니다. 이는 일반적으로 모델이 작업을 잘못 이해했거나 어떤 도구를 사용할지 결정하는 데 어려움을 겪고 있음을 나타냅니다. 모델이 적절한 도구 사용으로 다시 시도하도록 자동으로 요청되었습니다." + "noToolsUsedDetails": "모델이 텍스트/추론을 제공했지만 필요한 도구를 호출하지 않았습니다. 이는 일반적으로 모델이 작업을 잘못 이해했거나 어떤 도구를 사용할지 결정하는 데 어려움을 겪고 있음을 나타냅니다. 모델이 적절한 도구 사용으로 다시 시도하도록 자동으로 요청되었습니다.", + "noAssistantMessages": "모델이 응답 내용을 제공하지 않았습니다. API 또는 모델 출력에 문제가 있을 수 있습니다.", + "noAssistantMessagesDetails": "언어 모델이 텍스트나 도구 호출 없이 빈 응답을 반환했습니다. API 문제, 속도 제한 또는 모델별 문제로 인해 발생할 수 있습니다. 모델이 자동으로 다시 시도하도록 요청되었습니다." }, "errorDetails": { "link": "자세히", diff --git a/webview-ui/src/i18n/locales/nl/chat.json b/webview-ui/src/i18n/locales/nl/chat.json index e3eab860e85..a830c35ab33 100644 --- a/webview-ui/src/i18n/locales/nl/chat.json +++ b/webview-ui/src/i18n/locales/nl/chat.json @@ -257,7 +257,9 @@ "modelResponseIncomplete": "Modelrespons onvolledig", "modelResponseErrors": { "noToolsUsed": "Het model heeft geen tools gebruikt in zijn reactie. Dit gebeurt meestal wanneer het model alleen tekst/redenering levert zonder de vereiste tools aan te roepen om de taak te voltooien.", - "noToolsUsedDetails": "Het model heeft tekst/redenering geleverd maar heeft geen van de vereiste tools aangeroepen. Dit geeft meestal aan dat het model de taak verkeerd heeft begrepen of moeite heeft om te bepalen welke tool te gebruiken. Het model is automatisch gevraagd om opnieuw te proberen met correct gebruik van tools." + "noToolsUsedDetails": "Het model heeft tekst/redenering geleverd maar heeft geen van de vereiste tools aangeroepen. Dit geeft meestal aan dat het model de taak verkeerd heeft begrepen of moeite heeft om te bepalen welke tool te gebruiken. Het model is automatisch gevraagd om opnieuw te proberen met correct gebruik van tools.", + "noAssistantMessages": "Het model heeft geen reactie-inhoud geleverd. Dit kan wijzen op een probleem met de API of de output van het model.", + "noAssistantMessagesDetails": "Het taalmodel heeft een lege reactie geretourneerd zonder tekst of tool-aanroepen. Dit kan gebeuren door API-problemen, snelheidslimieten of modelspecifieke problemen. Het model is automatisch gevraagd om opnieuw te proberen." }, "diffError": { "title": "Bewerking mislukt" diff --git a/webview-ui/src/i18n/locales/pl/chat.json b/webview-ui/src/i18n/locales/pl/chat.json index 4665d01cde4..773e6967a7c 100644 --- a/webview-ui/src/i18n/locales/pl/chat.json +++ b/webview-ui/src/i18n/locales/pl/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "Odpowiedź modelu niekompletna", "modelResponseErrors": { "noToolsUsed": "Model nie użył żadnych narzędzi w swojej odpowiedzi. Zwykle dzieje się tak, gdy model dostarcza tylko tekst/rozumowanie bez wywołania wymaganych narzędzi do wykonania zadania.", - "noToolsUsedDetails": "Model dostarczył tekst/rozumowanie, ale nie wywołał żadnego z wymaganych narzędzi. Zazwyczaj oznacza to, że model źle zrozumiał zadanie lub ma trudności z określeniem, którego narzędzia użyć. Model został automatycznie poproszony o ponowną próbę z odpowiednim użyciem narzędzi." + "noToolsUsedDetails": "Model dostarczył tekst/rozumowanie, ale nie wywołał żadnego z wymaganych narzędzi. Zazwyczaj oznacza to, że model źle zrozumiał zadanie lub ma trudności z określeniem, którego narzędzia użyć. Model został automatycznie poproszony o ponowną próbę z odpowiednim użyciem narzędzi.", + "noAssistantMessages": "Model nie dostarczył żadnej odpowiedzi. Może to wskazywać na problem z API lub wyjściem modelu.", + "noAssistantMessagesDetails": "Model językowy zwrócił pustą odpowiedź bez żadnego tekstu ani wywołań narzędzi. Może się to zdarzyć z powodu problemów z API, limitów szybkości lub problemów specyficznych dla modelu. Model został automatycznie poproszony o ponowną próbę." }, "errorDetails": { "link": "Details", diff --git a/webview-ui/src/i18n/locales/pt-BR/chat.json b/webview-ui/src/i18n/locales/pt-BR/chat.json index 30c51e72aeb..4b08add9529 100644 --- a/webview-ui/src/i18n/locales/pt-BR/chat.json +++ b/webview-ui/src/i18n/locales/pt-BR/chat.json @@ -261,7 +261,9 @@ "modelResponseIncomplete": "Resposta do modelo incompleta", "modelResponseErrors": { "noToolsUsed": "O modelo falhou em usar qualquer ferramenta em sua resposta. Isso geralmente acontece quando o modelo fornece apenas texto/raciocínio sem chamar as ferramentas necessárias para completar a tarefa.", - "noToolsUsedDetails": "O modelo forneceu texto/raciocínio, mas não chamou nenhuma das ferramentas necessárias. Isso geralmente indica que o modelo entendeu mal a tarefa ou está tendo dificuldade em determinar qual ferramenta usar. O modelo foi automaticamente solicitado a tentar novamente com o uso adequado de ferramentas." + "noToolsUsedDetails": "O modelo forneceu texto/raciocínio, mas não chamou nenhuma das ferramentas necessárias. Isso geralmente indica que o modelo entendeu mal a tarefa ou está tendo dificuldade em determinar qual ferramenta usar. O modelo foi automaticamente solicitado a tentar novamente com o uso adequado de ferramentas.", + "noAssistantMessages": "O modelo não forneceu nenhum conteúdo de resposta. Isso pode indicar um problema com a API ou a saída do modelo.", + "noAssistantMessagesDetails": "O modelo de linguagem retornou uma resposta vazia sem texto ou chamadas de ferramentas. Isso pode acontecer devido a problemas de API, limitação de taxa ou problemas específicos do modelo. O modelo foi automaticamente solicitado a tentar novamente." }, "errorDetails": { "link": "Details", diff --git a/webview-ui/src/i18n/locales/ru/chat.json b/webview-ui/src/i18n/locales/ru/chat.json index b3188fe8e53..84126a337c1 100644 --- a/webview-ui/src/i18n/locales/ru/chat.json +++ b/webview-ui/src/i18n/locales/ru/chat.json @@ -258,7 +258,9 @@ "modelResponseIncomplete": "Неполный ответ модели", "modelResponseErrors": { "noToolsUsed": "Модель не использовала никаких инструментов в своем ответе. Обычно это происходит, когда модель предоставляет только текст/рассуждения без вызова необходимых инструментов для выполнения задачи.", - "noToolsUsedDetails": "Модель предоставила текст/рассуждения, но не вызвала ни одного из необходимых инструментов. Обычно это указывает на то, что модель неправильно поняла задачу или испытывает трудности с определением того, какой инструмент использовать. Модели автоматически предложено повторить попытку с правильным использованием инструментов." + "noToolsUsedDetails": "Модель предоставила текст/рассуждения, но не вызвала ни одного из необходимых инструментов. Обычно это указывает на то, что модель неправильно поняла задачу или испытывает трудности с определением того, какой инструмент использовать. Модели автоматически предложено повторить попытку с правильным использованием инструментов.", + "noAssistantMessages": "Модель не предоставила никакого содержимого ответа. Это может указывать на проблему с API или выводом модели.", + "noAssistantMessagesDetails": "Языковая модель вернула пустой ответ без текста или вызовов инструментов. Это может произойти из-за проблем с API, ограничения скорости или проблем, специфичных для модели. Модели автоматически предложено повторить попытку." }, "diffError": { "title": "Не удалось выполнить редактирование" diff --git a/webview-ui/src/i18n/locales/tr/chat.json b/webview-ui/src/i18n/locales/tr/chat.json index 9a56b032fb9..29af2a2fe84 100644 --- a/webview-ui/src/i18n/locales/tr/chat.json +++ b/webview-ui/src/i18n/locales/tr/chat.json @@ -262,7 +262,9 @@ "modelResponseIncomplete": "Model yanıtı eksik", "modelResponseErrors": { "noToolsUsed": "Model yanıtında herhangi bir araç kullanamadı. Bu genellikle model, görevi tamamlamak için gerekli araçları çağırmadan yalnızca metin/akıl yürütme sağladığında olur.", - "noToolsUsedDetails": "Model metin/akıl yürütme sağladı ancak gerekli araçlardan hiçbirini çağırmadı. Bu genellikle modelin görevi yanlış anladığını veya hangi aracı kullanacağını belirlemekte zorlandığını gösterir. Model, uygun araç kullanımıyla yeniden denemesi için otomatik olarak istenmiştir." + "noToolsUsedDetails": "Model metin/akıl yürütme sağladı ancak gerekli araçlardan hiçbirini çağırmadı. Bu genellikle modelin görevi yanlış anladığını veya hangi aracı kullanacağını belirlemekte zorlandığını gösterir. Model, uygun araç kullanımıyla yeniden denemesi için otomatik olarak istenmiştir.", + "noAssistantMessages": "Model herhangi bir yanıt içeriği sağlamadı. Bu, API veya modelin çıktısıyla ilgili bir sorunu gösterebilir.", + "noAssistantMessagesDetails": "Dil modeli herhangi bir metin veya araç çağrısı olmadan boş bir yanıt döndürdü. Bu, API sorunları, hız sınırlaması veya modele özgü sorunlar nedeniyle olabilir. Model otomatik olarak yeniden denemeye yönlendirildi." }, "errorDetails": { "link": "Details", diff --git a/webview-ui/src/i18n/locales/vi/chat.json b/webview-ui/src/i18n/locales/vi/chat.json index be6a42addd1..dba5c1a946d 100644 --- a/webview-ui/src/i18n/locales/vi/chat.json +++ b/webview-ui/src/i18n/locales/vi/chat.json @@ -262,7 +262,9 @@ "modelResponseIncomplete": "Phản hồi của mô hình không đầy đủ", "modelResponseErrors": { "noToolsUsed": "Mô hình đã không sử dụng bất kỳ công cụ nào trong phản hồi của mình. Điều này thường xảy ra khi mô hình chỉ cung cấp văn bản/lý luận mà không gọi các công cụ cần thiết để hoàn thành tác vụ.", - "noToolsUsedDetails": "Mô hình đã cung cấp văn bản/lý luận nhưng không gọi bất kỳ công cụ bắt buộc nào. Điều này thường cho thấy mô hình đã hiểu sai tác vụ hoặc đang gặp khó khăn trong việc xác định công cụ nào sẽ sử dụng. Mô hình đã được tự động nhắc thử lại với việc sử dụng công cụ phù hợp." + "noToolsUsedDetails": "Mô hình đã cung cấp văn bản/lý luận nhưng không gọi bất kỳ công cụ bắt buộc nào. Điều này thường cho thấy mô hình đã hiểu sai tác vụ hoặc đang gặp khó khăn trong việc xác định công cụ nào sẽ sử dụng. Mô hình đã được tự động nhắc thử lại với việc sử dụng công cụ phù hợp.", + "noAssistantMessages": "Mô hình không cung cấp bất kỳ nội dung phản hồi nào. Điều này có thể cho thấy có vấn đề với API hoặc đầu ra của mô hình.", + "noAssistantMessagesDetails": "Mô hình ngôn ngữ đã trả về một phản hồi trống mà không có văn bản hoặc lệnh gọi công cụ nào. Điều này có thể xảy ra do vấn đề API, giới hạn tốc độ hoặc các vấn đề cụ thể của mô hình. Mô hình đã được tự động nhắc thử lại." }, "errorDetails": { "link": "Chi tiết", diff --git a/webview-ui/src/i18n/locales/zh-CN/chat.json b/webview-ui/src/i18n/locales/zh-CN/chat.json index abaee47dcb8..a33efb42a60 100644 --- a/webview-ui/src/i18n/locales/zh-CN/chat.json +++ b/webview-ui/src/i18n/locales/zh-CN/chat.json @@ -262,7 +262,9 @@ "modelResponseIncomplete": "模型响应不完整", "modelResponseErrors": { "noToolsUsed": "模型在响应中未使用任何工具。这通常发生在模型仅提供文本/推理而未调用完成任务所需的工具时。", - "noToolsUsedDetails": "模型提供了文本/推理,但未调用任何必需的工具。这通常表明模型误解了任务,或在确定使用哪个工具时遇到困难。系统已自动提示模型使用正确的工具重试。" + "noToolsUsedDetails": "模型提供了文本/推理,但未调用任何必需的工具。这通常表明模型误解了任务,或在确定使用哪个工具时遇到困难。系统已自动提示模型使用正确的工具重试。", + "noAssistantMessages": "模型未提供任何响应内容。这可能表示 API 或模型输出存在问题。", + "noAssistantMessagesDetails": "语言模型返回了一个没有任何文本或工具调用的空响应。这可能是由于 API 问题、速率限制或模型特定问题所导致。系统已自动提示模型重试。" }, "errorDetails": { "link": "详情", diff --git a/webview-ui/src/i18n/locales/zh-TW/chat.json b/webview-ui/src/i18n/locales/zh-TW/chat.json index 6a95f0a0ac0..295e25c81af 100644 --- a/webview-ui/src/i18n/locales/zh-TW/chat.json +++ b/webview-ui/src/i18n/locales/zh-TW/chat.json @@ -291,7 +291,9 @@ "modelResponseIncomplete": "模型回應不完整", "modelResponseErrors": { "noToolsUsed": "模型在回應中未使用任何工具。這通常發生在模型僅提供文字/推理而未呼叫完成工作所需的工具時。", - "noToolsUsedDetails": "模型提供了文字/推理,但未呼叫任何必需的工具。這通常表示模型誤解了工作,或在確定使用哪個工具時遇到困難。系統已自動提示模型使用正確的工具重試。" + "noToolsUsedDetails": "模型提供了文字/推理,但未呼叫任何必需的工具。這通常表示模型誤解了工作,或在確定使用哪個工具時遇到困難。系統已自動提示模型使用正確的工具重試。", + "noAssistantMessages": "模型未提供任何回應內容。這可能表示 API 或模型輸出存在問題。", + "noAssistantMessagesDetails": "語言模型回傳了一個沒有任何文字或工具呼叫的空回應。這可能是由於 API 問題、速率限制或模型特定問題所導致。系統已自動提示模型重試。" }, "diffError": { "title": "編輯失敗"