jarvis-ai-assistant 0.7.16__py3-none-any.whl → 1.0.2__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +567 -222
- jarvis/jarvis_agent/agent_manager.py +19 -12
- jarvis/jarvis_agent/builtin_input_handler.py +79 -11
- jarvis/jarvis_agent/config_editor.py +7 -2
- jarvis/jarvis_agent/event_bus.py +24 -13
- jarvis/jarvis_agent/events.py +19 -1
- jarvis/jarvis_agent/file_context_handler.py +67 -64
- jarvis/jarvis_agent/file_methodology_manager.py +38 -24
- jarvis/jarvis_agent/jarvis.py +186 -114
- jarvis/jarvis_agent/language_extractors/__init__.py +8 -1
- jarvis/jarvis_agent/language_extractors/c_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/cpp_extractor.py +9 -4
- jarvis/jarvis_agent/language_extractors/go_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/java_extractor.py +27 -20
- jarvis/jarvis_agent/language_extractors/javascript_extractor.py +22 -17
- jarvis/jarvis_agent/language_extractors/python_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/rust_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/typescript_extractor.py +22 -17
- jarvis/jarvis_agent/language_support_info.py +250 -219
- jarvis/jarvis_agent/main.py +19 -23
- jarvis/jarvis_agent/memory_manager.py +9 -6
- jarvis/jarvis_agent/methodology_share_manager.py +21 -15
- jarvis/jarvis_agent/output_handler.py +4 -2
- jarvis/jarvis_agent/prompt_builder.py +7 -6
- jarvis/jarvis_agent/prompt_manager.py +113 -8
- jarvis/jarvis_agent/prompts.py +317 -85
- jarvis/jarvis_agent/protocols.py +5 -2
- jarvis/jarvis_agent/run_loop.py +192 -32
- jarvis/jarvis_agent/session_manager.py +7 -3
- jarvis/jarvis_agent/share_manager.py +23 -13
- jarvis/jarvis_agent/shell_input_handler.py +12 -8
- jarvis/jarvis_agent/stdio_redirect.py +25 -26
- jarvis/jarvis_agent/task_analyzer.py +29 -23
- jarvis/jarvis_agent/task_list.py +869 -0
- jarvis/jarvis_agent/task_manager.py +26 -23
- jarvis/jarvis_agent/tool_executor.py +6 -5
- jarvis/jarvis_agent/tool_share_manager.py +24 -14
- jarvis/jarvis_agent/user_interaction.py +3 -3
- jarvis/jarvis_agent/utils.py +9 -1
- jarvis/jarvis_agent/web_bridge.py +37 -17
- jarvis/jarvis_agent/web_output_sink.py +5 -2
- jarvis/jarvis_agent/web_server.py +165 -36
- jarvis/jarvis_c2rust/__init__.py +1 -1
- jarvis/jarvis_c2rust/cli.py +260 -141
- jarvis/jarvis_c2rust/collector.py +37 -18
- jarvis/jarvis_c2rust/constants.py +60 -0
- jarvis/jarvis_c2rust/library_replacer.py +242 -1010
- jarvis/jarvis_c2rust/library_replacer_checkpoint.py +133 -0
- jarvis/jarvis_c2rust/library_replacer_llm.py +287 -0
- jarvis/jarvis_c2rust/library_replacer_loader.py +191 -0
- jarvis/jarvis_c2rust/library_replacer_output.py +134 -0
- jarvis/jarvis_c2rust/library_replacer_prompts.py +124 -0
- jarvis/jarvis_c2rust/library_replacer_utils.py +188 -0
- jarvis/jarvis_c2rust/llm_module_agent.py +98 -1044
- jarvis/jarvis_c2rust/llm_module_agent_apply.py +170 -0
- jarvis/jarvis_c2rust/llm_module_agent_executor.py +288 -0
- jarvis/jarvis_c2rust/llm_module_agent_loader.py +170 -0
- jarvis/jarvis_c2rust/llm_module_agent_prompts.py +268 -0
- jarvis/jarvis_c2rust/llm_module_agent_types.py +57 -0
- jarvis/jarvis_c2rust/llm_module_agent_utils.py +150 -0
- jarvis/jarvis_c2rust/llm_module_agent_validator.py +119 -0
- jarvis/jarvis_c2rust/loaders.py +28 -10
- jarvis/jarvis_c2rust/models.py +5 -2
- jarvis/jarvis_c2rust/optimizer.py +192 -1974
- jarvis/jarvis_c2rust/optimizer_build_fix.py +286 -0
- jarvis/jarvis_c2rust/optimizer_clippy.py +766 -0
- jarvis/jarvis_c2rust/optimizer_config.py +49 -0
- jarvis/jarvis_c2rust/optimizer_docs.py +183 -0
- jarvis/jarvis_c2rust/optimizer_options.py +48 -0
- jarvis/jarvis_c2rust/optimizer_progress.py +469 -0
- jarvis/jarvis_c2rust/optimizer_report.py +52 -0
- jarvis/jarvis_c2rust/optimizer_unsafe.py +309 -0
- jarvis/jarvis_c2rust/optimizer_utils.py +469 -0
- jarvis/jarvis_c2rust/optimizer_visibility.py +185 -0
- jarvis/jarvis_c2rust/scanner.py +229 -166
- jarvis/jarvis_c2rust/transpiler.py +531 -2732
- jarvis/jarvis_c2rust/transpiler_agents.py +503 -0
- jarvis/jarvis_c2rust/transpiler_build.py +1294 -0
- jarvis/jarvis_c2rust/transpiler_codegen.py +204 -0
- jarvis/jarvis_c2rust/transpiler_compile.py +146 -0
- jarvis/jarvis_c2rust/transpiler_config.py +178 -0
- jarvis/jarvis_c2rust/transpiler_context.py +122 -0
- jarvis/jarvis_c2rust/transpiler_executor.py +516 -0
- jarvis/jarvis_c2rust/transpiler_generation.py +278 -0
- jarvis/jarvis_c2rust/transpiler_git.py +163 -0
- jarvis/jarvis_c2rust/transpiler_mod_utils.py +225 -0
- jarvis/jarvis_c2rust/transpiler_modules.py +336 -0
- jarvis/jarvis_c2rust/transpiler_planning.py +394 -0
- jarvis/jarvis_c2rust/transpiler_review.py +1196 -0
- jarvis/jarvis_c2rust/transpiler_symbols.py +176 -0
- jarvis/jarvis_c2rust/utils.py +269 -79
- jarvis/jarvis_code_agent/after_change.py +233 -0
- jarvis/jarvis_code_agent/build_validation_config.py +37 -30
- jarvis/jarvis_code_agent/builtin_rules.py +68 -0
- jarvis/jarvis_code_agent/code_agent.py +976 -1517
- jarvis/jarvis_code_agent/code_agent_build.py +227 -0
- jarvis/jarvis_code_agent/code_agent_diff.py +246 -0
- jarvis/jarvis_code_agent/code_agent_git.py +525 -0
- jarvis/jarvis_code_agent/code_agent_impact.py +177 -0
- jarvis/jarvis_code_agent/code_agent_lint.py +283 -0
- jarvis/jarvis_code_agent/code_agent_llm.py +159 -0
- jarvis/jarvis_code_agent/code_agent_postprocess.py +105 -0
- jarvis/jarvis_code_agent/code_agent_prompts.py +46 -0
- jarvis/jarvis_code_agent/code_agent_rules.py +305 -0
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +52 -48
- jarvis/jarvis_code_agent/code_analyzer/base_language.py +12 -10
- jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +12 -11
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +16 -12
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +26 -17
- jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +558 -104
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +27 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +22 -18
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +21 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +20 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +27 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +47 -23
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +71 -37
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +162 -35
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +111 -57
- jarvis/jarvis_code_agent/code_analyzer/build_validator.py +18 -12
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +185 -183
- jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +2 -1
- jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +24 -15
- jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +227 -141
- jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +321 -247
- jarvis/jarvis_code_agent/code_analyzer/language_registry.py +37 -29
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -13
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +15 -9
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +75 -45
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +87 -52
- jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +84 -51
- jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +94 -64
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +109 -71
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +97 -63
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +103 -69
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +271 -268
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +76 -64
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +92 -19
- jarvis/jarvis_code_agent/diff_visualizer.py +998 -0
- jarvis/jarvis_code_agent/lint.py +223 -524
- jarvis/jarvis_code_agent/rule_share_manager.py +158 -0
- jarvis/jarvis_code_agent/rules/clean_code.md +144 -0
- jarvis/jarvis_code_agent/rules/code_review.md +115 -0
- jarvis/jarvis_code_agent/rules/documentation.md +165 -0
- jarvis/jarvis_code_agent/rules/generate_rules.md +52 -0
- jarvis/jarvis_code_agent/rules/performance.md +158 -0
- jarvis/jarvis_code_agent/rules/refactoring.md +139 -0
- jarvis/jarvis_code_agent/rules/security.md +160 -0
- jarvis/jarvis_code_agent/rules/tdd.md +78 -0
- jarvis/jarvis_code_agent/test_rules/cpp_test.md +118 -0
- jarvis/jarvis_code_agent/test_rules/go_test.md +98 -0
- jarvis/jarvis_code_agent/test_rules/java_test.md +99 -0
- jarvis/jarvis_code_agent/test_rules/javascript_test.md +113 -0
- jarvis/jarvis_code_agent/test_rules/php_test.md +117 -0
- jarvis/jarvis_code_agent/test_rules/python_test.md +91 -0
- jarvis/jarvis_code_agent/test_rules/ruby_test.md +102 -0
- jarvis/jarvis_code_agent/test_rules/rust_test.md +86 -0
- jarvis/jarvis_code_agent/utils.py +36 -26
- jarvis/jarvis_code_analysis/checklists/loader.py +21 -21
- jarvis/jarvis_code_analysis/code_review.py +64 -33
- jarvis/jarvis_data/config_schema.json +285 -192
- jarvis/jarvis_git_squash/main.py +8 -6
- jarvis/jarvis_git_utils/git_commiter.py +53 -76
- jarvis/jarvis_mcp/__init__.py +5 -2
- jarvis/jarvis_mcp/sse_mcp_client.py +40 -30
- jarvis/jarvis_mcp/stdio_mcp_client.py +27 -19
- jarvis/jarvis_mcp/streamable_mcp_client.py +35 -26
- jarvis/jarvis_memory_organizer/memory_organizer.py +78 -55
- jarvis/jarvis_methodology/main.py +48 -39
- jarvis/jarvis_multi_agent/__init__.py +56 -23
- jarvis/jarvis_multi_agent/main.py +15 -18
- jarvis/jarvis_platform/base.py +179 -111
- jarvis/jarvis_platform/human.py +27 -16
- jarvis/jarvis_platform/kimi.py +52 -45
- jarvis/jarvis_platform/openai.py +101 -40
- jarvis/jarvis_platform/registry.py +51 -33
- jarvis/jarvis_platform/tongyi.py +68 -38
- jarvis/jarvis_platform/yuanbao.py +59 -43
- jarvis/jarvis_platform_manager/main.py +68 -76
- jarvis/jarvis_platform_manager/service.py +24 -14
- jarvis/jarvis_rag/README_CONFIG.md +314 -0
- jarvis/jarvis_rag/README_DYNAMIC_LOADING.md +311 -0
- jarvis/jarvis_rag/README_ONLINE_MODELS.md +230 -0
- jarvis/jarvis_rag/__init__.py +57 -4
- jarvis/jarvis_rag/cache.py +3 -1
- jarvis/jarvis_rag/cli.py +48 -68
- jarvis/jarvis_rag/embedding_interface.py +39 -0
- jarvis/jarvis_rag/embedding_manager.py +7 -230
- jarvis/jarvis_rag/embeddings/__init__.py +41 -0
- jarvis/jarvis_rag/embeddings/base.py +114 -0
- jarvis/jarvis_rag/embeddings/cohere.py +66 -0
- jarvis/jarvis_rag/embeddings/edgefn.py +117 -0
- jarvis/jarvis_rag/embeddings/local.py +260 -0
- jarvis/jarvis_rag/embeddings/openai.py +62 -0
- jarvis/jarvis_rag/embeddings/registry.py +293 -0
- jarvis/jarvis_rag/llm_interface.py +8 -6
- jarvis/jarvis_rag/query_rewriter.py +8 -9
- jarvis/jarvis_rag/rag_pipeline.py +61 -52
- jarvis/jarvis_rag/reranker.py +7 -75
- jarvis/jarvis_rag/reranker_interface.py +32 -0
- jarvis/jarvis_rag/rerankers/__init__.py +41 -0
- jarvis/jarvis_rag/rerankers/base.py +109 -0
- jarvis/jarvis_rag/rerankers/cohere.py +67 -0
- jarvis/jarvis_rag/rerankers/edgefn.py +140 -0
- jarvis/jarvis_rag/rerankers/jina.py +79 -0
- jarvis/jarvis_rag/rerankers/local.py +89 -0
- jarvis/jarvis_rag/rerankers/registry.py +293 -0
- jarvis/jarvis_rag/retriever.py +58 -43
- jarvis/jarvis_sec/__init__.py +66 -141
- jarvis/jarvis_sec/agents.py +21 -17
- jarvis/jarvis_sec/analysis.py +80 -33
- jarvis/jarvis_sec/checkers/__init__.py +7 -13
- jarvis/jarvis_sec/checkers/c_checker.py +356 -164
- jarvis/jarvis_sec/checkers/rust_checker.py +47 -29
- jarvis/jarvis_sec/cli.py +43 -21
- jarvis/jarvis_sec/clustering.py +430 -272
- jarvis/jarvis_sec/file_manager.py +99 -55
- jarvis/jarvis_sec/parsers.py +9 -6
- jarvis/jarvis_sec/prompts.py +4 -3
- jarvis/jarvis_sec/report.py +44 -22
- jarvis/jarvis_sec/review.py +180 -107
- jarvis/jarvis_sec/status.py +50 -41
- jarvis/jarvis_sec/types.py +3 -0
- jarvis/jarvis_sec/utils.py +160 -83
- jarvis/jarvis_sec/verification.py +411 -181
- jarvis/jarvis_sec/workflow.py +132 -21
- jarvis/jarvis_smart_shell/main.py +28 -41
- jarvis/jarvis_stats/cli.py +14 -12
- jarvis/jarvis_stats/stats.py +28 -19
- jarvis/jarvis_stats/storage.py +14 -8
- jarvis/jarvis_stats/visualizer.py +12 -7
- jarvis/jarvis_tools/base.py +5 -2
- jarvis/jarvis_tools/clear_memory.py +13 -9
- jarvis/jarvis_tools/cli/main.py +23 -18
- jarvis/jarvis_tools/edit_file.py +572 -873
- jarvis/jarvis_tools/execute_script.py +10 -7
- jarvis/jarvis_tools/file_analyzer.py +7 -8
- jarvis/jarvis_tools/meta_agent.py +287 -0
- jarvis/jarvis_tools/methodology.py +5 -3
- jarvis/jarvis_tools/read_code.py +305 -1438
- jarvis/jarvis_tools/read_symbols.py +50 -17
- jarvis/jarvis_tools/read_webpage.py +19 -18
- jarvis/jarvis_tools/registry.py +435 -156
- jarvis/jarvis_tools/retrieve_memory.py +16 -11
- jarvis/jarvis_tools/save_memory.py +8 -6
- jarvis/jarvis_tools/search_web.py +31 -31
- jarvis/jarvis_tools/sub_agent.py +32 -28
- jarvis/jarvis_tools/sub_code_agent.py +44 -60
- jarvis/jarvis_tools/task_list_manager.py +1811 -0
- jarvis/jarvis_tools/virtual_tty.py +29 -19
- jarvis/jarvis_utils/__init__.py +4 -0
- jarvis/jarvis_utils/builtin_replace_map.py +2 -1
- jarvis/jarvis_utils/clipboard.py +9 -8
- jarvis/jarvis_utils/collections.py +331 -0
- jarvis/jarvis_utils/config.py +699 -194
- jarvis/jarvis_utils/dialogue_recorder.py +294 -0
- jarvis/jarvis_utils/embedding.py +6 -3
- jarvis/jarvis_utils/file_processors.py +7 -1
- jarvis/jarvis_utils/fzf.py +9 -3
- jarvis/jarvis_utils/git_utils.py +71 -42
- jarvis/jarvis_utils/globals.py +116 -32
- jarvis/jarvis_utils/http.py +6 -2
- jarvis/jarvis_utils/input.py +318 -83
- jarvis/jarvis_utils/jsonnet_compat.py +119 -104
- jarvis/jarvis_utils/methodology.py +37 -28
- jarvis/jarvis_utils/output.py +201 -44
- jarvis/jarvis_utils/utils.py +986 -628
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/METADATA +49 -33
- jarvis_ai_assistant-1.0.2.dist-info/RECORD +304 -0
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +0 -556
- jarvis/jarvis_tools/generate_new_tool.py +0 -205
- jarvis/jarvis_tools/lsp_client.py +0 -1552
- jarvis/jarvis_tools/rewrite_file.py +0 -105
- jarvis_ai_assistant-0.7.16.dist-info/RECORD +0 -218
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Unsafe 清理优化模块。"""
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Callable
|
|
7
|
+
from typing import Dict
|
|
8
|
+
from typing import List
|
|
9
|
+
|
|
10
|
+
from jarvis.jarvis_utils.output import PrettyOutput
|
|
11
|
+
|
|
12
|
+
from jarvis.jarvis_agent.events import AFTER_TOOL_CALL
|
|
13
|
+
from jarvis.jarvis_agent.events import BEFORE_TOOL_CALL
|
|
14
|
+
from jarvis.jarvis_c2rust.optimizer_options import OptimizeOptions
|
|
15
|
+
from jarvis.jarvis_c2rust.optimizer_options import OptimizeStats
|
|
16
|
+
from jarvis.jarvis_c2rust.optimizer_progress import ProgressManager
|
|
17
|
+
from jarvis.jarvis_c2rust.optimizer_utils import cargo_check_full
|
|
18
|
+
from jarvis.jarvis_c2rust.optimizer_utils import check_missing_safety_doc_warnings
|
|
19
|
+
from jarvis.jarvis_c2rust.optimizer_utils import run_cargo_fmt
|
|
20
|
+
from jarvis.jarvis_code_agent.code_agent import CodeAgent
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class UnsafeOptimizer:
|
|
24
|
+
"""Unsafe 清理优化器。"""
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
crate_dir: Path,
|
|
29
|
+
options: OptimizeOptions,
|
|
30
|
+
stats: OptimizeStats,
|
|
31
|
+
progress_manager: ProgressManager,
|
|
32
|
+
append_additional_notes_func: Callable[[str], str],
|
|
33
|
+
extract_warnings_by_file_func: Callable[[str], Dict[str, List[Dict]]],
|
|
34
|
+
format_warnings_for_prompt_func: Callable[[List[Dict], int], str],
|
|
35
|
+
):
|
|
36
|
+
self.crate_dir = crate_dir
|
|
37
|
+
self.options = options
|
|
38
|
+
self.stats = stats
|
|
39
|
+
self.progress_manager = progress_manager
|
|
40
|
+
self.append_additional_notes = append_additional_notes_func
|
|
41
|
+
self.extract_warnings_by_file = extract_warnings_by_file_func
|
|
42
|
+
self.format_warnings_for_prompt = format_warnings_for_prompt_func
|
|
43
|
+
|
|
44
|
+
def codeagent_opt_unsafe_cleanup(self, target_files: List[Path]) -> None:
|
|
45
|
+
"""
|
|
46
|
+
使用 CodeAgent 进行 unsafe 清理优化。
|
|
47
|
+
使用 clippy 的 missing_safety_doc checker 来查找 unsafe 告警,按文件处理,每次处理一个文件的所有告警。
|
|
48
|
+
|
|
49
|
+
注意:CodeAgent 必须在 crate 目录下创建和执行,以确保所有文件操作和命令执行都在正确的上下文中进行。
|
|
50
|
+
"""
|
|
51
|
+
crate = self.crate_dir.resolve()
|
|
52
|
+
file_list: List[str] = []
|
|
53
|
+
for p in target_files:
|
|
54
|
+
try:
|
|
55
|
+
rel = p.resolve().relative_to(crate).as_posix()
|
|
56
|
+
except Exception:
|
|
57
|
+
rel = p.as_posix()
|
|
58
|
+
file_list.append(rel)
|
|
59
|
+
self.stats.files_scanned += 1
|
|
60
|
+
|
|
61
|
+
# 切换到 crate 目录,确保 CodeAgent 在正确的上下文中创建和执行
|
|
62
|
+
prev_cwd = os.getcwd()
|
|
63
|
+
iteration = 0
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
os.chdir(str(crate))
|
|
67
|
+
|
|
68
|
+
# 循环修复 unsafe 告警,按文件处理
|
|
69
|
+
while True:
|
|
70
|
+
iteration += 1
|
|
71
|
+
|
|
72
|
+
# 检查当前 missing_safety_doc 告警
|
|
73
|
+
has_warnings, current_clippy_output = check_missing_safety_doc_warnings(
|
|
74
|
+
crate
|
|
75
|
+
)
|
|
76
|
+
if not has_warnings:
|
|
77
|
+
PrettyOutput.auto_print(
|
|
78
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 所有 missing_safety_doc 告警已消除(共迭代 {iteration - 1} 次)"
|
|
79
|
+
)
|
|
80
|
+
return # 所有告警已消除
|
|
81
|
+
|
|
82
|
+
# 按文件提取告警
|
|
83
|
+
warnings_by_file = self.extract_warnings_by_file(current_clippy_output)
|
|
84
|
+
if not warnings_by_file:
|
|
85
|
+
PrettyOutput.auto_print(
|
|
86
|
+
"[c2rust-optimizer][codeagent][unsafe-cleanup] 无法提取告警,停止修复"
|
|
87
|
+
)
|
|
88
|
+
return # 仍有告警未消除
|
|
89
|
+
|
|
90
|
+
# 找到第一个有告警的文件(优先处理目标文件列表中的文件)
|
|
91
|
+
target_file_path = None
|
|
92
|
+
target_warnings = None
|
|
93
|
+
|
|
94
|
+
# 优先处理目标文件列表中的文件
|
|
95
|
+
for file_rel in file_list:
|
|
96
|
+
# 尝试匹配文件路径(可能是相对路径或绝对路径)
|
|
97
|
+
for file_path, warnings in warnings_by_file.items():
|
|
98
|
+
if file_rel in file_path or file_path.endswith(file_rel):
|
|
99
|
+
target_file_path = file_path
|
|
100
|
+
target_warnings = warnings
|
|
101
|
+
break
|
|
102
|
+
if target_file_path:
|
|
103
|
+
break
|
|
104
|
+
|
|
105
|
+
# 如果目标文件列表中没有告警,选择第一个有告警的文件
|
|
106
|
+
if not target_file_path:
|
|
107
|
+
target_file_path = next(iter(warnings_by_file.keys()))
|
|
108
|
+
target_warnings = warnings_by_file[target_file_path]
|
|
109
|
+
|
|
110
|
+
# 获取该文件的所有告警(一次处理一个文件的所有告警)
|
|
111
|
+
warnings_to_fix = target_warnings
|
|
112
|
+
warning_count = (
|
|
113
|
+
len(warnings_to_fix) if warnings_to_fix is not None else 0
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
PrettyOutput.auto_print(
|
|
117
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 第 {iteration} 次迭代:修复文件 {target_file_path} 的 {warning_count} 个 missing_safety_doc 告警"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# 格式化告警信息
|
|
121
|
+
formatted_warnings = self.format_warnings_for_prompt(
|
|
122
|
+
warnings_to_fix or [], warning_count
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# 构建提示词,修复该文件的所有 missing_safety_doc 告警
|
|
126
|
+
prompt_lines: List[str] = [
|
|
127
|
+
"你是资深 Rust 代码工程师。请在当前 crate 下修复指定文件中的 missing_safety_doc 告警,并以补丁形式输出修改:",
|
|
128
|
+
f"- crate 根目录:{crate}",
|
|
129
|
+
"",
|
|
130
|
+
"本次优化仅允许修改以下文件(严格限制,只处理这一个文件):",
|
|
131
|
+
f"- {target_file_path}",
|
|
132
|
+
"",
|
|
133
|
+
f"重要:本次修复仅修复该文件中的 {warning_count} 个 missing_safety_doc 告警。",
|
|
134
|
+
"",
|
|
135
|
+
"优化目标:",
|
|
136
|
+
f"1) 修复文件 {target_file_path} 中的 {warning_count} 个 missing_safety_doc 告警:",
|
|
137
|
+
" **修复原则:能消除就消除,不能消除才增加 SAFETY 注释**",
|
|
138
|
+
"",
|
|
139
|
+
" 优先级 1(优先尝试):消除 unsafe",
|
|
140
|
+
" - 如果 unsafe 函数或方法实际上不需要是 unsafe 的,应该移除 unsafe 关键字;",
|
|
141
|
+
" - 如果 unsafe 块可以移除,应该移除整个 unsafe 块;",
|
|
142
|
+
" - 如果 unsafe 块可以缩小范围,应该缩小范围;",
|
|
143
|
+
" - 仔细分析代码,判断是否真的需要 unsafe,如果可以通过安全的方式实现,优先使用安全的方式。",
|
|
144
|
+
"",
|
|
145
|
+
" 优先级 2(无法消除时):添加 SAFETY 注释",
|
|
146
|
+
" - 只有在确认无法消除 unsafe 的情况下,才为 unsafe 函数或方法添加 `/// SAFETY: ...` 文档注释;",
|
|
147
|
+
" - SAFETY 注释必须详细说明为什么该函数或方法是 unsafe 的,包括:",
|
|
148
|
+
" * 哪些不变量必须由调用者维护;",
|
|
149
|
+
" * 哪些前提条件必须满足;",
|
|
150
|
+
" * 可能导致未定义行为的情况;",
|
|
151
|
+
" * 为什么不能使用安全的替代方案;",
|
|
152
|
+
" - 如果 unsafe 块无法移除但可以缩小范围,应该缩小范围并在紧邻位置添加 `/// SAFETY: ...` 注释。",
|
|
153
|
+
"",
|
|
154
|
+
"2) 修复已有实现的问题:",
|
|
155
|
+
" - 如果在修复 missing_safety_doc 告警的过程中,发现代码已有的实现有问题(如逻辑错误、潜在 bug、性能问题、内存安全问题等),也需要一并修复;",
|
|
156
|
+
" - 这些问题可能包括但不限于:不正确的 unsafe 使用、未检查的边界条件、资源泄漏、竞态条件、数据竞争等;",
|
|
157
|
+
" - 修复时应该保持最小改动原则,优先修复最严重的问题。",
|
|
158
|
+
"",
|
|
159
|
+
"约束与范围:",
|
|
160
|
+
f"- **仅修改文件 {target_file_path},不要修改其他文件**;除非必须(如修复引用路径),否则不要修改其他文件。",
|
|
161
|
+
"- 保持最小改动,不要进行与修复 missing_safety_doc 告警无关的重构或格式化。",
|
|
162
|
+
f"- **只修复该文件中的 {warning_count} 个 missing_safety_doc 告警,不要修复其他告警**。",
|
|
163
|
+
"- 修改后需保证 `cargo test` 可以通过;如需引入少量配套改动,请一并包含在补丁中以确保通过。",
|
|
164
|
+
"- 输出仅为补丁,不要输出解释或多余文本。",
|
|
165
|
+
"",
|
|
166
|
+
"优先级说明:",
|
|
167
|
+
"- **修复 unsafe 的优先级:能消除就消除,不能消除才增加 SAFETY 注释**;",
|
|
168
|
+
"- 对于每个 unsafe,首先尝试分析是否可以安全地移除,只有在确认无法移除时才添加 SAFETY 注释;",
|
|
169
|
+
"- **如果优化过程中出现了测试不通过或编译错误,必须优先解决这些问题**;",
|
|
170
|
+
"- 在修复告警之前,先确保代码能够正常编译和通过测试;",
|
|
171
|
+
"- 如果修复告警导致了编译错误或测试失败,必须立即修复这些错误,然后再继续优化。",
|
|
172
|
+
"",
|
|
173
|
+
"自检要求:在每次输出补丁后,请使用 execute_script 工具在 crate 根目录执行 `cargo test -q` 进行验证;",
|
|
174
|
+
"若出现编译错误或测试失败,请优先修复这些问题,然后再继续修复告警;",
|
|
175
|
+
"若未通过,请继续输出新的补丁进行最小修复并再次自检,直至 `cargo test` 通过为止。",
|
|
176
|
+
"",
|
|
177
|
+
f"文件 {target_file_path} 中的 missing_safety_doc 告警信息如下:",
|
|
178
|
+
"<WARNINGS>",
|
|
179
|
+
formatted_warnings,
|
|
180
|
+
"</WARNINGS>",
|
|
181
|
+
]
|
|
182
|
+
prompt = "\n".join(prompt_lines)
|
|
183
|
+
prompt = self.append_additional_notes(prompt)
|
|
184
|
+
|
|
185
|
+
# 修复前执行 cargo fmt
|
|
186
|
+
run_cargo_fmt(crate)
|
|
187
|
+
|
|
188
|
+
# 记录运行前的 commit id
|
|
189
|
+
commit_before = self.progress_manager.get_crate_commit_hash()
|
|
190
|
+
|
|
191
|
+
# CodeAgent 在 crate 目录下创建和执行
|
|
192
|
+
agent = CodeAgent(
|
|
193
|
+
name=f"UnsafeCleanupAgent-iter{iteration}",
|
|
194
|
+
need_summary=False,
|
|
195
|
+
non_interactive=self.options.non_interactive,
|
|
196
|
+
model_group=self.options.llm_group,
|
|
197
|
+
enable_task_list_manager=False,
|
|
198
|
+
disable_review=True,
|
|
199
|
+
)
|
|
200
|
+
# 订阅 BEFORE_TOOL_CALL 和 AFTER_TOOL_CALL 事件,用于细粒度检测测试代码删除
|
|
201
|
+
agent.event_bus.subscribe(
|
|
202
|
+
BEFORE_TOOL_CALL, self.progress_manager.on_before_tool_call
|
|
203
|
+
)
|
|
204
|
+
agent.event_bus.subscribe(
|
|
205
|
+
AFTER_TOOL_CALL, self.progress_manager.on_after_tool_call
|
|
206
|
+
)
|
|
207
|
+
# 记录 Agent 创建时的 commit id(作为初始值)
|
|
208
|
+
agent_id = id(agent)
|
|
209
|
+
agent_key = f"agent_{agent_id}"
|
|
210
|
+
initial_commit = self.progress_manager.get_crate_commit_hash()
|
|
211
|
+
if initial_commit:
|
|
212
|
+
self.progress_manager._agent_before_commits[agent_key] = (
|
|
213
|
+
initial_commit
|
|
214
|
+
)
|
|
215
|
+
agent.run(
|
|
216
|
+
prompt,
|
|
217
|
+
prefix=f"[c2rust-optimizer][codeagent][unsafe-cleanup][iter{iteration}]",
|
|
218
|
+
suffix="",
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# 检测并处理测试代码删除
|
|
222
|
+
if self.progress_manager.check_and_handle_test_deletion(
|
|
223
|
+
commit_before, agent
|
|
224
|
+
):
|
|
225
|
+
# 如果回退了,需要重新运行 agent
|
|
226
|
+
PrettyOutput.auto_print(
|
|
227
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 检测到测试代码删除问题,已回退,重新运行 agent (iter={iteration})"
|
|
228
|
+
)
|
|
229
|
+
commit_before = self.progress_manager.get_crate_commit_hash()
|
|
230
|
+
agent.run(
|
|
231
|
+
prompt,
|
|
232
|
+
prefix=f"[c2rust-optimizer][codeagent][unsafe-cleanup][iter{iteration}][retry]",
|
|
233
|
+
suffix="",
|
|
234
|
+
)
|
|
235
|
+
# 再次检测
|
|
236
|
+
if self.progress_manager.check_and_handle_test_deletion(
|
|
237
|
+
commit_before, agent
|
|
238
|
+
):
|
|
239
|
+
PrettyOutput.auto_print(
|
|
240
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 再次检测到测试代码删除问题,已回退 (iter={iteration})"
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# 验证修复是否成功(通过 cargo test)
|
|
244
|
+
ok, _ = cargo_check_full(
|
|
245
|
+
crate,
|
|
246
|
+
self.stats,
|
|
247
|
+
self.options.max_checks,
|
|
248
|
+
timeout=self.options.cargo_test_timeout,
|
|
249
|
+
)
|
|
250
|
+
if ok:
|
|
251
|
+
# 修复成功,保存进度和 commit id
|
|
252
|
+
try:
|
|
253
|
+
# 确保 target_file_path 是 Path 对象
|
|
254
|
+
target_file_path_obj = Path(target_file_path)
|
|
255
|
+
file_path_to_save: Path = (
|
|
256
|
+
crate / target_file_path_obj
|
|
257
|
+
if not target_file_path_obj.is_absolute()
|
|
258
|
+
else target_file_path_obj
|
|
259
|
+
)
|
|
260
|
+
if file_path_to_save.exists():
|
|
261
|
+
self.progress_manager.save_fix_progress(
|
|
262
|
+
"unsafe_cleanup",
|
|
263
|
+
f"{target_file_path}-iter{iteration}",
|
|
264
|
+
[file_path_to_save],
|
|
265
|
+
)
|
|
266
|
+
else:
|
|
267
|
+
self.progress_manager.save_fix_progress(
|
|
268
|
+
"unsafe_cleanup",
|
|
269
|
+
f"{target_file_path}-iter{iteration}",
|
|
270
|
+
None,
|
|
271
|
+
)
|
|
272
|
+
except Exception:
|
|
273
|
+
self.progress_manager.save_fix_progress(
|
|
274
|
+
"unsafe_cleanup",
|
|
275
|
+
f"{target_file_path}-iter{iteration}",
|
|
276
|
+
None,
|
|
277
|
+
)
|
|
278
|
+
PrettyOutput.auto_print(
|
|
279
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 文件 {target_file_path} 的 {warning_count} 个告警修复成功,已保存进度"
|
|
280
|
+
)
|
|
281
|
+
else:
|
|
282
|
+
# 测试失败,回退到运行前的 commit
|
|
283
|
+
if commit_before:
|
|
284
|
+
PrettyOutput.auto_print(
|
|
285
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 文件 {target_file_path} 修复后测试失败,回退到运行前的 commit: {commit_before[:8]}"
|
|
286
|
+
)
|
|
287
|
+
if self.progress_manager.reset_to_commit(commit_before):
|
|
288
|
+
PrettyOutput.auto_print(
|
|
289
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 已成功回退到 commit: {commit_before[:8]}"
|
|
290
|
+
)
|
|
291
|
+
else:
|
|
292
|
+
PrettyOutput.auto_print(
|
|
293
|
+
"[c2rust-optimizer][codeagent][unsafe-cleanup] 回退失败,请手动检查代码状态"
|
|
294
|
+
)
|
|
295
|
+
else:
|
|
296
|
+
PrettyOutput.auto_print(
|
|
297
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 文件 {target_file_path} 修复后测试失败,但无法获取运行前的 commit,继续修复"
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
# 修复后再次检查告警
|
|
301
|
+
has_warnings_after, _ = check_missing_safety_doc_warnings(crate)
|
|
302
|
+
if not has_warnings_after:
|
|
303
|
+
PrettyOutput.auto_print(
|
|
304
|
+
f"[c2rust-optimizer][codeagent][unsafe-cleanup] 所有 missing_safety_doc 告警已消除(共迭代 {iteration} 次)"
|
|
305
|
+
)
|
|
306
|
+
return # 所有告警已消除
|
|
307
|
+
|
|
308
|
+
finally:
|
|
309
|
+
os.chdir(prev_cwd)
|