diff --git a/mateclaw-server/src/main/java/vip/mate/agent/graph/NodeStreamingChatHelper.java b/mateclaw-server/src/main/java/vip/mate/agent/graph/NodeStreamingChatHelper.java index a71a4676..4e80804c 100644 --- a/mateclaw-server/src/main/java/vip/mate/agent/graph/NodeStreamingChatHelper.java +++ b/mateclaw-server/src/main/java/vip/mate/agent/graph/NodeStreamingChatHelper.java @@ -431,7 +431,7 @@ public class NodeStreamingChatHelper { // Client error (400): 不重试(参数/格式错误重试也不会变) if (errorType == ErrorType.CLIENT_ERROR) { log.error("[{}] Client error (400), not retrying: {}", phase, error.getMessage()); - return buildErrorResultWithType("请求参数错误: " + extractUserFriendlyError(error), + return buildErrorResultWithType("Bad request: " + extractUserFriendlyError(error), conversationId, phase, errorType); } @@ -625,12 +625,12 @@ public class NodeStreamingChatHelper { String msg = error.getMessage(); if (msg == null) return error.getClass().getSimpleName(); // 对 Jackson 反序列化错误,提取关键信息 - if (msg.contains("engine_overloaded")) return "模型服务过载,请稍后重试"; - if (msg.contains("unsupported image format") || msg.contains("unsupported")) return "不支持的文件格式(如 SVG),请使用 PNG/JPG 等光栅图片"; - if (msg.contains("invalid_request_error") || msg.contains("400 Bad Request")) return "请求参数错误,请检查输入"; - if (msg.contains("rate_limit") || msg.contains("429")) return "请求频率过高,请稍后重试"; - if (msg.contains("timeout") || msg.contains("Timeout")) return "请求超时,请重试"; - if (msg.contains("502") || msg.contains("503") || msg.contains("504")) return "模型服务暂时不可用"; + if (msg.contains("engine_overloaded")) return "Model service overloaded, please retry later"; + if (msg.contains("unsupported image format") || msg.contains("unsupported")) return "Unsupported file format (e.g. SVG), use PNG/JPG instead"; + if (msg.contains("invalid_request_error") || msg.contains("400 Bad Request")) return "Bad request, please check input"; + if (msg.contains("rate_limit") || msg.contains("429")) return "Rate limit exceeded, please retry later"; + if (msg.contains("timeout") || msg.contains("Timeout")) return "Request timeout, please retry"; + if (msg.contains("502") || msg.contains("503") || msg.contains("504")) return "Model service temporarily unavailable"; // 截断过长的原始消息 return msg.length() > 100 ? msg.substring(0, 100) + "..." : msg; } diff --git a/mateclaw-server/src/main/java/vip/mate/agent/graph/executor/ToolExecutionExecutor.java b/mateclaw-server/src/main/java/vip/mate/agent/graph/executor/ToolExecutionExecutor.java index 5e47a74f..ae4b9999 100644 --- a/mateclaw-server/src/main/java/vip/mate/agent/graph/executor/ToolExecutionExecutor.java +++ b/mateclaw-server/src/main/java/vip/mate/agent/graph/executor/ToolExecutionExecutor.java @@ -230,9 +230,9 @@ public class ToolExecutionExecutor { ToolCallback callback = toolCallbackMap.get(toolName); if (callback == null) { log.warn("[ToolExecutor] Tool not found: {}", toolName); - events.add(GraphEventPublisher.toolComplete(toolName, "工具不存在: " + toolName, false)); + events.add(GraphEventPublisher.toolComplete(toolName, "Tool not found: " + toolName, false)); allResponses.add(new ToolResponseMessage.ToolResponse( - toolCall.id(), toolName, "工具不存在: " + toolName)); + toolCall.id(), toolName, "Tool not found: " + toolName)); continue; } @@ -270,8 +270,8 @@ public class ToolExecutionExecutor { ToolCallback callback = toolCallbackMap.get(toolName); if (callback == null) { log.warn("[ToolExecutor] Pre-approved tool not found: {}", toolName); - events.add(GraphEventPublisher.toolComplete(toolName, "工具不存在: " + toolName, false)); - return new ToolResponseMessage.ToolResponse(toolCall.id(), toolName, "工具不存在: " + toolName); + events.add(GraphEventPublisher.toolComplete(toolName, "Tool not found: " + toolName, false)); + return new ToolResponseMessage.ToolResponse(toolCall.id(), toolName, "Tool not found: " + toolName); } try { @@ -288,7 +288,7 @@ public class ToolExecutionExecutor { log.error("[ToolExecutor] Pre-approved tool {} failed: {}", toolName, e.getMessage()); events.add(GraphEventPublisher.toolComplete(toolName, e.getMessage(), false)); return new ToolResponseMessage.ToolResponse( - toolCall.id(), toolName, "工具执行失败: " + e.getMessage()); + toolCall.id(), toolName, "Tool execution failed: " + e.getMessage()); } } @@ -505,7 +505,7 @@ public class ToolExecutionExecutor { } private String normalizeToolExecutionError(Exception e) { - String message = e != null && e.getMessage() != null ? e.getMessage() : "未知错误"; + String message = e != null && e.getMessage() != null ? e.getMessage() : "Unknown error"; String lower = message.toLowerCase(Locale.ROOT); if (lower.contains("conversion from json") @@ -513,16 +513,16 @@ public class ToolExecutionExecutor { || lower.contains("unexpected character escape sequence") || lower.contains("json parse error") || lower.contains("malformed json")) { - return "工具执行失败:模型生成的工具参数不是合法 JSON,通常表示单次 tool call 内容过长," + return "Tool execution failed: model generated invalid JSON for tool arguments. " + "或在字符串转义位置被截断。请改为分步骤写入,拆成多个文件,或缩小单次 write_file/edit_file 的内容后重试。"; } if (lower.contains("access denied") && lower.contains("path outside allowed directories")) { // 提取目标路径和允许路径 - return "工具执行失败:目标路径不在允许的工作目录范围内。请将文件操作改为用户主目录下的路径(如 ~/Documents/ 或 ~/Desktop/)。"; + return "Tool execution failed: target path is outside the allowed workspace directory."; } - return "工具执行失败: " + message; + return "Tool execution failed: " + message; } /** diff --git a/mateclaw-server/src/main/java/vip/mate/agent/graph/node/FinalAnswerNode.java b/mateclaw-server/src/main/java/vip/mate/agent/graph/node/FinalAnswerNode.java index 7c09fbf3..0f6438c9 100644 --- a/mateclaw-server/src/main/java/vip/mate/agent/graph/node/FinalAnswerNode.java +++ b/mateclaw-server/src/main/java/vip/mate/agent/graph/node/FinalAnswerNode.java @@ -95,7 +95,7 @@ public class FinalAnswerNode implements NodeAction { finishReason = FinishReason.SUMMARIZED; log.warn("[FinalAnswerNode] No finalAnswer or draft found, falling back to summarizedContext"); } else { - finalAnswer = "未能生成回答,请重试。"; + finalAnswer = "Failed to generate a response, please retry."; finalThinking = ""; finishReason = FinishReason.ERROR_FALLBACK; log.error("[FinalAnswerNode] No answer source available, returning fallback"); diff --git a/mateclaw-server/src/main/java/vip/mate/tool/guard/DefaultToolGuard.java b/mateclaw-server/src/main/java/vip/mate/tool/guard/DefaultToolGuard.java index db3971f5..b34e8d9c 100644 --- a/mateclaw-server/src/main/java/vip/mate/tool/guard/DefaultToolGuard.java +++ b/mateclaw-server/src/main/java/vip/mate/tool/guard/DefaultToolGuard.java @@ -85,13 +85,13 @@ public class DefaultToolGuard implements ToolGuard { // Shell 工具即使未命中任何模式,也需要审批(任何本地命令执行都是敏感操作) if (isShellTool) { log.info("[ToolGuard] NEEDS_APPROVAL (shell tool default): tool={}", toolName); - return ToolGuardResult.needsApproval("本地命令执行需要用户确认", "shell_tool_default"); + return ToolGuardResult.needsApproval("Shell command execution requires user approval", "shell_tool_default"); } // 文件写入/编辑工具需要审批 if (toolName != null && FILE_WRITE_TOOL_NAMES.contains(toolName)) { log.info("[ToolGuard] NEEDS_APPROVAL (file write tool): tool={}", toolName); - return ToolGuardResult.needsApproval("文件写入/编辑操作需要用户确认", "file_write_tool_default"); + return ToolGuardResult.needsApproval("File write/edit operation requires user approval", "file_write_tool_default"); } return ToolGuardResult.allow(); diff --git a/mateclaw-ui/src/components/chat/CompressionSummary.vue b/mateclaw-ui/src/components/chat/CompressionSummary.vue index 02a33c4c..cafc420e 100644 --- a/mateclaw-ui/src/components/chat/CompressionSummary.vue +++ b/mateclaw-ui/src/components/chat/CompressionSummary.vue @@ -1,8 +1,11 @@