diff --git a/core/main_terminal_parts/tools_definition/file_tools.py b/core/main_terminal_parts/tools_definition/file_tools.py index 62ea7b81..a2664859 100644 --- a/core/main_terminal_parts/tools_definition/file_tools.py +++ b/core/main_terminal_parts/tools_definition/file_tools.py @@ -247,7 +247,7 @@ class ToolsDefinitionFileToolsMixin: "properties": { "old_string": { "type": "string", - "description": "要替换的文本(需与文件内容精确匹配,保留缩进;建议提供至少3行提升定位稳定性。需要批量替换的场景可以单行或不足一行)" + "description": "要替换的文本(需与文件内容精确匹配,保留缩进;必须提供至少3行内容,包含目标行及其前后上下文,不足3行将被拒绝执行)" }, "new_string": { "type": "string", diff --git a/modules/file_manager/replace_mixin.py b/modules/file_manager/replace_mixin.py index e59c070f..2d25b500 100644 --- a/modules/file_manager/replace_mixin.py +++ b/modules/file_manager/replace_mixin.py @@ -73,7 +73,12 @@ class ReplaceMixin: "error": tr("file_manager.replace_new_text_too_long"), "suggestion": "请将大内容分成多个小的替换操作" } - short_old_text_notice = bool(old_text and len(old_text.splitlines()) < 3) + if old_text and len(old_text.splitlines()) < 3: + return { + "success": False, + "error": tr("file_manager.replace_old_text_too_short"), + "suggestion": "请在 old_string 中包含目标行及其前后上下文(至少3行)后重试" + } # 检查是否包含要替换的内容 if old_text and old_text not in content: @@ -111,11 +116,6 @@ class ReplaceMixin: lines=line_text, count=count, )) - if short_old_text_notice: - message_parts.insert( - 0, - tr("file_manager.replace_short_old_notice") - ) if message_parts: result["message"] = ";".join(message_parts) print(f"{OUTPUT_FORMATS['file']} 替换了 {count} 处内容") @@ -144,7 +144,6 @@ class ReplaceMixin: failed_details: List[Dict[str, Any]] = [] total_replacements = 0 total_found_matches = 0 - short_old_text_indices: List[int] = [] for zero_based_index, item in enumerate(replacements): index = zero_based_index + 1 @@ -230,7 +229,13 @@ class ReplaceMixin: break if len(old_text.splitlines()) < 3: - short_old_text_indices.append(index) + detail.update({ + "status": "error", + "reason": "old_string 少于3行,请包含目标行及其前后上下文(至少3行)后重试" + }) + failed_details.append(detail.copy()) + details.append(detail) + break matched_lines = self._find_match_line_numbers(current_content, old_text) found_count = len(matched_lines) @@ -300,9 +305,6 @@ class ReplaceMixin: groups=len(replacements), replacements=total_replacements, )] - if short_old_text_indices: - indices_text = ",".join(str(item) for item in short_old_text_indices) - message_parts.append(tr("file_manager.replace_many_short_notice", indices=indices_text)) write_result["message"] = ";".join(message_parts) print(f"{OUTPUT_FORMATS['file']} 批量替换了 {total_replacements} 处内容") return write_result diff --git a/modules/i18n_messages/file_manager.py b/modules/i18n_messages/file_manager.py index 1d2cf15c..bb6e29db 100644 --- a/modules/i18n_messages/file_manager.py +++ b/modules/i18n_messages/file_manager.py @@ -258,16 +258,12 @@ MESSAGES = { "zh-CN": "发现{found}处,于{lines}行共替换{count}处", "en-US": "Found {found} matches; replaced {count} at lines {lines}", }, - "file_manager.replace_short_old_notice": { - "zh-CN": "提示:old_string 少于3行,已继续执行;需要批量替换的场景可以单行或不足一行", - "en-US": "Note: old_string is shorter than 3 lines; execution continued. For batch replacement, use single-line or shorter strings", + "file_manager.replace_old_text_too_short": { + "zh-CN": "old_string 少于3行:为确保精确匹配,请提供至少3行内容(包含目标行及其前后上下文)", + "en-US": "old_string has fewer than 3 lines: to ensure precise matching, provide at least 3 lines including the target line and its surrounding context", }, "file_manager.replace_many_summary": { "zh-CN": "共 {groups} 组替换,替换 {replacements} 处", "en-US": "{groups} groups processed; {replacements} replacements made", }, - "file_manager.replace_many_short_notice": { - "zh-CN": "提示:第 {indices} 组 old_string 少于3行,已继续执行", - "en-US": "Note: old_string in groups {indices} is shorter than 3 lines; execution continued", - }, } \ No newline at end of file