auto-coder 0.1.334__py3-none-any.whl → 0.1.336__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.
- {auto_coder-0.1.334.dist-info → auto_coder-0.1.336.dist-info}/METADATA +2 -2
- {auto_coder-0.1.334.dist-info → auto_coder-0.1.336.dist-info}/RECORD +67 -32
- autocoder/agent/agentic_edit.py +833 -0
- autocoder/agent/agentic_edit_tools/__init__.py +28 -0
- autocoder/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +32 -0
- autocoder/agent/agentic_edit_tools/attempt_completion_tool_resolver.py +29 -0
- autocoder/agent/agentic_edit_tools/base_tool_resolver.py +29 -0
- autocoder/agent/agentic_edit_tools/execute_command_tool_resolver.py +84 -0
- autocoder/agent/agentic_edit_tools/list_code_definition_names_tool_resolver.py +75 -0
- autocoder/agent/agentic_edit_tools/list_files_tool_resolver.py +62 -0
- autocoder/agent/agentic_edit_tools/plan_mode_respond_tool_resolver.py +30 -0
- autocoder/agent/agentic_edit_tools/read_file_tool_resolver.py +36 -0
- autocoder/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +95 -0
- autocoder/agent/agentic_edit_tools/search_files_tool_resolver.py +70 -0
- autocoder/agent/agentic_edit_tools/use_mcp_tool_resolver.py +55 -0
- autocoder/agent/agentic_edit_tools/write_to_file_tool_resolver.py +98 -0
- autocoder/agent/agentic_edit_types.py +124 -0
- autocoder/auto_coder.py +39 -18
- autocoder/auto_coder_rag.py +18 -9
- autocoder/auto_coder_runner.py +50 -5
- autocoder/chat_auto_coder_lang.py +18 -2
- autocoder/commands/tools.py +5 -1
- autocoder/common/__init__.py +2 -0
- autocoder/common/auto_coder_lang.py +40 -8
- autocoder/common/code_auto_generate_diff.py +1 -1
- autocoder/common/code_auto_generate_editblock.py +1 -1
- autocoder/common/code_auto_generate_strict_diff.py +1 -1
- autocoder/common/mcp_hub.py +185 -2
- autocoder/common/mcp_server.py +243 -306
- autocoder/common/mcp_server_install.py +269 -0
- autocoder/common/mcp_server_types.py +169 -0
- autocoder/common/stream_out_type.py +3 -0
- autocoder/common/v2/agent/__init__.py +0 -0
- autocoder/common/v2/agent/agentic_edit.py +1302 -0
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +28 -0
- autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +70 -0
- autocoder/common/v2/agent/agentic_edit_tools/attempt_completion_tool_resolver.py +35 -0
- autocoder/common/v2/agent/agentic_edit_tools/base_tool_resolver.py +33 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +88 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_code_definition_names_tool_resolver.py +80 -0
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +105 -0
- autocoder/common/v2/agent/agentic_edit_tools/plan_mode_respond_tool_resolver.py +35 -0
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +51 -0
- autocoder/common/v2/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +144 -0
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +99 -0
- autocoder/common/v2/agent/agentic_edit_tools/use_mcp_tool_resolver.py +46 -0
- autocoder/common/v2/agent/agentic_edit_tools/write_to_file_tool_resolver.py +58 -0
- autocoder/common/v2/agent/agentic_edit_types.py +162 -0
- autocoder/common/v2/agent/agentic_tool_display.py +184 -0
- autocoder/common/v2/code_agentic_editblock_manager.py +812 -0
- autocoder/common/v2/code_auto_generate.py +1 -1
- autocoder/common/v2/code_auto_generate_diff.py +1 -1
- autocoder/common/v2/code_auto_generate_editblock.py +1 -1
- autocoder/common/v2/code_auto_generate_strict_diff.py +1 -1
- autocoder/common/v2/code_editblock_manager.py +151 -178
- autocoder/compilers/provided_compiler.py +3 -2
- autocoder/events/event_manager.py +4 -4
- autocoder/events/event_types.py +1 -0
- autocoder/memory/active_context_manager.py +2 -29
- autocoder/models.py +10 -2
- autocoder/shadows/shadow_manager.py +1 -1
- autocoder/utils/llms.py +4 -2
- autocoder/version.py +1 -1
- {auto_coder-0.1.334.dist-info → auto_coder-0.1.336.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.334.dist-info → auto_coder-0.1.336.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.334.dist-info → auto_coder-0.1.336.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.334.dist-info → auto_coder-0.1.336.dist-info}/top_level.txt +0 -0
|
@@ -65,7 +65,7 @@ class CodeAutoGenerate:
|
|
|
65
65
|
# 获取包上下文信息
|
|
66
66
|
package_context = ""
|
|
67
67
|
|
|
68
|
-
if self.args.enable_active_context:
|
|
68
|
+
if self.args.enable_active_context and self.args.enable_active_context_in_generate:
|
|
69
69
|
# 获取活动上下文信息
|
|
70
70
|
result = active_context_manager.load_active_contexts_for_files(
|
|
71
71
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -227,7 +227,7 @@ class CodeAutoGenerateDiff:
|
|
|
227
227
|
# 获取包上下文信息
|
|
228
228
|
package_context = ""
|
|
229
229
|
|
|
230
|
-
if self.args.enable_active_context:
|
|
230
|
+
if self.args.enable_active_context and self.args.enable_active_context_in_generate:
|
|
231
231
|
# 获取活动上下文信息
|
|
232
232
|
result = active_context_manager.load_active_contexts_for_files(
|
|
233
233
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -245,7 +245,7 @@ class CodeAutoGenerateEditBlock:
|
|
|
245
245
|
# 获取包上下文信息
|
|
246
246
|
package_context = ""
|
|
247
247
|
|
|
248
|
-
if self.args.enable_active_context:
|
|
248
|
+
if self.args.enable_active_context and self.args.enable_active_context_in_generate:
|
|
249
249
|
# 获取活动上下文信息
|
|
250
250
|
result = active_context_manager.load_active_contexts_for_files(
|
|
251
251
|
[source.module_name for source in source_code_list.sources]
|
|
@@ -299,7 +299,7 @@ class CodeAutoGenerateStrictDiff:
|
|
|
299
299
|
# 获取包上下文信息
|
|
300
300
|
package_context = ""
|
|
301
301
|
|
|
302
|
-
if self.args.enable_active_context:
|
|
302
|
+
if self.args.enable_active_context and self.args.enable_active_context_in_generate:
|
|
303
303
|
# 初始化活动上下文管理器
|
|
304
304
|
active_context_manager = ActiveContextManager(self.llm, self.args.source_dir)
|
|
305
305
|
# 获取活动上下文信息
|
|
@@ -5,14 +5,14 @@ import time
|
|
|
5
5
|
import byzerllm
|
|
6
6
|
|
|
7
7
|
from autocoder.common.types import Mode, CodeGenerateResult, MergeCodeWithoutEffect
|
|
8
|
-
from autocoder.common import AutoCoderArgs, SourceCodeList,SourceCode
|
|
8
|
+
from autocoder.common import AutoCoderArgs, SourceCodeList, SourceCode
|
|
9
9
|
from autocoder.common.action_yml_file_manager import ActionYmlFileManager
|
|
10
10
|
from autocoder.common import sys_prompt
|
|
11
11
|
from autocoder.compilers.shadow_compiler import ShadowCompiler
|
|
12
12
|
from autocoder.privacy.model_filter import ModelPathFilter
|
|
13
13
|
from autocoder.common.utils_code_auto_generate import chat_with_continue, stream_chat_with_continue, ChatWithContinueResult
|
|
14
14
|
from autocoder.utils.auto_coder_utils.chat_stream_out import stream_out
|
|
15
|
-
from autocoder.common.stream_out_type import LintStreamOutType, CompileStreamOutType, UnmergedBlocksStreamOutType
|
|
15
|
+
from autocoder.common.stream_out_type import LintStreamOutType, CompileStreamOutType, UnmergedBlocksStreamOutType, ContextMissingCheckStreamOutType
|
|
16
16
|
from autocoder.common.auto_coder_lang import get_message_with_format
|
|
17
17
|
from autocoder.common.printer import Printer
|
|
18
18
|
from autocoder.rag.token_counter import count_tokens
|
|
@@ -242,11 +242,34 @@ class CodeEditBlockManager:
|
|
|
242
242
|
返回:
|
|
243
243
|
CodeGenerateResult: 修复后的代码结果
|
|
244
244
|
"""
|
|
245
|
+
get_event_manager(self.args.event_file).write_result(
|
|
246
|
+
EventContentCreator.create_result(
|
|
247
|
+
content=self.printer.get_message_from_key("/context/check/start")),
|
|
248
|
+
metadata={
|
|
249
|
+
# Using a placeholder type, replace if ContextFixStreamOutType is defined
|
|
250
|
+
"stream_out_type": ContextMissingCheckStreamOutType.CONTEXT_MISSING_CHECK.value,
|
|
251
|
+
"action_file": self.args.file,
|
|
252
|
+
"path": "/context/check/start"
|
|
253
|
+
}
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
def write_end_event():
|
|
257
|
+
get_event_manager(self.args.event_file).write_result(
|
|
258
|
+
EventContentCreator.create_result(
|
|
259
|
+
content=self.printer.get_message_from_key("/context/check/end")),
|
|
260
|
+
metadata={
|
|
261
|
+
# Using a placeholder type, replace if ContextFixStreamOutType is defined
|
|
262
|
+
"stream_out_type": ContextMissingCheckStreamOutType.CONTEXT_MISSING_CHECK.value,
|
|
263
|
+
"action_file": self.args.file,
|
|
264
|
+
"path": "/context/check/end"
|
|
265
|
+
}
|
|
266
|
+
)
|
|
267
|
+
|
|
245
268
|
token_cost_calculator = TokenCostCalculator(args=self.args)
|
|
246
|
-
|
|
269
|
+
|
|
247
270
|
# 获取编辑块
|
|
248
271
|
codes = self.code_merger.get_edits(generation_result.contents[0])
|
|
249
|
-
|
|
272
|
+
|
|
250
273
|
# 检查是否有空的SEARCH块但目标文件存在
|
|
251
274
|
missing_files = []
|
|
252
275
|
for file_path, head, update in codes:
|
|
@@ -258,7 +281,7 @@ class CodeEditBlockManager:
|
|
|
258
281
|
in_context = file_path in self.args.urls
|
|
259
282
|
if hasattr(self.args, 'dynamic_urls') and self.args.dynamic_urls and not in_context:
|
|
260
283
|
in_context = file_path in self.args.dynamic_urls
|
|
261
|
-
|
|
284
|
+
|
|
262
285
|
# 如果文件存在但不在上下文中,添加到缺失文件列表
|
|
263
286
|
if not in_context:
|
|
264
287
|
missing_files.append(file_path)
|
|
@@ -267,58 +290,61 @@ class CodeEditBlockManager:
|
|
|
267
290
|
self.args.dynamic_urls = []
|
|
268
291
|
if file_path not in self.args.dynamic_urls:
|
|
269
292
|
self.args.dynamic_urls.append(file_path)
|
|
270
|
-
|
|
293
|
+
|
|
271
294
|
# 如果没有缺失文件,直接返回原结果
|
|
272
295
|
if not missing_files:
|
|
296
|
+
write_end_event()
|
|
273
297
|
return generation_result
|
|
274
|
-
|
|
298
|
+
|
|
275
299
|
# 格式化缺失文件列表
|
|
276
300
|
missing_files_text = "\n".join(missing_files)
|
|
277
|
-
|
|
301
|
+
|
|
278
302
|
# 打印当前修复状态
|
|
279
303
|
self.printer.print_in_terminal(
|
|
280
304
|
"missing_context_attempt_status",
|
|
281
305
|
style="yellow",
|
|
282
306
|
missing_files=missing_files_text
|
|
283
307
|
)
|
|
284
|
-
|
|
308
|
+
|
|
285
309
|
# 更新源代码列表,包含新添加的文件
|
|
286
310
|
updated_source_code_list = SourceCodeList([])
|
|
287
311
|
for source in source_code_list.sources:
|
|
288
312
|
updated_source_code_list.sources.append(source)
|
|
289
|
-
|
|
313
|
+
|
|
290
314
|
# 添加缺失的文件到源代码列表
|
|
291
315
|
for file_path in missing_files:
|
|
292
316
|
if os.path.exists(file_path):
|
|
293
317
|
with open(file_path, 'r') as f:
|
|
294
318
|
file_content = f.read()
|
|
295
|
-
source = SourceCode(module_name=file_path,
|
|
319
|
+
source = SourceCode(module_name=file_path,
|
|
320
|
+
source_code=file_content)
|
|
296
321
|
updated_source_code_list.sources.append(source)
|
|
297
|
-
|
|
322
|
+
|
|
298
323
|
# 更新action yml文件
|
|
299
324
|
if missing_files and hasattr(self.args, 'dynamic_urls') and self.args.dynamic_urls:
|
|
300
|
-
action_yml_file_manager = ActionYmlFileManager(
|
|
325
|
+
action_yml_file_manager = ActionYmlFileManager(
|
|
326
|
+
self.args.source_dir)
|
|
301
327
|
action_file_name = os.path.basename(self.args.file)
|
|
302
328
|
update_yaml_success = action_yml_file_manager.update_yaml_field(
|
|
303
329
|
action_file_name, "dynamic_urls", self.args.dynamic_urls)
|
|
304
330
|
if not update_yaml_success:
|
|
305
331
|
self.printer.print_in_terminal(
|
|
306
332
|
"yaml_save_error", style="red", yaml_file=action_file_name)
|
|
307
|
-
|
|
333
|
+
|
|
308
334
|
# 准备修复提示
|
|
309
335
|
fix_prompt = self.fix_missing_context.prompt(
|
|
310
336
|
query=query,
|
|
311
337
|
original_code=generation_result.contents[0],
|
|
312
338
|
missing_files=missing_files_text
|
|
313
339
|
)
|
|
314
|
-
|
|
340
|
+
|
|
315
341
|
logger.info(f"fix_missing_context_prompt: {fix_prompt}")
|
|
316
|
-
|
|
342
|
+
|
|
317
343
|
# 使用修复提示重新生成代码
|
|
318
344
|
start_time = time.time()
|
|
319
345
|
generation_result = self.code_generator.single_round_run(
|
|
320
346
|
fix_prompt, updated_source_code_list)
|
|
321
|
-
|
|
347
|
+
|
|
322
348
|
# 计算这次修复缺失上下文花费的token情况
|
|
323
349
|
token_cost_calculator.track_token_usage_by_generate(
|
|
324
350
|
llm=self.llm,
|
|
@@ -327,12 +353,15 @@ class CodeEditBlockManager:
|
|
|
327
353
|
start_time=start_time,
|
|
328
354
|
end_time=time.time()
|
|
329
355
|
)
|
|
330
|
-
|
|
356
|
+
|
|
331
357
|
# 选择最佳结果
|
|
332
|
-
generation_result = self.code_merger.choose_best_choice(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
358
|
+
generation_result = self.code_merger.choose_best_choice(
|
|
359
|
+
generation_result)
|
|
360
|
+
# 因为已经排完结果,就不要触发后面的排序了,所以只要保留第一个即可。
|
|
361
|
+
generation_result = CodeGenerateResult(contents=[generation_result.contents[0]], conversations=[
|
|
362
|
+
generation_result.conversations[0]], metadata=generation_result.metadata)
|
|
363
|
+
|
|
364
|
+
write_end_event()
|
|
336
365
|
return generation_result
|
|
337
366
|
|
|
338
367
|
def _fix_unmerged_blocks(self, query: str, generation_result: CodeGenerateResult, source_code_list: SourceCodeList) -> CodeGenerateResult:
|
|
@@ -348,11 +377,22 @@ class CodeEditBlockManager:
|
|
|
348
377
|
CodeGenerateResult: 修复后的代码结果
|
|
349
378
|
"""
|
|
350
379
|
token_cost_calculator = TokenCostCalculator(args=self.args)
|
|
351
|
-
merge = self.code_merger._merge_code_without_effect(
|
|
380
|
+
merge = self.code_merger._merge_code_without_effect(
|
|
381
|
+
generation_result.contents[0])
|
|
352
382
|
|
|
353
383
|
if not self.args.enable_auto_fix_merge or not merge.failed_blocks:
|
|
354
384
|
return generation_result
|
|
355
385
|
|
|
386
|
+
get_event_manager(self.args.event_file).write_result(
|
|
387
|
+
EventContentCreator.create_result(
|
|
388
|
+
content=self.printer.get_message_from_key("/unmerged_blocks/check/start")),
|
|
389
|
+
metadata={
|
|
390
|
+
"stream_out_type": UnmergedBlocksStreamOutType.UNMERGED_BLOCKS.value,
|
|
391
|
+
"action_file": self.args.file,
|
|
392
|
+
"path": "/unmerged_blocks/check/start"
|
|
393
|
+
}
|
|
394
|
+
)
|
|
395
|
+
|
|
356
396
|
def _format_blocks(merge: MergeCodeWithoutEffect) -> Tuple[str, str]:
|
|
357
397
|
unmerged_formatted_text = ""
|
|
358
398
|
for file_path, head, update in merge.failed_blocks:
|
|
@@ -386,14 +426,16 @@ class CodeEditBlockManager:
|
|
|
386
426
|
).to_dict(),
|
|
387
427
|
metadata={
|
|
388
428
|
"stream_out_type": UnmergedBlocksStreamOutType.UNMERGED_BLOCKS.value,
|
|
389
|
-
"action_file": self.args.file
|
|
429
|
+
"action_file": self.args.file,
|
|
430
|
+
"path": "/unmerged_blocks/check/message"
|
|
390
431
|
}
|
|
391
432
|
))
|
|
392
433
|
return (unmerged_formatted_text, merged_formatted_text)
|
|
393
434
|
|
|
394
435
|
for attempt in range(self.args.auto_fix_merge_max_attempts):
|
|
395
436
|
global_cancel.check_and_raise()
|
|
396
|
-
unmerged_formatted_text, merged_formatted_text = _format_blocks(
|
|
437
|
+
unmerged_formatted_text, merged_formatted_text = _format_blocks(
|
|
438
|
+
merge)
|
|
397
439
|
fix_prompt = self.fix_unmerged_blocks.prompt(
|
|
398
440
|
query=query,
|
|
399
441
|
original_code=generation_result.contents[0],
|
|
@@ -416,7 +458,8 @@ class CodeEditBlockManager:
|
|
|
416
458
|
).to_dict(),
|
|
417
459
|
metadata={
|
|
418
460
|
"stream_out_type": UnmergedBlocksStreamOutType.UNMERGED_BLOCKS.value,
|
|
419
|
-
"action_file": self.args.file
|
|
461
|
+
"action_file": self.args.file,
|
|
462
|
+
"path": "/unmerged_blocks/check/message"
|
|
420
463
|
}
|
|
421
464
|
))
|
|
422
465
|
|
|
@@ -435,9 +478,11 @@ class CodeEditBlockManager:
|
|
|
435
478
|
)
|
|
436
479
|
|
|
437
480
|
# 检查修复后的代码是否仍有未合并块
|
|
438
|
-
generation_result = self.code_merger.choose_best_choice(
|
|
439
|
-
|
|
440
|
-
|
|
481
|
+
generation_result = self.code_merger.choose_best_choice(
|
|
482
|
+
generation_result)
|
|
483
|
+
# 因为已经排完结果,就不要触发后面的排序了,所以只要保留第一个即可。
|
|
484
|
+
generation_result = CodeGenerateResult(contents=[generation_result.contents[0]], conversations=[
|
|
485
|
+
generation_result.conversations[0]], metadata=generation_result.metadata)
|
|
441
486
|
merge = self.code_merger._merge_code_without_effect(
|
|
442
487
|
generation_result.contents[0])
|
|
443
488
|
|
|
@@ -462,137 +507,16 @@ class CodeEditBlockManager:
|
|
|
462
507
|
))
|
|
463
508
|
raise Exception(self.printer.get_message_from_key(
|
|
464
509
|
"max_unmerged_blocks_attempts_reached"))
|
|
465
|
-
|
|
466
|
-
return generation_result
|
|
467
|
-
|
|
468
|
-
def _fix_unmerged_blocks(self, query: str, generation_result: CodeGenerateResult, source_code_list: SourceCodeList) -> CodeGenerateResult:
|
|
469
|
-
"""
|
|
470
|
-
修复未合并的代码块,最多尝试指定次数
|
|
471
|
-
|
|
472
|
-
参数:
|
|
473
|
-
query (str): 用户查询
|
|
474
|
-
generation_result (CodeGenerateResult): 生成的代码结果
|
|
475
|
-
source_code_list (SourceCodeList): 源代码列表
|
|
476
|
-
|
|
477
|
-
返回:
|
|
478
|
-
CodeGenerateResult: 修复后的代码结果
|
|
479
|
-
"""
|
|
480
|
-
token_cost_calculator = TokenCostCalculator(args=self.args)
|
|
481
|
-
merge = self.code_merger._merge_code_without_effect(generation_result.contents[0])
|
|
482
510
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
unmerged_formatted_text += head
|
|
493
|
-
unmerged_formatted_text += "=======\n"
|
|
494
|
-
unmerged_formatted_text += update
|
|
495
|
-
unmerged_formatted_text += ">>>>>>> REPLACE\n"
|
|
496
|
-
unmerged_formatted_text += "```"
|
|
497
|
-
unmerged_formatted_text += "\n"
|
|
498
|
-
|
|
499
|
-
merged_formatted_text = ""
|
|
500
|
-
if merge.merged_blocks:
|
|
501
|
-
for file_path, head, update in merge.merged_blocks:
|
|
502
|
-
merged_formatted_text += "```lang"
|
|
503
|
-
merged_formatted_text += f"##File: {file_path}\n"
|
|
504
|
-
merged_formatted_text += head
|
|
505
|
-
merged_formatted_text += "=======\n"
|
|
506
|
-
merged_formatted_text += update
|
|
507
|
-
merged_formatted_text += "```"
|
|
508
|
-
merged_formatted_text += "\n"
|
|
509
|
-
|
|
510
|
-
get_event_manager(self.args.event_file).write_result(EventContentCreator.create_result(
|
|
511
|
-
content=EventContentCreator.ResultContent(content=f"Unmerged blocks:\\n {unmerged_formatted_text}",
|
|
512
|
-
metadata={
|
|
513
|
-
"merged_blocks": merge.success_blocks,
|
|
514
|
-
"failed_blocks": merge.failed_blocks
|
|
515
|
-
}
|
|
516
|
-
).to_dict(),
|
|
517
|
-
metadata={
|
|
518
|
-
"stream_out_type": UnmergedBlocksStreamOutType.UNMERGED_BLOCKS.value,
|
|
519
|
-
"action_file": self.args.file
|
|
520
|
-
}
|
|
521
|
-
))
|
|
522
|
-
return (unmerged_formatted_text, merged_formatted_text)
|
|
523
|
-
|
|
524
|
-
for attempt in range(self.args.auto_fix_merge_max_attempts):
|
|
525
|
-
global_cancel.check_and_raise()
|
|
526
|
-
unmerged_formatted_text, merged_formatted_text = _format_blocks(merge)
|
|
527
|
-
fix_prompt = self.fix_unmerged_blocks.prompt(
|
|
528
|
-
query=query,
|
|
529
|
-
original_code=generation_result.contents[0],
|
|
530
|
-
unmerged_blocks=unmerged_formatted_text
|
|
531
|
-
)
|
|
532
|
-
|
|
533
|
-
logger.info(f"fix_prompt: {fix_prompt}")
|
|
534
|
-
|
|
535
|
-
# 打印当前修复尝试状态
|
|
536
|
-
self.printer.print_in_terminal(
|
|
537
|
-
"unmerged_blocks_attempt_status",
|
|
538
|
-
style="yellow",
|
|
539
|
-
attempt=(attempt + 1),
|
|
540
|
-
max_correction_attempts=self.args.auto_fix_merge_max_attempts
|
|
541
|
-
)
|
|
542
|
-
|
|
543
|
-
get_event_manager(self.args.event_file).write_result(EventContentCreator.create_result(
|
|
544
|
-
content=EventContentCreator.ResultContent(content=f"Unmerged blocks attempt {attempt + 1}/{self.args.auto_fix_merge_max_attempts}: {unmerged_formatted_text}",
|
|
545
|
-
metadata={}
|
|
546
|
-
).to_dict(),
|
|
547
|
-
metadata={
|
|
548
|
-
"stream_out_type": UnmergedBlocksStreamOutType.UNMERGED_BLOCKS.value,
|
|
549
|
-
"action_file": self.args.file
|
|
550
|
-
}
|
|
551
|
-
))
|
|
552
|
-
|
|
553
|
-
# 使用修复提示重新生成代码
|
|
554
|
-
start_time = time.time()
|
|
555
|
-
generation_result = self.code_generator.single_round_run(
|
|
556
|
-
fix_prompt, source_code_list)
|
|
557
|
-
|
|
558
|
-
# 计算这次修复未合并块花费的token情况
|
|
559
|
-
token_cost_calculator.track_token_usage_by_generate(
|
|
560
|
-
llm=self.llm,
|
|
561
|
-
generate=generation_result,
|
|
562
|
-
operation_name="code_generation_complete",
|
|
563
|
-
start_time=start_time,
|
|
564
|
-
end_time=time.time()
|
|
565
|
-
)
|
|
566
|
-
|
|
567
|
-
# 检查修复后的代码是否仍有未合并块
|
|
568
|
-
generation_result = self.code_merger.choose_best_choice(generation_result)
|
|
569
|
-
## 因为已经排完结果,就不要触发后面的排序了,所以只要保留第一个即可。
|
|
570
|
-
generation_result = CodeGenerateResult(contents=[generation_result.contents[0]],conversations=[generation_result.conversations[0]],metadata=generation_result.metadata)
|
|
571
|
-
merge = self.code_merger._merge_code_without_effect(
|
|
572
|
-
generation_result.contents[0])
|
|
573
|
-
|
|
574
|
-
# 如果没有失败的块,则修复成功,退出循环
|
|
575
|
-
if not merge.failed_blocks:
|
|
576
|
-
self.printer.print_in_terminal(
|
|
577
|
-
"unmerged_blocks_fixed", style="green")
|
|
578
|
-
break
|
|
579
|
-
|
|
580
|
-
# 如果是最后一次尝试仍未成功,打印警告
|
|
581
|
-
if attempt == self.args.auto_fix_merge_max_attempts - 1:
|
|
582
|
-
self.printer.print_in_terminal(
|
|
583
|
-
"max_unmerged_blocks_attempts_reached", style="yellow")
|
|
584
|
-
get_event_manager(self.args.event_file).write_result(EventContentCreator.create_result(
|
|
585
|
-
content=EventContentCreator.ResultContent(content=self.printer.get_message_from_key("max_unmerged_blocks_attempts_reached"),
|
|
586
|
-
metadata={}
|
|
587
|
-
).to_dict(),
|
|
588
|
-
metadata={
|
|
589
|
-
"stream_out_type": UnmergedBlocksStreamOutType.UNMERGED_BLOCKS.value,
|
|
590
|
-
"action_file": self.args.file
|
|
591
|
-
}
|
|
592
|
-
))
|
|
593
|
-
raise Exception(self.printer.get_message_from_key(
|
|
594
|
-
"max_unmerged_blocks_attempts_reached"))
|
|
595
|
-
|
|
511
|
+
get_event_manager(self.args.event_file).write_result(
|
|
512
|
+
EventContentCreator.create_result(
|
|
513
|
+
content=self.printer.get_message_from_key("/unmerged_blocks/check/end")),
|
|
514
|
+
metadata={
|
|
515
|
+
"stream_out_type": UnmergedBlocksStreamOutType.UNMERGED_BLOCKS.value,
|
|
516
|
+
"action_file": self.args.file,
|
|
517
|
+
"path": "/unmerged_blocks/check/end"
|
|
518
|
+
}
|
|
519
|
+
)
|
|
596
520
|
return generation_result
|
|
597
521
|
|
|
598
522
|
def _fix_lint_errors(self, query: str, generation_result: CodeGenerateResult, source_code_list: SourceCodeList) -> CodeGenerateResult:
|
|
@@ -607,11 +531,22 @@ class CodeEditBlockManager:
|
|
|
607
531
|
返回:
|
|
608
532
|
CodeGenerateResult: 修复后的代码结果
|
|
609
533
|
"""
|
|
534
|
+
get_event_manager(self.args.event_file).write_result(
|
|
535
|
+
EventContentCreator.create_result(
|
|
536
|
+
content=self.printer.get_message_from_key("/lint/check/start")),
|
|
537
|
+
metadata={
|
|
538
|
+
"stream_out_type": LintStreamOutType.LINT.value,
|
|
539
|
+
"action_file": self.args.file,
|
|
540
|
+
"path": "/lint/check/start"
|
|
541
|
+
}
|
|
542
|
+
)
|
|
543
|
+
|
|
610
544
|
token_cost_calculator = TokenCostCalculator(args=self.args)
|
|
611
545
|
|
|
612
546
|
for attempt in range(self.auto_fix_lint_max_attempts):
|
|
613
547
|
global_cancel.check_and_raise()
|
|
614
548
|
# 代码生成结果更新到影子文件里去
|
|
549
|
+
self.shadow_manager.clean_shadows()
|
|
615
550
|
shadow_files = self._create_shadow_files_from_edits(
|
|
616
551
|
generation_result)
|
|
617
552
|
|
|
@@ -651,7 +586,8 @@ class CodeEditBlockManager:
|
|
|
651
586
|
).to_dict(),
|
|
652
587
|
metadata={
|
|
653
588
|
"stream_out_type": LintStreamOutType.LINT.value,
|
|
654
|
-
"action_file": self.args.file
|
|
589
|
+
"action_file": self.args.file,
|
|
590
|
+
"path": "/lint/check/message"
|
|
655
591
|
}
|
|
656
592
|
))
|
|
657
593
|
|
|
@@ -681,7 +617,16 @@ class CodeEditBlockManager:
|
|
|
681
617
|
start_time=start_time,
|
|
682
618
|
end_time=time.time()
|
|
683
619
|
)
|
|
684
|
-
|
|
620
|
+
|
|
621
|
+
get_event_manager(self.args.event_file).write_result(
|
|
622
|
+
EventContentCreator.create_result(
|
|
623
|
+
content=self.printer.get_message_from_key("/lint/check/end")),
|
|
624
|
+
metadata={
|
|
625
|
+
"stream_out_type": LintStreamOutType.LINT.value,
|
|
626
|
+
"action_file": self.args.file,
|
|
627
|
+
"path": "/lint/check/end"
|
|
628
|
+
}
|
|
629
|
+
)
|
|
685
630
|
return generation_result
|
|
686
631
|
|
|
687
632
|
def _fix_compile_errors(self, query: str, generation_result: CodeGenerateResult, source_code_list: SourceCodeList) -> CodeGenerateResult:
|
|
@@ -698,15 +643,26 @@ class CodeEditBlockManager:
|
|
|
698
643
|
"""
|
|
699
644
|
if not self.args.enable_auto_fix_compile:
|
|
700
645
|
return generation_result
|
|
701
|
-
|
|
646
|
+
|
|
647
|
+
get_event_manager(self.args.event_file).write_result(
|
|
648
|
+
EventContentCreator.create_result(
|
|
649
|
+
content=self.printer.get_message_from_key("/compile/check/start")),
|
|
650
|
+
metadata={
|
|
651
|
+
"stream_out_type": CompileStreamOutType.COMPILE.value,
|
|
652
|
+
"action_file": self.args.file,
|
|
653
|
+
"path": "/compile/check/start"
|
|
654
|
+
}
|
|
655
|
+
)
|
|
656
|
+
|
|
702
657
|
token_cost_calculator = TokenCostCalculator(args=self.args)
|
|
703
|
-
|
|
658
|
+
|
|
704
659
|
for attempt in range(self.auto_fix_compile_max_attempts):
|
|
705
660
|
global_cancel.check_and_raise()
|
|
706
661
|
# 先更新增量影子系统的文件
|
|
662
|
+
self.shadow_manager.clean_shadows()
|
|
707
663
|
shadow_files = self._create_shadow_files_from_edits(
|
|
708
664
|
generation_result)
|
|
709
|
-
|
|
665
|
+
|
|
710
666
|
# 在影子系统生成完整的项目,然后编译
|
|
711
667
|
compile_result = self.shadow_compiler.compile_all_shadow_files()
|
|
712
668
|
|
|
@@ -723,7 +679,8 @@ class CodeEditBlockManager:
|
|
|
723
679
|
).to_dict(),
|
|
724
680
|
metadata={
|
|
725
681
|
"stream_out_type": CompileStreamOutType.COMPILE.value,
|
|
726
|
-
"action_file": self.args.file
|
|
682
|
+
"action_file": self.args.file,
|
|
683
|
+
"path": "/compile/check/message"
|
|
727
684
|
}
|
|
728
685
|
))
|
|
729
686
|
|
|
@@ -759,7 +716,18 @@ class CodeEditBlockManager:
|
|
|
759
716
|
start_time=start_time,
|
|
760
717
|
end_time=time.time()
|
|
761
718
|
)
|
|
762
|
-
|
|
719
|
+
|
|
720
|
+
# Log end only if enabled
|
|
721
|
+
if self.args.enable_auto_fix_compile:
|
|
722
|
+
get_event_manager(self.args.event_file).write_result(
|
|
723
|
+
EventContentCreator.create_result(
|
|
724
|
+
content=self.printer.get_message_from_key("/compile/check/end")),
|
|
725
|
+
metadata={
|
|
726
|
+
"stream_out_type": CompileStreamOutType.COMPILE.value,
|
|
727
|
+
"action_file": self.args.file,
|
|
728
|
+
"path": "/compile/check/end"
|
|
729
|
+
}
|
|
730
|
+
)
|
|
763
731
|
return generation_result
|
|
764
732
|
|
|
765
733
|
def generate_and_fix(self, query: str, source_code_list: SourceCodeList) -> CodeGenerateResult:
|
|
@@ -792,27 +760,32 @@ class CodeEditBlockManager:
|
|
|
792
760
|
if not generation_result.contents:
|
|
793
761
|
self.printer.print_in_terminal("generation_failed", style="red")
|
|
794
762
|
return generation_result
|
|
795
|
-
|
|
796
|
-
## 可能第一次触发排序
|
|
797
|
-
generation_result = self.code_merger.choose_best_choice(generation_result)
|
|
798
763
|
|
|
799
|
-
|
|
800
|
-
generation_result =
|
|
764
|
+
# 可能第一次触发排序
|
|
765
|
+
generation_result = self.code_merger.choose_best_choice(
|
|
766
|
+
generation_result)
|
|
767
|
+
|
|
768
|
+
# 因为已经排完结果,就不要触发后面的排序了,所以只要保留第一个即可。
|
|
769
|
+
generation_result = CodeGenerateResult(contents=[generation_result.contents[0]], conversations=[
|
|
770
|
+
generation_result.conversations[0]], metadata=generation_result.metadata)
|
|
801
771
|
|
|
802
772
|
# 修复缺少上下文的文件
|
|
803
|
-
generation_result = self._fix_missing_context(
|
|
773
|
+
generation_result = self._fix_missing_context(
|
|
774
|
+
query, generation_result, source_code_list)
|
|
804
775
|
|
|
805
776
|
# 修复未合并的代码块
|
|
806
|
-
generation_result = self._fix_unmerged_blocks(
|
|
777
|
+
generation_result = self._fix_unmerged_blocks(
|
|
778
|
+
query, generation_result, source_code_list)
|
|
807
779
|
|
|
808
780
|
# 修复lint错误
|
|
809
|
-
generation_result = self._fix_lint_errors(
|
|
810
|
-
|
|
781
|
+
generation_result = self._fix_lint_errors(
|
|
782
|
+
query, generation_result, source_code_list)
|
|
783
|
+
|
|
811
784
|
# 修复编译错误
|
|
812
|
-
generation_result = self._fix_compile_errors(
|
|
785
|
+
generation_result = self._fix_compile_errors(
|
|
786
|
+
query, generation_result, source_code_list)
|
|
813
787
|
|
|
814
|
-
#
|
|
815
|
-
self.shadow_manager.clean_shadows()
|
|
788
|
+
# self.shadow_manager.clean_shadows()
|
|
816
789
|
|
|
817
790
|
# 返回最终结果
|
|
818
791
|
return generation_result
|
|
@@ -21,6 +21,7 @@ from autocoder.compilers.models import (
|
|
|
21
21
|
CompilationErrorSeverity
|
|
22
22
|
)
|
|
23
23
|
from autocoder.utils.project_structure import EnhancedFileAnalyzer
|
|
24
|
+
from loguru import logger
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class ProvidedCompiler(BaseCompiler):
|
|
@@ -307,12 +308,12 @@ class ProvidedCompiler(BaseCompiler):
|
|
|
307
308
|
result.error_message = f"Compiler {target_compiler_name} not found in configuration"
|
|
308
309
|
return result
|
|
309
310
|
|
|
310
|
-
|
|
311
|
-
print(f"Running compiler: {target_compiler_name}")
|
|
311
|
+
logger.info(f"Using compiler to compile project({project_path}): {target_compiler_config.get('name','unknown')}")
|
|
312
312
|
|
|
313
313
|
# Run the compilation command
|
|
314
314
|
compile_result = self._run_compilation_command(project_path, target_compiler_config)
|
|
315
315
|
compile_errors:List[CompilationError] = compile_result['errors']
|
|
316
|
+
# logger.info(f"compile_result: {compile_result}")
|
|
316
317
|
error_count = len(compile_errors)
|
|
317
318
|
|
|
318
319
|
result = ProjectCompilationResult(
|
|
@@ -62,7 +62,7 @@ class EventManager:
|
|
|
62
62
|
self.event_store.append_event(event)
|
|
63
63
|
return event
|
|
64
64
|
|
|
65
|
-
def write_completion(self, content: Union[Dict[str, Any], Any]) -> Event:
|
|
65
|
+
def write_completion(self, content: Union[Dict[str, Any], Any], metadata: Dict[str, Any] = {}) -> Event:
|
|
66
66
|
"""
|
|
67
67
|
Write a completion event.
|
|
68
68
|
|
|
@@ -74,11 +74,11 @@ class EventManager:
|
|
|
74
74
|
"""
|
|
75
75
|
if not isinstance(content, dict):
|
|
76
76
|
content = content.to_dict()
|
|
77
|
-
event = Event(event_type=EventType.COMPLETION, content=content)
|
|
77
|
+
event = Event(event_type=EventType.COMPLETION, content=content, metadata=metadata)
|
|
78
78
|
self.event_store.append_event(event)
|
|
79
79
|
return event
|
|
80
80
|
|
|
81
|
-
def write_error(self, content: Union[Dict[str, Any], Any]) -> Event:
|
|
81
|
+
def write_error(self, content: Union[Dict[str, Any], Any], metadata: Dict[str, Any] = {}) -> Event:
|
|
82
82
|
"""
|
|
83
83
|
Write an error event.
|
|
84
84
|
|
|
@@ -90,7 +90,7 @@ class EventManager:
|
|
|
90
90
|
"""
|
|
91
91
|
if not isinstance(content, dict):
|
|
92
92
|
content = content.to_dict()
|
|
93
|
-
event = Event(event_type=EventType.ERROR, content=content)
|
|
93
|
+
event = Event(event_type=EventType.ERROR, content=content, metadata=metadata)
|
|
94
94
|
self.event_store.append_event(event)
|
|
95
95
|
return event
|
|
96
96
|
|
autocoder/events/event_types.py
CHANGED
|
@@ -68,6 +68,7 @@ class EventMetadata(BaseModel):
|
|
|
68
68
|
stream_out_type: str = field(default="") # 标记,比如当前这个流式是用于什么场景的,比如用于产生命令的还是啥
|
|
69
69
|
is_streaming: bool = field(default=False) # 是否是流式输出
|
|
70
70
|
output: str = field(default="") # result or delta, 在流式里,我们也可能会输出 ResultContent 类型
|
|
71
|
+
path: str = field(default="") # 唯一路径,比如 /agent/edit/tool/call
|
|
71
72
|
|
|
72
73
|
def to_dict(self) -> Dict[str, Any]:
|
|
73
74
|
"""Convert event metadata to dictionary for serialization"""
|