auto-coder 0.1.235__py3-none-any.whl → 0.1.237__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of auto-coder might be problematic. Click here for more details.

@@ -2,6 +2,19 @@ import locale
2
2
 
3
3
  MESSAGES = {
4
4
  "en": {
5
+ "mcp_remove_error": "Error removing MCP server: {error}",
6
+ "mcp_remove_success": "Successfully removed MCP server: {result}",
7
+ "mcp_list_running_error": "Error listing running MCP servers: {error}",
8
+ "mcp_list_running_title": "Running MCP servers:",
9
+ "mcp_list_builtin_error": "Error listing builtin MCP servers: {error}",
10
+ "mcp_list_builtin_title": "Available builtin MCP servers:",
11
+ "mcp_refresh_error": "Error refreshing MCP servers: {error}",
12
+ "mcp_refresh_success": "Successfully refreshed MCP servers",
13
+ "mcp_install_error": "Error installing MCP server: {error}",
14
+ "mcp_install_success": "Successfully installed MCP server: {result}",
15
+ "mcp_query_empty": "Please enter your query.",
16
+ "mcp_error_title": "Error",
17
+ "mcp_response_title": "MCP Response",
5
18
  "initializing": "🚀 Initializing system...",
6
19
  "not_initialized": "The current directory is not initialized as an auto-coder project.",
7
20
  "init_prompt": "Do you want to initialize the project now? (y/n): ",
@@ -68,21 +81,47 @@ MESSAGES = {
68
81
  "commit_desc": "Auto generate yaml file and commit changes based on user's manual changes",
69
82
  "models_desc": "Manage model configurations, only available in lite mode",
70
83
  "models_usage": "Usage: /models /list|/add|/add_model|/remove ...",
71
- "models_added": "Added/Updated model '{name}' successfully.",
72
- "models_add_failed": "Failed to add model '{name}'. Model not found in defaults.",
84
+ "models_added": "Added/Updated model '{{name}}' successfully.",
85
+ "models_add_failed": "Failed to add model '{{name}}'. Model not found in defaults.",
73
86
  "models_add_usage": "Usage: /models /add <name> <api_key> or\n/models /add <name> <model_type> <model_name> <base_url> <api_key_path> [description]",
74
87
  "models_add_model_params": "Please provide parameters in key=value format",
75
88
  "models_add_model_name_required": "'name' parameter is required",
76
- "models_add_model_exists": "Model '{name}' already exists.",
77
- "models_add_model_success": "Successfully added custom model: {name}",
78
- "models_add_model_remove": "Model '{name}' not found.",
79
- "models_add_model_removed": "Removed model: {name}",
80
- "models_unknown_subcmd": "Unknown subcommand: {subcmd}",
89
+ "models_add_model_exists": "Model '{{name}}' already exists.",
90
+ "models_add_model_success": "Successfully added custom model: {{name}}",
91
+ "models_add_model_remove": "Model '{{name}}' not found.",
92
+ "models_add_model_removed": "Removed model: {{name}}",
93
+ "models_unknown_subcmd": "Unknown subcommand: {{subcmd}}",
81
94
  "models_title": "All Models (内置 + models.json)",
82
95
  "models_no_models": "No models found.",
83
- "models_lite_only": "The /models command is only available in lite mode"
96
+ "models_lite_only": "The /models command is only available in lite mode",
97
+ "models_api_key_exists": "API key file exists: {{path}}",
98
+ "config_invalid_format": "Error: Invalid configuration format. Use 'key:value' or '/drop key'.",
99
+ "config_value_empty": "Error: Value cannot be empty. Use 'key:value'.",
100
+ "config_set_success": "Set {{key}} to {{value}}",
101
+ "config_delete_success": "Deleted configuration: {{key}}",
102
+ "config_not_found": "Configuration not found: {{key}}",
103
+ "add_files_matched": "All specified files are already in the current session or no matches found.",
104
+ "add_files_added_files": "Added Files",
105
+ "add_files_no_args": "Please provide arguments for the /add_files command.",
106
+ "remove_files_all": "Removed all files.",
107
+ "remove_files_removed": "Removed Files",
108
+ "remove_files_none": "No files were removed.",
109
+ "files_removed": "Files Removed"
84
110
  },
85
111
  "zh": {
112
+ "mcp_remove_error": "移除 MCP 服务器时出错:{error}",
113
+ "mcp_remove_success": "成功移除 MCP 服务器:{result}",
114
+ "mcp_list_running_error": "列出运行中的 MCP 服务器时出错:{error}",
115
+ "mcp_list_running_title": "正在运行的 MCP 服务器:",
116
+ "mcp_list_builtin_error": "列出内置 MCP 服务器时出错:{error}",
117
+ "mcp_list_builtin_title": "可用的内置 MCP 服务器:",
118
+ "mcp_refresh_error": "刷新 MCP 服务器时出错:{error}",
119
+ "mcp_refresh_success": "成功刷新 MCP 服务器",
120
+ "mcp_install_error": "安装 MCP 服务器时出错:{error}",
121
+ "mcp_install_success": "成功安装 MCP 服务器:{result}",
122
+ "mcp_query_empty": "请输入您的查询。",
123
+ "mcp_error_title": "错误",
124
+ "mcp_response_title": "MCP 响应",
86
125
  "initializing": "🚀 正在初始化系统...",
87
126
  "not_initialized": "当前目录未初始化为auto-coder项目。",
88
127
  "init_prompt": "是否现在初始化项目?(y/n): ",
@@ -147,21 +186,34 @@ MESSAGES = {
147
186
  "exit_desc": "退出程序",
148
187
  "design_desc": "根据需求设计SVG图片",
149
188
  "commit_desc": "根据用户人工修改的代码自动生成yaml文件并提交更改",
150
- "models_desc": "管理模型配置,仅在lite模式下可用",
189
+ "models_desc": "管理模型配置,仅在lite模式下可用",
151
190
  "models_usage": "用法: /models /list|/add|/add_model|/remove ...",
152
- "models_added": "成功添加/更新模型 '{name}'。",
153
- "models_add_failed": "添加模型 '{name}' 失败。在默认模型中未找到该模型。",
191
+ "models_added": "成功添加/更新模型 '{{name}}'。",
192
+ "models_add_failed": "添加模型 '{{name}}' 失败。在默认模型中未找到该模型。",
154
193
  "models_add_usage": "用法: /models /add <name> <api_key> 或\n/models /add <name> <model_type> <model_name> <base_url> <api_key_path> [description]",
155
194
  "models_add_model_params": "请提供 key=value 格式的参数",
156
195
  "models_add_model_name_required": "缺少必需的 'name' 参数",
157
- "models_add_model_exists": "模型 '{name}' 已存在。",
158
- "models_add_model_success": "成功添加自定义模型: {name}",
159
- "models_add_model_remove": "找不到模型 '{name}'。",
160
- "models_add_model_removed": "已移除模型: {name}",
161
- "models_unknown_subcmd": "未知的子命令: {subcmd}",
196
+ "models_add_model_exists": "模型 '{{name}}' 已存在。",
197
+ "models_add_model_success": "成功添加自定义模型: {{name}}",
198
+ "models_add_model_remove": "找不到模型 '{{name}}'。",
199
+ "models_add_model_removed": "已移除模型: {{name}}",
200
+ "models_unknown_subcmd": "未知的子命令: {{subcmd}}",
162
201
  "models_title": "所有模型 (内置 + models.json)",
163
202
  "models_no_models": "未找到任何模型。",
164
- "models_lite_only": "/models 命令仅在 lite 模式下可用"
203
+ "models_lite_only": "/models 命令仅在 lite 模式下可用",
204
+ "models_api_key_exists": "API密钥文件存在: {{path}}",
205
+ "config_invalid_format": "错误:配置格式无效。请使用 'key:value' 或 '/drop key'。",
206
+ "config_value_empty": "错误:值不能为空。请使用 'key:value'。",
207
+ "config_set_success": "已设置 {{key}} 为 {{value}}",
208
+ "config_delete_success": "已删除配置:{{key}}",
209
+ "config_not_found": "未找到配置:{{key}}",
210
+ "add_files_matched": "所有指定的文件都已在当前会话中或未找到匹配项。",
211
+ "add_files_added_files": "已添加的文件",
212
+ "add_files_no_args": "请为 /add_files 命令提供参数。",
213
+ "remove_files_all": "已移除所有文件。",
214
+ "remove_files_removed": "已移除的文件",
215
+ "remove_files_none": "没有文件被移除。",
216
+ "files_removed": "移除的文件"
165
217
  }
166
218
  }
167
219
 
@@ -2,6 +2,7 @@ import locale
2
2
 
3
3
  MESSAGES = {
4
4
  "en": {
5
+ "memory_save_success": "✅ Saved to your memory",
5
6
  "index_file_too_large": "⚠️ File {{ file_path }} is too large ({{ file_size }} > {{ max_length }}), splitting into chunks...",
6
7
  "index_update_success": "✅ Successfully updated index for {{ file_path }} (md5: {{ md5 }}) in {{ duration }}s",
7
8
  "index_build_error": "❌ Error building index for {{ file_path }}: {{ error }}",
@@ -35,9 +36,32 @@ MESSAGES = {
35
36
  "Please use Web version model to get the answer.\n"
36
37
  "Or use /conf human_as_model:false to close this mode and get the answer in terminal directly."
37
38
  "Paste the answer to the input box below, use '/break' to exit, '/clear' to clear the screen, '/eof' to submit."
38
- )
39
+ ),
40
+ "code_generation_start": "Auto generate the code...",
41
+ "code_generation_complete": "Code generation completed in {{ duration }} seconds, input_tokens_count: {{ input_tokens }}, generated_tokens_count: {{ output_tokens }}",
42
+ "code_merge_start": "Auto merge the code...",
43
+ "code_execution_warning": "Content(send to model) is {{ content_length }} tokens (you may collect too much files), which is larger than the maximum input length {{ max_length }}",
44
+ "quick_filter_start": "Starting filter context(quick_filter)...",
45
+ "normal_filter_start": "Starting filter context(normal_filter)...",
46
+ "pylint_check_failed": "⚠️ Pylint check failed: {{ error_message }}",
47
+ "pylint_error": "❌ Error running pylint: {{ error_message }}",
48
+ "unmerged_blocks_warning": "⚠️ Found {{ num_blocks }} unmerged blocks, the changes will not be applied. Please review them manually then try again.",
49
+ "pylint_file_check_failed": "⚠️ Pylint check failed for {{ file_path }}. Changes not applied. Error: {{ error_message }}",
50
+ "merge_success": "✅ Merged changes in {{ num_files }} files {{ num_changes }}/{{ total_blocks }} blocks.",
51
+ "no_changes_made": "⚠️ No changes were made to any files.",
52
+ "files_merged": "✅ Merged {{ total }} files into the project.",
53
+ "merge_failed": "❌ Merge file {{ path }} failed: {{ error }}",
54
+ "files_merged_total": "✅ Merged {{ total }} files into the project.",
55
+ "ranking_skip": "Only 1 candidate, skip ranking",
56
+ "ranking_start": "Start ranking {{ count }} candidates",
57
+ "ranking_failed_request": "Ranking request failed: {{ error }}",
58
+ "ranking_all_failed": "All ranking requests failed",
59
+ "ranking_complete": "Ranking completed in {{ elapsed }}s, total voters: {{ total_tasks }}, best candidate index: {{ best_candidate }}, scores: {{ scores }}, input_tokens: {{ input_tokens }}, output_tokens: {{ output_tokens }}",
60
+ "ranking_process_failed": "Ranking process failed: {{ error }}",
61
+ "ranking_failed": "Ranking failed in {{ elapsed }}s, using original order"
39
62
  },
40
63
  "zh": {
64
+ "memory_save_success": "✅ 已保存到您的记忆中",
41
65
  "index_file_too_large": "⚠️ 文件 {{ file_path }} 过大 ({{ file_size }} > {{ max_length }}), 正在分块处理...",
42
66
  "index_update_success": "✅ 成功更新 {{ file_path }} 的索引 (md5: {{ md5 }}), 耗时 {{ duration }} 秒",
43
67
  "index_build_error": "❌ 构建 {{ file_path }} 索引时出错: {{ error }}",
@@ -61,12 +85,10 @@ MESSAGES = {
61
85
  "系统正在等待您的输入。完成后,在新行输入'EOF'提交。\n"
62
86
  "使用'/break'退出此模式。如果复制粘贴有问题,使用'/clear'清理并重新粘贴。"
63
87
  ),
64
-
65
88
  "phase1_processing_sources": "阶段 1: 正在处理 REST/RAG/Search 源...",
66
89
  "phase2_building_index": "阶段 2: 正在为所有文件构建索引...",
67
90
  "phase6_file_selection": "阶段 6: 正在处理文件选择和限制...",
68
91
  "phase7_preparing_output": "阶段 7: 正在准备最终输出...",
69
-
70
92
  "chat_human_as_model_instructions": (
71
93
  "\n============= Chat 处于 Human as Model 模式 =============\n"
72
94
  "问题已复制到剪贴板\n"
@@ -74,7 +96,36 @@ MESSAGES = {
74
96
  "或者使用 /conf human_as_model:false 关闭该模式直接在终端获得答案。"
75
97
  "将获得答案黏贴到下面的输入框,换行后,使用 '/break' 退出,'/clear' 清屏,'/eof' 提交。"
76
98
  ),
77
- }
99
+ "code_generation_start": "正在自动生成代码...",
100
+ "code_generation_complete": "代码生成完成,耗时 {{ duration }} 秒,输入token数: {{ input_tokens }}, 输出token数: {{ output_tokens }}",
101
+ "code_merge_start": "正在自动合并代码...",
102
+ "code_execution_warning": "发送给模型的内容长度为 {{ content_length }} tokens(您可能收集了太多文件),超过了最大输入长度 {{ max_length }}",
103
+ "quick_filter_start": "开始查找上下文(quick_filter)...",
104
+ "normal_filter_start": "开始查找上下文(normal_filter)...",
105
+ "pylint_check_failed": "⚠️ Pylint 检查失败: {{ error_message }}",
106
+ "pylint_error": "❌ 运行 Pylint 时出错: {{ error_message }}",
107
+ "unmerged_blocks_warning": "⚠️ 发现 {{ num_blocks }} 个未合并的代码块,更改将不会被应用。请手动检查后重试。",
108
+ "pylint_file_check_failed": "⚠️ {{ file_path }} 的 Pylint 检查失败。更改未应用。错误: {{ error_message }}",
109
+ "merge_success": "✅ 成功合并了 {{ num_files }} 个文件中的更改 {{ num_changes }}/{{ total_blocks }} 个代码块。",
110
+ "no_changes_made": "⚠️ 未对任何文件进行更改。",
111
+ "unmerged_blocks_title": "Unmerged Blocks",
112
+ "unmerged_file_path": "File: {file_path}",
113
+ "unmerged_search_block": "Search Block({similarity}):",
114
+ "unmerged_replace_block": "Replace Block:",
115
+ "unmerged_blocks_total": "Total unmerged blocks: {num_blocks}",
116
+ "git_init_required": "⚠️ auto_merge 仅适用于 git 仓库。\n\n请尝试在源目录中使用 git init:\n\n```shell\ncd {{ source_dir }}\ngit init .\n```\n\n然后再次运行 auto-coder。\n错误: {{ error }}",
117
+ "upsert_file": "✅ 更新文件: {{ file_path }}",
118
+ "files_merged": "✅ 成功合并了 {{ total }} 个文件到项目中。",
119
+ "merge_failed": "❌ 合并文件 {{ path }} 失败: {{ error }}",
120
+ "files_merged_total": "✅ 合并了 {{ total }} 个文件到项目中。",
121
+ "ranking_skip": "只有1个候选项,跳过排序",
122
+ "ranking_start": "开始对 {{ count }} 个候选项进行排序",
123
+ "ranking_failed_request": "排序请求失败: {{ error }}",
124
+ "ranking_all_failed": "所有排序请求都失败",
125
+ "ranking_complete": "排序完成,耗时 {{ elapsed }} 秒,总投票数: {{ total_tasks }},最佳候选索引: {{ best_candidate }},得分: {{ scores }},输入token数: {{ input_tokens }},输出token数: {{ output_tokens }}",
126
+ "ranking_process_failed": "排序过程失败: {{ error }}",
127
+ "ranking_failed": "排序失败,耗时 {{ elapsed }} 秒,使用原始顺序"
128
+ }
78
129
  }
79
130
 
80
131
 
@@ -1,24 +1,26 @@
1
1
 
2
2
  import os
3
3
  from byzerllm.utils.client import code_utils
4
- from autocoder.common import AutoCoderArgs,git_utils
5
- from typing import List,Union,Tuple
4
+ from autocoder.common import AutoCoderArgs, git_utils
5
+ from typing import List, Union, Tuple
6
6
  import pydantic
7
7
  import byzerllm
8
- from loguru import logger
9
8
  from autocoder.common.types import CodeGenerateResult, MergeCodeWithoutEffect
10
9
  from autocoder.common.code_modification_ranker import CodeModificationRanker
11
10
  import hashlib
12
11
  from autocoder.common import files as FileUtils
12
+ from autocoder.common.printer import Printer
13
+ from autocoder.common.auto_coder_lang import get_message
13
14
 
14
15
  class PathAndCode(pydantic.BaseModel):
15
16
  path: str
16
17
  content: str
17
18
 
18
19
  class CodeAutoMerge:
19
- def __init__(self, llm:byzerllm.ByzerLLM,args:AutoCoderArgs):
20
+ def __init__(self, llm: byzerllm.ByzerLLM, args: AutoCoderArgs):
20
21
  self.llm = llm
21
- self.args = args
22
+ self.args = args
23
+ self.printer = Printer()
22
24
 
23
25
 
24
26
  def parse_whole_text_v2(self,text: str) -> List[PathAndCode]:
@@ -159,8 +161,9 @@ class CodeAutoMerge:
159
161
  try:
160
162
  git_utils.commit_changes(self.args.source_dir, f"auto_coder_pre_{file_name}_{md5}")
161
163
  except Exception as e:
162
- logger.error(self.git_require_msg(source_dir=self.args.source_dir,error=str(e)))
163
- return
164
+ self.printer.print_in_terminal("git_init_required",
165
+ source_dir=self.args.source_dir, error=str(e))
166
+ return
164
167
 
165
168
  codes = self.parse_whole_text_v2(content)
166
169
  for block in codes:
@@ -168,11 +171,11 @@ class CodeAutoMerge:
168
171
  os.makedirs(os.path.dirname(file_path), exist_ok=True)
169
172
 
170
173
  with open(file_path, "w") as f:
171
- logger.info(f"Upsert path: {file_path}")
174
+ self.printer.print_in_terminal("upsert_file", file_path=file_path)
172
175
  total += 1
173
176
  f.write(block.content)
174
177
 
175
- logger.info(f"Merged {total} files into the project.")
178
+ self.printer.print_in_terminal("files_merged", total=total)
176
179
  if not force_skip_git:
177
180
  commit_result = git_utils.commit_changes(self.args.source_dir, f"auto_coder_{file_name}_{md5}")
178
181
  git_utils.print_commit_info(commit_result=commit_result)
@@ -4,7 +4,7 @@ from autocoder.common import AutoCoderArgs,git_utils
4
4
  from typing import List,Union,Tuple
5
5
  import pydantic
6
6
  import byzerllm
7
- from loguru import logger
7
+ from autocoder.common.printer import Printer
8
8
  import hashlib
9
9
  from pathlib import Path
10
10
  from itertools import groupby
@@ -361,7 +361,8 @@ other_hunks_applied = (
361
361
  class CodeAutoMergeDiff:
362
362
  def __init__(self, llm:byzerllm.ByzerLLM,args:AutoCoderArgs):
363
363
  self.llm = llm
364
- self.args = args
364
+ self.args = args
365
+ self.printer = Printer()
365
366
 
366
367
  def get_edits(self,content:str):
367
368
  # might raise ValueError for malformed ORIG/UPD blocks
@@ -514,13 +515,13 @@ class CodeAutoMergeDiff:
514
515
  try:
515
516
  git_utils.commit_changes(self.args.source_dir, f"auto_coder_pre_{file_name}_{md5}")
516
517
  except Exception as e:
517
- logger.error(self.git_require_msg(source_dir=self.args.source_dir,error=str(e)))
518
+ self.printer.print_in_terminal("git_init_required", style="red", source_dir=self.args.source_dir, error=str(e))
518
519
  return
519
520
 
520
521
  edits = self.get_edits(content)
521
522
  self.apply_edits(edits)
522
523
 
523
- logger.info(f"Merged {total} files into the project.")
524
+ self.printer.print_in_terminal("files_merged_total", total=total)
524
525
  if not force_skip_git:
525
526
  commit_result = git_utils.commit_changes(self.args.source_dir, f"auto_coder_{file_name}_{md5}")
526
527
  git_utils.print_commit_info(commit_result=commit_result)
@@ -9,7 +9,7 @@ from autocoder.utils.queue_communicate import (
9
9
  )
10
10
  import pydantic
11
11
  import byzerllm
12
- from loguru import logger
12
+
13
13
  import hashlib
14
14
  import subprocess
15
15
  import tempfile
@@ -21,6 +21,7 @@ from typing import Union, List, Tuple
21
21
  from autocoder.common.types import CodeGenerateResult, MergeCodeWithoutEffect
22
22
  from autocoder.common.code_modification_ranker import CodeModificationRanker
23
23
  from autocoder.common import files as FileUtils
24
+ from autocoder.common.printer import Printer
24
25
 
25
26
  class PathAndCode(pydantic.BaseModel):
26
27
  path: str
@@ -39,6 +40,7 @@ class CodeAutoMergeEditBlock:
39
40
  self.args = args
40
41
  self.fence_0 = fence_0
41
42
  self.fence_1 = fence_1
43
+ self.printer = Printer()
42
44
 
43
45
  def run_pylint(self, code: str) -> tuple[bool, str]:
44
46
  with tempfile.NamedTemporaryFile(
@@ -62,12 +64,12 @@ class CodeAutoMergeEditBlock:
62
64
  os.unlink(temp_file_path)
63
65
  if result.returncode != 0:
64
66
  error_message = result.stdout.strip() or result.stderr.strip()
65
- logger.warning(f"Pylint check failed: {error_message}")
67
+ self.printer.print_in_terminal("pylint_check_failed", error_message=error_message)
66
68
  return False, error_message
67
69
  return True, ""
68
70
  except subprocess.CalledProcessError as e:
69
71
  error_message = f"Error running pylint: {str(e)}"
70
- logger.error(error_message)
72
+ self.printer.print_in_terminal("pylint_error", error_message=error_message)
71
73
  os.unlink(temp_file_path)
72
74
  return False, error_message
73
75
 
@@ -344,9 +346,8 @@ class CodeAutoMergeEditBlock:
344
346
  ),
345
347
  )
346
348
  return
347
-
348
- s = f"Found {len(unmerged_blocks)} unmerged blocks, the changes will not be applied. Please review them manually then try again."
349
- logger.warning(s)
349
+
350
+ self.printer.print_in_terminal("unmerged_blocks_warning", num_blocks=len(unmerged_blocks))
350
351
  self._print_unmerged_blocks(unmerged_blocks)
351
352
  return
352
353
 
@@ -355,9 +356,9 @@ class CodeAutoMergeEditBlock:
355
356
  if file_path.endswith(".py"):
356
357
  pylint_passed, error_message = self.run_pylint(new_content)
357
358
  if not pylint_passed:
358
- logger.warning(
359
- f"Pylint check failed for {file_path}. Changes not applied. Error: {error_message}"
360
- )
359
+ self.printer.print_in_terminal("pylint_file_check_failed",
360
+ file_path=file_path,
361
+ error_message=error_message)
361
362
 
362
363
  if changes_made and not force_skip_git:
363
364
  try:
@@ -365,9 +366,9 @@ class CodeAutoMergeEditBlock:
365
366
  self.args.source_dir, f"auto_coder_pre_{file_name}_{md5}"
366
367
  )
