jarvis-ai-assistant 0.1.134__py3-none-any.whl → 0.1.138__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 jarvis-ai-assistant might be problematic. Click here for more details.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +201 -79
- jarvis/jarvis_agent/builtin_input_handler.py +16 -6
- jarvis/jarvis_agent/file_input_handler.py +9 -9
- jarvis/jarvis_agent/jarvis.py +10 -10
- jarvis/jarvis_agent/main.py +12 -11
- jarvis/jarvis_agent/output_handler.py +3 -3
- jarvis/jarvis_agent/patch.py +86 -62
- jarvis/jarvis_agent/shell_input_handler.py +5 -3
- jarvis/jarvis_code_agent/code_agent.py +134 -99
- jarvis/jarvis_code_agent/file_select.py +24 -24
- jarvis/jarvis_dev/main.py +45 -51
- jarvis/jarvis_git_details/__init__.py +0 -0
- jarvis/jarvis_git_details/main.py +179 -0
- jarvis/jarvis_git_squash/main.py +7 -7
- jarvis/jarvis_lsp/base.py +11 -11
- jarvis/jarvis_lsp/cpp.py +14 -14
- jarvis/jarvis_lsp/go.py +13 -13
- jarvis/jarvis_lsp/python.py +8 -8
- jarvis/jarvis_lsp/registry.py +21 -21
- jarvis/jarvis_lsp/rust.py +15 -15
- jarvis/jarvis_methodology/main.py +101 -0
- jarvis/jarvis_multi_agent/__init__.py +11 -11
- jarvis/jarvis_multi_agent/main.py +6 -6
- jarvis/jarvis_platform/__init__.py +1 -1
- jarvis/jarvis_platform/ai8.py +67 -89
- jarvis/jarvis_platform/base.py +14 -13
- jarvis/jarvis_platform/kimi.py +25 -28
- jarvis/jarvis_platform/ollama.py +24 -26
- jarvis/jarvis_platform/openai.py +15 -19
- jarvis/jarvis_platform/oyi.py +48 -50
- jarvis/jarvis_platform/registry.py +27 -28
- jarvis/jarvis_platform/yuanbao.py +38 -42
- jarvis/jarvis_platform_manager/main.py +81 -81
- jarvis/jarvis_platform_manager/openai_test.py +21 -21
- jarvis/jarvis_rag/file_processors.py +18 -18
- jarvis/jarvis_rag/main.py +261 -277
- jarvis/jarvis_smart_shell/main.py +12 -12
- jarvis/jarvis_tools/ask_codebase.py +28 -28
- jarvis/jarvis_tools/ask_user.py +8 -8
- jarvis/jarvis_tools/base.py +4 -4
- jarvis/jarvis_tools/chdir.py +9 -9
- jarvis/jarvis_tools/code_review.py +19 -19
- jarvis/jarvis_tools/create_code_agent.py +15 -15
- jarvis/jarvis_tools/execute_python_script.py +3 -3
- jarvis/jarvis_tools/execute_shell.py +11 -11
- jarvis/jarvis_tools/execute_shell_script.py +3 -3
- jarvis/jarvis_tools/file_analyzer.py +29 -29
- jarvis/jarvis_tools/file_operation.py +22 -20
- jarvis/jarvis_tools/find_caller.py +25 -25
- jarvis/jarvis_tools/find_methodolopy.py +65 -0
- jarvis/jarvis_tools/find_symbol.py +24 -24
- jarvis/jarvis_tools/function_analyzer.py +27 -27
- jarvis/jarvis_tools/git_commiter.py +9 -9
- jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -19
- jarvis/jarvis_tools/methodology.py +23 -62
- jarvis/jarvis_tools/project_analyzer.py +29 -33
- jarvis/jarvis_tools/rag.py +15 -15
- jarvis/jarvis_tools/read_code.py +24 -22
- jarvis/jarvis_tools/read_webpage.py +31 -31
- jarvis/jarvis_tools/registry.py +72 -52
- jarvis/jarvis_tools/tool_generator.py +18 -18
- jarvis/jarvis_utils/config.py +23 -23
- jarvis/jarvis_utils/embedding.py +83 -83
- jarvis/jarvis_utils/git_utils.py +20 -20
- jarvis/jarvis_utils/globals.py +18 -6
- jarvis/jarvis_utils/input.py +10 -9
- jarvis/jarvis_utils/methodology.py +140 -136
- jarvis/jarvis_utils/output.py +11 -11
- jarvis/jarvis_utils/utils.py +22 -70
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/METADATA +1 -1
- jarvis_ai_assistant-0.1.138.dist-info/RECORD +85 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/entry_points.txt +2 -0
- jarvis/jarvis_tools/select_code_files.py +0 -62
- jarvis_ai_assistant-0.1.134.dist-info/RECORD +0 -82
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/top_level.txt +0 -0
jarvis/jarvis_dev/main.py
CHANGED
|
@@ -67,20 +67,20 @@ PM_PROMPT = f"""
|
|
|
67
67
|
to: [角色]
|
|
68
68
|
content: |
|
|
69
69
|
# [任务主题]
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
## 背景与目标
|
|
72
72
|
[提供任务背景和期望达成的目标]
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
## 相关代码
|
|
75
75
|
- [代码路径及其分析结果]
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
## 具体要求
|
|
78
78
|
1. [基于代码事实的明确要求1]
|
|
79
79
|
2. [基于代码事实的明确要求2]
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
## 预期交付物
|
|
82
82
|
- [具体交付物及其格式要求]
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
## 时间与优先级
|
|
85
85
|
- 优先级:[高/中/低]
|
|
86
86
|
- 期望完成时间:[时间点]
|
|
@@ -295,7 +295,7 @@ arguments:
|
|
|
295
295
|
- [详细功能描述]
|
|
296
296
|
- [输入/输出规范]
|
|
297
297
|
- [错误处理要求]
|
|
298
|
-
|
|
298
|
+
|
|
299
299
|
技术要求:
|
|
300
300
|
- [编程语言/框架]
|
|
301
301
|
- [代码风格]
|
|
@@ -360,7 +360,7 @@ arguments:
|
|
|
360
360
|
- 测试正常功能路径
|
|
361
361
|
- 测试边界条件和异常情况
|
|
362
362
|
- 测试错误处理逻辑
|
|
363
|
-
|
|
363
|
+
|
|
364
364
|
技术要求:
|
|
365
365
|
- 使用[测试框架]
|
|
366
366
|
- 模拟外部依赖
|
|
@@ -381,10 +381,10 @@ def create_dev_team() -> MultiAgent:
|
|
|
381
381
|
|
|
382
382
|
PM_output_handler = ToolRegistry()
|
|
383
383
|
PM_output_handler.use_tools([
|
|
384
|
-
"ask_user",
|
|
385
|
-
"file_operation",
|
|
386
|
-
"search_web",
|
|
387
|
-
"rag",
|
|
384
|
+
"ask_user",
|
|
385
|
+
"file_operation",
|
|
386
|
+
"search_web",
|
|
387
|
+
"rag",
|
|
388
388
|
"execute_shell",
|
|
389
389
|
"read_webpage",
|
|
390
390
|
"project_analyzer",
|
|
@@ -394,37 +394,35 @@ def create_dev_team() -> MultiAgent:
|
|
|
394
394
|
|
|
395
395
|
BA_output_handler = ToolRegistry()
|
|
396
396
|
BA_output_handler.use_tools([
|
|
397
|
-
"ask_user",
|
|
398
|
-
"file_operation",
|
|
399
|
-
"search_web",
|
|
400
|
-
"rag",
|
|
397
|
+
"ask_user",
|
|
398
|
+
"file_operation",
|
|
399
|
+
"search_web",
|
|
400
|
+
"rag",
|
|
401
401
|
"execute_shell",
|
|
402
|
-
"read_webpage",
|
|
403
|
-
"select_code_files",
|
|
402
|
+
"read_webpage",
|
|
404
403
|
"methodology",
|
|
405
404
|
"ask_codebase"
|
|
406
405
|
])
|
|
407
406
|
|
|
408
407
|
SA_output_handler = ToolRegistry()
|
|
409
408
|
SA_output_handler.use_tools([
|
|
410
|
-
"file_operation",
|
|
411
|
-
"search_web",
|
|
412
|
-
"rag",
|
|
413
|
-
"ask_codebase",
|
|
409
|
+
"file_operation",
|
|
410
|
+
"search_web",
|
|
411
|
+
"rag",
|
|
412
|
+
"ask_codebase",
|
|
414
413
|
"execute_shell",
|
|
415
414
|
"project_analyzer",
|
|
416
415
|
"file_analyzer",
|
|
417
416
|
"function_analyzer",
|
|
418
417
|
"read_code",
|
|
419
|
-
"select_code_files",
|
|
420
418
|
"methodology"
|
|
421
419
|
])
|
|
422
|
-
|
|
420
|
+
|
|
423
421
|
TL_output_handler = ToolRegistry()
|
|
424
422
|
TL_output_handler.use_tools([
|
|
425
|
-
"file_operation",
|
|
426
|
-
"ask_codebase",
|
|
427
|
-
"lsp_get_diagnostics",
|
|
423
|
+
"file_operation",
|
|
424
|
+
"ask_codebase",
|
|
425
|
+
"lsp_get_diagnostics",
|
|
428
426
|
"execute_shell",
|
|
429
427
|
"code_review",
|
|
430
428
|
"find_symbol",
|
|
@@ -432,12 +430,12 @@ def create_dev_team() -> MultiAgent:
|
|
|
432
430
|
"function_analyzer",
|
|
433
431
|
"project_analyzer"
|
|
434
432
|
])
|
|
435
|
-
|
|
433
|
+
|
|
436
434
|
DEV_output_handler = ToolRegistry()
|
|
437
435
|
DEV_output_handler.use_tools([
|
|
438
|
-
"create_code_agent",
|
|
439
|
-
"file_operation",
|
|
440
|
-
"ask_codebase",
|
|
436
|
+
"create_code_agent",
|
|
437
|
+
"file_operation",
|
|
438
|
+
"ask_codebase",
|
|
441
439
|
"execute_shell",
|
|
442
440
|
"find_symbol",
|
|
443
441
|
"function_analyzer",
|
|
@@ -445,20 +443,19 @@ def create_dev_team() -> MultiAgent:
|
|
|
445
443
|
"read_code",
|
|
446
444
|
"create_sub_agent"
|
|
447
445
|
])
|
|
448
|
-
|
|
446
|
+
|
|
449
447
|
QA_output_handler = ToolRegistry()
|
|
450
448
|
QA_output_handler.use_tools([
|
|
451
|
-
"create_code_agent",
|
|
452
|
-
"file_operation",
|
|
453
|
-
"ask_codebase",
|
|
449
|
+
"create_code_agent",
|
|
450
|
+
"file_operation",
|
|
451
|
+
"ask_codebase",
|
|
454
452
|
"execute_shell",
|
|
455
453
|
"lsp_get_diagnostics",
|
|
456
454
|
"code_review",
|
|
457
455
|
"execute_shell_script",
|
|
458
456
|
"read_code",
|
|
459
|
-
"select_code_files"
|
|
460
457
|
])
|
|
461
|
-
|
|
458
|
+
|
|
462
459
|
# Update PM prompt with tool usage guidance
|
|
463
460
|
PM_PROMPT_EXTENSION = """
|
|
464
461
|
## 工具使用指南
|
|
@@ -482,7 +479,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
482
479
|
|
|
483
480
|
文档命名需规范,内容需要结构化,使用Markdown格式,便于团队成员理解和跟进。
|
|
484
481
|
"""
|
|
485
|
-
|
|
482
|
+
|
|
486
483
|
# Update BA prompt with tool usage guidance
|
|
487
484
|
BA_PROMPT_EXTENSION = """
|
|
488
485
|
## 工具使用指南
|
|
@@ -492,7 +489,6 @@ def create_dev_team() -> MultiAgent:
|
|
|
492
489
|
- **rag**:访问项目知识库,参考相似需求历史
|
|
493
490
|
- **execute_shell**:查询系统环境和配置信息
|
|
494
491
|
- **read_webpage**:收集用户体验和行业趋势信息
|
|
495
|
-
- **select_code_files**:了解现有代码中与需求相关的部分
|
|
496
492
|
- **methodology**:应用需求分析和用户故事映射方法论
|
|
497
493
|
- **ask_codebase**:分析代码库中的功能实现,了解现有系统能力和限制,分析业务逻辑
|
|
498
494
|
|
|
@@ -507,7 +503,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
507
503
|
|
|
508
504
|
文档需要结构化,使用Markdown格式,包含清晰的需求描述、优先级、验收标准和依赖关系。
|
|
509
505
|
"""
|
|
510
|
-
|
|
506
|
+
|
|
511
507
|
# Update SA prompt with tool usage guidance
|
|
512
508
|
SA_PROMPT_EXTENSION = """
|
|
513
509
|
## 工具使用指南
|
|
@@ -520,7 +516,6 @@ def create_dev_team() -> MultiAgent:
|
|
|
520
516
|
- **file_analyzer**:深入分析关键文件的结构和功能
|
|
521
517
|
- **function_analyzer**:分析核心函数的实现和设计
|
|
522
518
|
- **read_code**:阅读和理解关键代码段
|
|
523
|
-
- **select_code_files**:选择并分析与架构相关的代码文件
|
|
524
519
|
- **methodology**:应用架构设计方法论和模式
|
|
525
520
|
|
|
526
521
|
## 文档管理规范
|
|
@@ -534,7 +529,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
534
529
|
|
|
535
530
|
文档需使用图表、表格等方式清晰展示架构设计,包含各组件职责、接口、性能考量及安全措施。
|
|
536
531
|
"""
|
|
537
|
-
|
|
532
|
+
|
|
538
533
|
# Update TL prompt with tool usage guidance
|
|
539
534
|
TL_PROMPT_EXTENSION = """
|
|
540
535
|
## 工具使用指南
|
|
@@ -560,7 +555,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
560
555
|
|
|
561
556
|
文档需包含清晰的技术指导、代码质量标准、任务分解和时间估计,便于开发团队执行。
|
|
562
557
|
"""
|
|
563
|
-
|
|
558
|
+
|
|
564
559
|
# Update DEV prompt with tool usage guidance
|
|
565
560
|
DEV_PROMPT_EXTENSION = """
|
|
566
561
|
## 工具使用指南
|
|
@@ -586,7 +581,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
586
581
|
|
|
587
582
|
文档需要包含功能描述、使用示例、参数说明和注意事项,便于其他开发者理解和使用。
|
|
588
583
|
"""
|
|
589
|
-
|
|
584
|
+
|
|
590
585
|
# Update QA prompt with tool usage guidance
|
|
591
586
|
QA_PROMPT_EXTENSION = """
|
|
592
587
|
## 工具使用指南
|
|
@@ -598,7 +593,6 @@ def create_dev_team() -> MultiAgent:
|
|
|
598
593
|
- **code_review**:从质量保证角度审查代码
|
|
599
594
|
- **execute_shell_script**:执行自动化测试脚本
|
|
600
595
|
- **read_code**:阅读和理解代码以设计测试用例
|
|
601
|
-
- **select_code_files**:选择需要测试的关键代码文件
|
|
602
596
|
|
|
603
597
|
## 文档管理规范
|
|
604
598
|
每一步测试或质量评估后,必须使用file_operation工具将结论性输出记录到测试文档中:
|
|
@@ -612,7 +606,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
612
606
|
|
|
613
607
|
测试文档需包含测试范围、测试环境、测试用例、预期结果、实际结果和缺陷级别,便于跟踪和修复。
|
|
614
608
|
"""
|
|
615
|
-
|
|
609
|
+
|
|
616
610
|
# Append tool guidance to each role's prompt
|
|
617
611
|
PM_PROMPT_WITH_TOOLS = PM_PROMPT + PM_PROMPT_EXTENSION
|
|
618
612
|
BA_PROMPT_WITH_TOOLS = BA_PROMPT + BA_PROMPT_EXTENSION
|
|
@@ -620,7 +614,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
620
614
|
TL_PROMPT_WITH_TOOLS = TL_PROMPT + TL_PROMPT_EXTENSION
|
|
621
615
|
DEV_PROMPT_WITH_TOOLS = DEV_PROMPT + DEV_PROMPT_EXTENSION
|
|
622
616
|
QA_PROMPT_WITH_TOOLS = QA_PROMPT + QA_PROMPT_EXTENSION
|
|
623
|
-
|
|
617
|
+
|
|
624
618
|
# Create configurations for each role
|
|
625
619
|
configs = [
|
|
626
620
|
dict(
|
|
@@ -666,27 +660,27 @@ def create_dev_team() -> MultiAgent:
|
|
|
666
660
|
platform=PlatformRegistry().get_thinking_platform(),
|
|
667
661
|
)
|
|
668
662
|
]
|
|
669
|
-
|
|
663
|
+
|
|
670
664
|
return MultiAgent(configs, "PM")
|
|
671
665
|
|
|
672
666
|
def main():
|
|
673
667
|
"""Main entry point for the development team simulation."""
|
|
674
668
|
|
|
675
669
|
init_env()
|
|
676
|
-
|
|
670
|
+
|
|
677
671
|
# Create the development team
|
|
678
672
|
dev_team = create_dev_team()
|
|
679
|
-
|
|
673
|
+
|
|
680
674
|
# Start interaction loop
|
|
681
675
|
while True:
|
|
682
676
|
try:
|
|
683
677
|
user_input = get_multiline_input("\nEnter your request (or press Enter to exit): ")
|
|
684
678
|
if not user_input:
|
|
685
679
|
break
|
|
686
|
-
|
|
680
|
+
|
|
687
681
|
result = dev_team.run("My requirement: " + user_input)
|
|
688
682
|
PrettyOutput.print(result, output_type=OutputType.SYSTEM)
|
|
689
|
-
|
|
683
|
+
|
|
690
684
|
except KeyboardInterrupt:
|
|
691
685
|
PrettyOutput.print("Exiting...", output_type=OutputType.SYSTEM)
|
|
692
686
|
break
|
|
File without changes
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""Git Commit分析工具模块
|
|
2
|
+
|
|
3
|
+
该模块提供了一个GitCommitAnalyzer类,用于获取和分析指定Git commit的详细信息,
|
|
4
|
+
包括提交信息、修改内容以及详细的功能、原因和逻辑分析。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import re
|
|
9
|
+
import subprocess
|
|
10
|
+
from typing import Dict, Any
|
|
11
|
+
|
|
12
|
+
from jarvis.jarvis_agent import Agent
|
|
13
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
14
|
+
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
15
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
16
|
+
from jarvis.jarvis_utils.utils import ct, ot, init_env
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GitCommitAnalyzer:
|
|
20
|
+
"""Git Commit分析器
|
|
21
|
+
|
|
22
|
+
该类用于获取和分析指定Git commit的详细信息,包括:
|
|
23
|
+
- 完整的提交信息
|
|
24
|
+
- 修改的文件列表和状态
|
|
25
|
+
- 修改的功能、原因和逻辑分析
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
29
|
+
"""执行commit分析
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
args: 包含commit_sha和root_dir的参数字典
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
包含分析结果的字典,包括:
|
|
36
|
+
- success: 操作是否成功
|
|
37
|
+
- stdout: 包含commit_info和diff_content的结果
|
|
38
|
+
- stderr: 错误信息(如果操作失败)
|
|
39
|
+
"""
|
|
40
|
+
try:
|
|
41
|
+
commit_sha = args["commit_sha"]
|
|
42
|
+
root_dir = args.get("root_dir", ".")
|
|
43
|
+
|
|
44
|
+
# Store current directory
|
|
45
|
+
original_dir = os.getcwd()
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
# Change to root_dir
|
|
49
|
+
os.chdir(root_dir)
|
|
50
|
+
|
|
51
|
+
# 获取commit详细信息
|
|
52
|
+
commit_info = subprocess.check_output(
|
|
53
|
+
f"git show {commit_sha} --pretty=fuller",
|
|
54
|
+
shell=True,
|
|
55
|
+
text=True
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# 获取commit修改内容
|
|
59
|
+
diff_content = subprocess.check_output(
|
|
60
|
+
f"git show {commit_sha} --patch",
|
|
61
|
+
shell=True,
|
|
62
|
+
text=True
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# 分析commit的功能、原因和逻辑
|
|
66
|
+
system_prompt = """你是一位资深代码分析专家,拥有多年代码审查和重构经验。你需要对Git commit进行深入分析,包括:
|
|
67
|
+
1. 修改的功能:明确说明本次commit实现或修改了哪些功能
|
|
68
|
+
2. 修改的原因:分析为什么要进行这些修改(如修复bug、优化性能、添加新功能等)
|
|
69
|
+
3. 修改的逻辑:详细说明代码修改的具体实现逻辑和思路
|
|
70
|
+
4. 影响范围:评估本次修改可能影响的其他模块或功能
|
|
71
|
+
5. 代码质量:分析代码风格、可读性和可维护性
|
|
72
|
+
6. 测试覆盖:评估是否需要添加或修改测试用例
|
|
73
|
+
7. 最佳实践:检查代码是否符合行业最佳实践和项目规范
|
|
74
|
+
|
|
75
|
+
请确保分析内容:
|
|
76
|
+
- 准确反映commit的实际修改
|
|
77
|
+
- 提供足够的技术细节
|
|
78
|
+
- 保持结构清晰,便于理解
|
|
79
|
+
- 重点关注关键修改和潜在风险"""
|
|
80
|
+
|
|
81
|
+
tool_registry = ToolRegistry()
|
|
82
|
+
agent = Agent(
|
|
83
|
+
system_prompt=system_prompt,
|
|
84
|
+
name="Commit Analysis Agent",
|
|
85
|
+
summary_prompt=f"""请生成一份详细的commit分析报告,包含以下内容:
|
|
86
|
+
{ot("REPORT")}
|
|
87
|
+
# 功能分析
|
|
88
|
+
[说明本次commit实现或修改了哪些功能]
|
|
89
|
+
|
|
90
|
+
# 修改原因
|
|
91
|
+
[分析进行这些修改的原因,如修复bug、优化性能、添加新功能等]
|
|
92
|
+
|
|
93
|
+
# 实现逻辑
|
|
94
|
+
[详细说明代码修改的具体实现逻辑和思路]
|
|
95
|
+
|
|
96
|
+
# 影响范围
|
|
97
|
+
[评估本次修改可能影响的其他模块或功能]
|
|
98
|
+
|
|
99
|
+
# 代码质量
|
|
100
|
+
[分析代码风格、可读性和可维护性]
|
|
101
|
+
|
|
102
|
+
# 测试覆盖
|
|
103
|
+
[评估是否需要添加或修改测试用例]
|
|
104
|
+
|
|
105
|
+
# 最佳实践
|
|
106
|
+
[检查代码是否符合行业最佳实践和项目规范]
|
|
107
|
+
{ct("REPORT")}""",
|
|
108
|
+
output_handler=[tool_registry],
|
|
109
|
+
platform=PlatformRegistry().get_thinking_platform(),
|
|
110
|
+
auto_complete=True
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
analysis_result = agent.run(diff_content)
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
"success": True,
|
|
117
|
+
"stdout": {
|
|
118
|
+
"commit_info": commit_info,
|
|
119
|
+
"diff_content": diff_content,
|
|
120
|
+
"analysis_result": analysis_result
|
|
121
|
+
},
|
|
122
|
+
"stderr": ""
|
|
123
|
+
}
|
|
124
|
+
finally:
|
|
125
|
+
# Always restore original directory
|
|
126
|
+
os.chdir(original_dir)
|
|
127
|
+
except subprocess.CalledProcessError as error:
|
|
128
|
+
return {
|
|
129
|
+
"success": False,
|
|
130
|
+
"stdout": {},
|
|
131
|
+
"stderr": f"Failed to analyze commit: {str(error)}"
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def extract_analysis_report(result: str) -> str:
|
|
136
|
+
"""从分析结果中提取报告内容
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
result: 包含REPORT标签的完整分析结果字符串
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
提取的报告内容,如果未找到REPORT标签则返回空字符串
|
|
143
|
+
"""
|
|
144
|
+
search_match = re.search(ot("REPORT")+r'\n(.*?)\n'+ct("REPORT"), result, re.DOTALL)
|
|
145
|
+
if search_match:
|
|
146
|
+
return search_match.group(1)
|
|
147
|
+
return ""
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def main():
|
|
151
|
+
"""主函数,用于命令行接口"""
|
|
152
|
+
import argparse
|
|
153
|
+
|
|
154
|
+
init_env()
|
|
155
|
+
|
|
156
|
+
parser = argparse.ArgumentParser(description='Git Commit Analyzer')
|
|
157
|
+
parser.add_argument('commit', help='Commit SHA to analyze')
|
|
158
|
+
parser.add_argument('--root-dir', type=str, help='Root directory of the codebase', default=".")
|
|
159
|
+
|
|
160
|
+
args = parser.parse_args()
|
|
161
|
+
|
|
162
|
+
analyzer = GitCommitAnalyzer()
|
|
163
|
+
result = analyzer.execute({
|
|
164
|
+
"commit_sha": args.commit,
|
|
165
|
+
"root_dir": args.root_dir
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
if result["success"]:
|
|
169
|
+
PrettyOutput.section("Commit Information:", OutputType.SUCCESS)
|
|
170
|
+
PrettyOutput.print(result["stdout"]["commit_info"], OutputType.CODE)
|
|
171
|
+
PrettyOutput.section("Analysis Report:", OutputType.SUCCESS)
|
|
172
|
+
report = extract_analysis_report(result["stdout"]["analysis_result"])
|
|
173
|
+
PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown")
|
|
174
|
+
else:
|
|
175
|
+
PrettyOutput.print(result["stderr"], OutputType.WARNING)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
if __name__ == "__main__":
|
|
179
|
+
main()
|
jarvis/jarvis_git_squash/main.py
CHANGED
|
@@ -10,11 +10,11 @@ from jarvis.jarvis_utils.utils import init_env, user_confirm
|
|
|
10
10
|
class GitSquashTool:
|
|
11
11
|
name = "git_squash_agent"
|
|
12
12
|
description = "Squash commits interactively using a base commit hash"
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
def _confirm_squash(self) -> bool:
|
|
15
15
|
"""Prompt user for confirmation to squash commits"""
|
|
16
16
|
return user_confirm("是否确认压缩提交?", default=True)
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
def _reset_to_commit(self, commit_hash: str) -> bool:
|
|
19
19
|
"""Perform soft reset to specified commit hash"""
|
|
20
20
|
try:
|
|
@@ -26,31 +26,31 @@ class GitSquashTool:
|
|
|
26
26
|
return True
|
|
27
27
|
except Exception:
|
|
28
28
|
return False
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
def execute(self, args: Dict):
|
|
31
31
|
"""Execute the squash operation"""
|
|
32
32
|
try:
|
|
33
33
|
if not self._confirm_squash():
|
|
34
34
|
PrettyOutput.print("操作已取消", OutputType.WARNING)
|
|
35
35
|
return
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
if not self._reset_to_commit(args['commit_hash']):
|
|
38
38
|
PrettyOutput.print("重置到指定提交失败", OutputType.WARNING)
|
|
39
39
|
return
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
# Use existing GitCommitTool for new commit
|
|
42
42
|
commit_tool = GitCommitTool()
|
|
43
43
|
commit_tool.execute({"lang": args.get('lang', 'Chinese')})
|
|
44
44
|
except Exception as e:
|
|
45
45
|
PrettyOutput.print(f"压缩提交失败: {str(e)}", OutputType.WARNING)
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
def main():
|
|
48
48
|
init_env()
|
|
49
49
|
parser = argparse.ArgumentParser(description='Git squash tool')
|
|
50
50
|
parser.add_argument('commit_hash', type=str, help='Base commit hash to squash from')
|
|
51
51
|
parser.add_argument('--lang', type=str, default='Chinese', help='Language for commit messages')
|
|
52
52
|
args = parser.parse_args()
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
tool = GitSquashTool()
|
|
55
55
|
tool.execute({
|
|
56
56
|
'commit_hash': args.commit_hash,
|
jarvis/jarvis_lsp/base.py
CHANGED
|
@@ -3,36 +3,36 @@ from typing import List, Dict, Optional, Tuple, Any, Union
|
|
|
3
3
|
|
|
4
4
|
class BaseLSP(ABC):
|
|
5
5
|
"""Base class for Language Server Protocol integration.
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
Core LSP features needed for LLM-based code editing:
|
|
8
8
|
1. Code navigation and analysis
|
|
9
9
|
2. Code modification validation
|
|
10
10
|
3. Diagnostic information
|
|
11
11
|
4. Symbol analysis
|
|
12
12
|
"""
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
language: Union[str, List[str]] = "" # Language identifier, should be overridden by subclasses
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
@abstractmethod
|
|
17
17
|
def initialize(self, workspace_path: str) -> bool:
|
|
18
18
|
"""Initialize LSP server for the workspace.
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
Args:
|
|
21
21
|
workspace_path: Root path of the workspace
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
Returns:
|
|
24
24
|
bool: True if initialization successful
|
|
25
25
|
"""
|
|
26
26
|
return False
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
|
|
29
29
|
@abstractmethod
|
|
30
30
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
|
31
31
|
"""Get diagnostics (errors, warnings) for file.
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
Args:
|
|
34
34
|
file_path: Path to the file
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
Returns:
|
|
37
37
|
List of diagnostic items:
|
|
38
38
|
[
|
|
@@ -58,8 +58,8 @@ class BaseLSP(ABC):
|
|
|
58
58
|
]
|
|
59
59
|
"""
|
|
60
60
|
return []
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
|
|
62
|
+
|
|
63
63
|
def shutdown(self):
|
|
64
64
|
"""Shutdown LSP server cleanly."""
|
|
65
65
|
pass
|
jarvis/jarvis_lsp/cpp.py
CHANGED
|
@@ -8,19 +8,19 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
|
8
8
|
|
|
9
9
|
class CPPLSP(BaseLSP):
|
|
10
10
|
"""C++ LSP implementation using clangd."""
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
language = ["cpp", "c"]
|
|
13
13
|
|
|
14
14
|
@staticmethod
|
|
15
15
|
def check() -> bool:
|
|
16
16
|
"""Check if clangd is installed."""
|
|
17
17
|
return shutil.which("clangd") is not None
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def __init__(self):
|
|
20
20
|
self.workspace_path = ""
|
|
21
21
|
self.clangd_process = None
|
|
22
22
|
self.request_id = 0
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
def initialize(self, workspace_path: str) -> bool:
|
|
25
25
|
try:
|
|
26
26
|
self.workspace_path = workspace_path
|
|
@@ -31,24 +31,24 @@ class CPPLSP(BaseLSP):
|
|
|
31
31
|
stdout=subprocess.PIPE,
|
|
32
32
|
stderr=subprocess.PIPE
|
|
33
33
|
)
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
# Send initialize request
|
|
36
36
|
self._send_request("initialize", {
|
|
37
37
|
"processId": os.getpid(),
|
|
38
38
|
"rootUri": f"file://{workspace_path}",
|
|
39
39
|
"capabilities": {}
|
|
40
40
|
})
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
return True
|
|
43
43
|
except Exception as e:
|
|
44
44
|
PrettyOutput.print(f"C++ LSP 初始化失败: {str(e)}", OutputType.ERROR)
|
|
45
45
|
return False
|
|
46
|
-
|
|
46
|
+
|
|
47
47
|
def _send_request(self, method: str, params: Dict) -> Optional[Dict]:
|
|
48
48
|
"""Send JSON-RPC request to clangd."""
|
|
49
49
|
if not self.clangd_process:
|
|
50
50
|
return None
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
try:
|
|
53
53
|
self.request_id += 1
|
|
54
54
|
request = {
|
|
@@ -57,16 +57,16 @@ class CPPLSP(BaseLSP):
|
|
|
57
57
|
"method": method,
|
|
58
58
|
"params": params
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
self.clangd_process.stdin.write(json.dumps(request).encode() + b"\n") # type: ignore
|
|
62
62
|
self.clangd_process.stdin.flush() # type: ignore
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
response = json.loads(self.clangd_process.stdout.readline().decode()) # type: ignore
|
|
65
65
|
return response.get("result")
|
|
66
66
|
except Exception:
|
|
67
67
|
return None
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
|
|
69
|
+
|
|
70
70
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
|
71
71
|
# Send didOpen notification to trigger diagnostics
|
|
72
72
|
self._send_request("textDocument/didOpen", {
|
|
@@ -77,7 +77,7 @@ class CPPLSP(BaseLSP):
|
|
|
77
77
|
"text": open(file_path).read()
|
|
78
78
|
}
|
|
79
79
|
})
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
# Wait for diagnostic notification
|
|
82
82
|
try:
|
|
83
83
|
response = json.loads(self.clangd_process.stdout.readline().decode()) # type: ignore
|
|
@@ -86,8 +86,8 @@ class CPPLSP(BaseLSP):
|
|
|
86
86
|
except Exception:
|
|
87
87
|
pass
|
|
88
88
|
return []
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
|
|
90
|
+
|
|
91
91
|
def shutdown(self):
|
|
92
92
|
if self.clangd_process:
|
|
93
93
|
try:
|