367
368
  except Exception as e:
368
- logger.error(
369
- self.git_require_msg(
370
- source_dir=self.args.source_dir, error=str(e))
369
+ self.printer.print_str_in_terminal(
370
+ self.git_require_msg(source_dir=self.args.source_dir, error=str(e)),
371
+ style="red"
371
372
  )
372
373
  return
373
374
  # Now, apply the changes
@@ -406,30 +407,31 @@ class CodeAutoMergeEditBlock:
406
407
  )
407
408
  git_utils.print_commit_info(commit_result=commit_result)
408
409
  except Exception as e:
409
- logger.error(
410
- self.git_require_msg(
411
- source_dir=self.args.source_dir, error=str(e)
412
- )
410
+ self.printer.print_str_in_terminal(
411
+ self.git_require_msg(source_dir=self.args.source_dir, error=str(e)),
412
+ style="red"
413
413
  )
414
- logger.info(
415
- f"Merged changes in {len(file_content_mapping.keys())} files {len(changes_to_make)}/{len(codes)} blocks."
416
- )
414
+ self.printer.print_in_terminal("merge_success",
415
+ num_files=len(file_content_mapping.keys()),
416
+ num_changes=len(changes_to_make),
417
+ total_blocks=len(codes))
417
418
  else:
418
- logger.warning("No changes were made to any files.")
419
+ self.printer.print_in_terminal("no_changes_made")
419
420
 
420
421
  def _print_unmerged_blocks(self, unmerged_blocks: List[tuple]):
421
- console = Console()
422
- console.print("\n[bold red]Unmerged Blocks:[/bold red]")
422
+ self.printer.print_in_terminal("unmerged_blocks_title", style="bold red")
423
423
  for file_path, head, update, similarity in unmerged_blocks:
424
- console.print(f"\n[bold blue]File:[/bold blue] {file_path}")
425
- console.print(
426
- f"\n[bold green]Search Block({similarity}):[/bold green]")
424
+ self.printer.print_str_in_terminal(
425
+ f"\n{self.printer.get_message_from_key('unmerged_file_path').format(file_path=file_path)}",
426
+ style="bold blue"
427
+ )
428
+ self.printer.print_str_in_terminal(
429
+ f"\n{self.printer.get_message_from_key('unmerged_search_block').format(similarity=similarity)}",
430
+ style="bold green"
431
+ )
427
432
  syntax = Syntax(head, "python", theme="monokai", line_numbers=True)
428
- console.print(Panel(syntax, expand=False))
429
- console.print("\n[bold yellow]Replace Block:[/bold yellow]")
430
- syntax = Syntax(update, "python", theme="monokai",
431
- line_numbers=True)
432
- console.print(Panel(syntax, expand=False))
433
- console.print(
434
- f"\n[bold red]Total unmerged blocks: {len(unmerged_blocks)}[/bold red]"
435
- )
433
+ self.printer.console.print(Panel(syntax, expand=False))
434
+ self.printer.print_in_terminal("unmerged_replace_block", style="bold yellow")
435
+ syntax = Syntax(update, "python", theme="monokai", line_numbers=True)
436
+ self.printer.console.print(Panel(syntax, expand=False))
437
+ self.printer.print_in_terminal("unmerged_blocks_total", num_blocks=len(unmerged_blocks), style="bold red")
@@ -5,7 +5,7 @@ from autocoder.common import AutoCoderArgs, git_utils
5
5
  from typing import List,Tuple
6
6
  import pydantic
7
7
  import byzerllm
8
- from loguru import logger
8
+ from autocoder.common.printer import Printer
9
9
  import hashlib
10
10
  from pathlib import Path
11
11
  from autocoder.common.types import CodeGenerateResult, MergeCodeWithoutEffect
@@ -84,6 +84,7 @@ class CodeAutoMergeStrictDiff:
84
84
  def __init__(self, llm: byzerllm.ByzerLLM, args: AutoCoderArgs):
85
85
  self.llm = llm
86
86
  self.args = args
87
+ self.printer = Printer()
87
88
 
88
89
 
89
90
  def parse_diff_block(self,text: str) -> List[PathAndCode]:
@@ -192,7 +193,7 @@ class CodeAutoMergeStrictDiff:
192
193
  else:
193
194
  failed_blocks.append((full_path, content))
194
195
  except Exception as e:
195
- logger.warning(f"Failed to apply patch to {full_path}: {str(e)}")
196
+ self.printer.print_in_terminal("merge_failed", style="yellow", path=full_path, error=str(e))
196
197
  failed_blocks.append((full_path, content))
197
198
 
198
199
  return MergeCodeWithoutEffect(
@@ -212,7 +213,7 @@ class CodeAutoMergeStrictDiff:
212
213
  try:
213
214
  git_utils.commit_changes(self.args.source_dir, f"auto_coder_pre_{file_name}_{md5}")
214
215
  except Exception as e:
215
- logger.error(self.git_require_msg(source_dir=self.args.source_dir, error=str(e)))
216
+ self.printer.print_in_terminal("git_init_required", style="red", source_dir=self.args.source_dir, error=str(e))
216
217
  return
217
218
 
218
219
  diff_blocks = self.parse_diff_block(content)
@@ -230,7 +231,7 @@ class CodeAutoMergeStrictDiff:
230
231
  if not success:
231
232
  raise Exception("Error applying diff to file: " + path)
232
233
 
233
- logger.info(f"Merged {total} files into the project.")
234
+ self.printer.print_in_terminal("files_merged_total", total=total)
234
235
  if not force_skip_git:
235
236
  commit_result = git_utils.commit_changes(self.args.source_dir, f"auto_coder_{file_name}_{md5}")
236
237
  git_utils.print_commit_info(commit_result=commit_result)