jarvis-ai-assistant 0.1.132__py3-none-any.whl → 0.1.134__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.

Files changed (44) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +140 -279
  3. jarvis/jarvis_agent/jarvis.py +143 -0
  4. jarvis/jarvis_agent/main.py +0 -2
  5. jarvis/jarvis_agent/patch.py +16 -12
  6. jarvis/jarvis_code_agent/code_agent.py +155 -104
  7. jarvis/jarvis_dev/main.py +0 -8
  8. jarvis/jarvis_lsp/base.py +0 -42
  9. jarvis/jarvis_lsp/cpp.py +0 -15
  10. jarvis/jarvis_lsp/go.py +0 -15
  11. jarvis/jarvis_lsp/python.py +0 -19
  12. jarvis/jarvis_lsp/registry.py +0 -62
  13. jarvis/jarvis_lsp/rust.py +0 -15
  14. jarvis/jarvis_multi_agent/__init__.py +0 -41
  15. jarvis/jarvis_multi_agent/main.py +43 -0
  16. jarvis/jarvis_platform/registry.py +2 -16
  17. jarvis/jarvis_platform/yuanbao.py +1 -1
  18. jarvis/jarvis_rag/main.py +1 -1
  19. jarvis/jarvis_tools/ask_codebase.py +61 -54
  20. jarvis/jarvis_tools/code_review.py +21 -2
  21. jarvis/jarvis_tools/create_sub_agent.py +0 -1
  22. jarvis/jarvis_tools/file_analyzer.py +84 -73
  23. jarvis/jarvis_tools/find_caller.py +83 -18
  24. jarvis/jarvis_tools/find_symbol.py +102 -18
  25. jarvis/jarvis_tools/function_analyzer.py +115 -32
  26. jarvis/jarvis_tools/git_commiter.py +1 -1
  27. jarvis/jarvis_tools/methodology.py +0 -6
  28. jarvis/jarvis_tools/project_analyzer.py +116 -28
  29. jarvis/jarvis_tools/rag.py +0 -5
  30. jarvis/jarvis_tools/read_code.py +1 -1
  31. jarvis/jarvis_tools/search_web.py +23 -353
  32. jarvis/jarvis_tools/tool_generator.py +2 -2
  33. jarvis/jarvis_utils/config.py +13 -73
  34. jarvis/jarvis_utils/methodology.py +8 -11
  35. jarvis/jarvis_utils/output.py +2 -2
  36. jarvis/jarvis_utils/utils.py +1 -1
  37. {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/METADATA +6 -15
  38. {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/RECORD +42 -42
  39. {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/entry_points.txt +2 -3
  40. jarvis/jarvis_tools/lsp_find_definition.py +0 -150
  41. jarvis/jarvis_tools/lsp_find_references.py +0 -127
  42. {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/LICENSE +0 -0
  43. {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/WHEEL +0 -0
  44. {jarvis_ai_assistant-0.1.132.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/top_level.txt +0 -0
@@ -5,6 +5,7 @@ import os
5
5
  from yaspin import yaspin
6
6
 
7
7
  from jarvis.jarvis_agent.output_handler import OutputHandler
8
+ from jarvis.jarvis_platform.base import BasePlatform
8
9
  from jarvis.jarvis_platform.registry import PlatformRegistry
9
10
  from jarvis.jarvis_tools.git_commiter import GitCommitTool
10
11
  from jarvis.jarvis_tools.file_operation import FileOperationTool
@@ -168,11 +169,15 @@ def apply_patch(output_str: str) -> str:
168
169
 
169
170
  # 增加代码变更分析和错误提示
170
171
  final_ret += "\n\n# 代码变更分析:\n"
171
- final_ret += "1. 请仔细检查以上变更是否引入了潜在错误\n"
172
+ final_ret += "1. 请使用静态检查工具(如有)检查以上变更是否引入了潜在错误\n"
172
173
  final_ret += "2. 如果发现代码错误,请立即提出修复方案\n"
173
174
  final_ret += "3. 修复代码错误的优先级高于继续实现功能\n"
174
- final_ret += "4. 常见错误类型:语法错误、逻辑错误、命名错误、路径错误等\n"
175
- final_ret += "5. 确保修改后代码的一致性和完整性\n"
175
+ final_ret += "4. 确保修改后代码的一致性和完整性\n"
176
+ final_ret += "5. 请确认所有相关点是否已修改完成,包括但不限于:\n"
177
+ final_ret += " - 所有需要修改的文件\n"
178
+ final_ret += " - 所有需要更新的函数\n"
179
+ final_ret += " - 所有需要调整的依赖关系\n"
180
+ final_ret += " - 所有需要同步的文档\n"
176
181
  final_ret += "\n\n"
177
182
  final_ret += "如果没有问题,请继续进行下一步修改,如果所有修改都已经完成,请终止"
178
183
 
@@ -182,20 +187,20 @@ def apply_patch(output_str: str) -> str:
182
187
  final_ret += "❌ 补丁应用被拒绝\n"
183
188
  final_ret += f"# 补丁预览:\n```diff\n{diff}\n```"
184
189
  else:
190
+ commited = False
185
191
  final_ret += "❌ 没有要提交的更改\n"
186
192
  # 用户确认最终结果
187
193
  with spinner.hidden():
194
+ if commited:
195
+ return final_ret
188
196
  PrettyOutput.print(final_ret, OutputType.USER, lang="markdown")
189
197
  if not is_confirm_before_apply_patch() or user_confirm("是否使用此回复?", default=True):
190
198
  return final_ret
191
199
  custom_reply = get_multiline_input("请输入自定义回复")
192
200
  if not custom_reply.strip(): # 如果自定义回复为空,返回空字符串
193
201
  return ""
194
- if not commited:
195
- return final_ret + "\n\n" + custom_reply
196
- else:
197
- return custom_reply
198
-
202
+ return final_ret + "\n\n" + custom_reply
203
+
199
204
  def revert_file(filepath: str):
200
205
  """增强版git恢复,处理新文件"""
201
206
  import subprocess
@@ -258,7 +263,7 @@ def handle_code_operation(filepath: str, patch_content: str) -> bool:
258
263
  retry_count = 5
259
264
  while retry_count > 0:
260
265
  retry_count -= 1
261
- if handle_large_code_operation(filepath, patch_content):
266
+ if handle_large_code_operation(filepath, patch_content, PlatformRegistry().get_normal_platform() if retry_count > 2 else PlatformRegistry().get_thinking_platform()):
262
267
  return True
263
268
  return handle_small_code_operation(filepath, patch_content)
264
269
 
@@ -308,7 +313,7 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
308
313
  [合并后的完整代码,包括所有空行和缩进]
309
314
  {ct("MERGED_CODE")}
310
315
  """
311
- model = PlatformRegistry().get_codegen_platform()
316
+ model = PlatformRegistry().get_normal_platform()
312
317
  model.set_suppress_output(True)
313
318
  count = 30
314
319
  start_line = -1
@@ -365,7 +370,7 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
365
370
  return False
366
371
 
367
372
 
368
- def handle_large_code_operation(filepath: str, patch_content: str) -> bool:
373
+ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePlatform) -> bool:
369
374
  """处理大型代码文件的补丁操作,使用差异化补丁格式"""
370
375
  with yaspin(text=f"正在处理文件 {filepath}...", color="cyan") as spinner:
371
376
  try:
@@ -376,7 +381,6 @@ def handle_large_code_operation(filepath: str, patch_content: str) -> bool:
376
381
  spinner.fail("❌")
377
382
  return False
378
383
 
379
- model = PlatformRegistry().get_codegen_platform()
380
384
  model.set_suppress_output(True)
381
385
 
382
386
  prompt = f"""
@@ -1,5 +1,8 @@
1
1
  import subprocess
2
2
  import os
3
+ import argparse
4
+ from token import OP
5
+ from typing import Optional
3
6
 
4
7
  from yaspin import yaspin
5
8
 
@@ -22,7 +25,7 @@ from jarvis.jarvis_utils.utils import init_env, user_confirm
22
25
 
23
26
 
24
27
  class CodeAgent:
25
- def __init__(self):
28
+ def __init__(self, platform : Optional[str] = None, model: Optional[str] = None, need_summary: bool = True):
26
29
  self.root_dir = os.getcwd()
27
30
  tool_registry = ToolRegistry()
28
31
  tool_registry.use_tools(["execute_shell",
@@ -31,119 +34,162 @@ class CodeAgent:
31
34
  "ask_user",
32
35
  "ask_codebase",
33
36
  "lsp_get_diagnostics",
34
- "lsp_find_references",
35
- "lsp_find_definition",
36
37
  "code_review", # 代码审查工具
37
38
  "find_symbol", # 添加符号查找工具
38
39
  "find_caller", # 添加函数调用者查找工具
39
40
  "function_analyzer", # 添加函数分析工具
40
41
  "project_analyzer", # 添加项目分析工具
41
- "file_analyzer" # 添加单文件分析工具
42
+ "file_analyzer", # 添加单文件分析工具
43
+ "read_code"
42
44
  ])
43
45
  code_system_prompt = """
44
- # 专业代码工程师
45
-
46
- ## 身份与职责
47
- - **角色**:精通代码修改的高级工程师
48
- - **能力**:代码分析、精准重构和系统化验证
49
- - **知识**:软件架构、设计模式和编程最佳实践
50
-
51
- ## 工作原则
52
- - **准备工作**:在修改任何代码之前,必须已经阅读并充分理解相关代码
53
- - **分析范围判断**:首先评估当前文件内容是否足够完成修改,避免不必要的项目分析
54
- - **沟通**:清晰简洁的技术解释,提供决策依据
55
- - **代码修改**:结构化展示变更及其上下文
56
- - **问题处理**:遇到模糊请求时提出澄清问题,高风险变更时提出渐进式方法
57
- - **修改效率**:对于变更不超过50行的代码,应一次性完成修改,避免分段处理
58
-
59
- ## 任务执行流程
60
- ### 分析阶段
61
- - **范围确定**:首先判断是否仅需当前文件内容即可完成任务,避免不必要的分析
62
- - 评估任务复杂度,只在必要时进行全面分析
63
- - 简单修改可直接进行,无需复杂分析
64
- - 使用代码分析工具理解依赖关系
65
- - 识别潜在影响区域
66
- - 确保在开始修改前,已经完全阅读和理解相关代码文件
67
-
68
- ### 实施阶段
69
- - 进行最小范围更改,保持代码完整性
70
- - 对于不超过50行的代码变更,应一次性完成修改
71
- - 大型文件分段修改,确保每段修改后代码功能完整
72
- - 保持一致的代码风格和格式
73
- - 修改后立即验证,优先修复错误
74
-
75
- ### 验证阶段
76
- - 确认已充分理解所修改代码及其上下文
77
- - 使用诊断工具检查问题
78
- - 检查相关代码中的意外副作用
79
- - 确保兼容性和功能正确性
80
- - 验证修改是否符合原始设计意图和代码结构
81
-
82
- ### 文档阶段
83
- - 提供清晰的修改理由和上下文
84
- - 记录假设和约束条件
85
- - 准备详细的提交信息
86
-
87
- ## 工具使用指南
88
- - **范围决策**:
89
- - 先阅读当前文件,判断是否包含足够信息完成任务
90
- - 只有在确认需要更多上下文时才扩展分析范围
91
- - 明确告知用户当前文件是否足够,避免不必要分析
92
-
93
- - **代码阅读与理解**:
94
- - 在使用任何分析工具前,应首先完整阅读相关代码
95
- - 使用分析工具补充而非替代直接阅读和理解代码
96
- - 如有必要,可以使用`ask_codebase`工具来帮助理解复杂部分
97
-
98
- - **分析工具**:
99
- - lsp_find_references:理解使用模式
100
- - lsp_find_definition:追踪实现细节
101
- - find_symbol:查找代码符号位置
102
- - find_caller:查找函数调用位置
103
- - function_analyzer:分析函数实现
104
- - project_analyzer:分析项目架构(仅复杂任务使用)
105
- - file_analyzer:分析单文件结构
106
-
107
- - **验证工具**:
108
- - lsp_get_diagnostics:检查修改问题
109
- - code_review:代码审查
110
-
111
- - **系统工具**:
112
- - execute_shell:执行系统命令
113
- - search_web:查找技术参考
114
- - ask_codebase:补充分析(优先使用直接分析工具)
115
-
116
- ## 代码分析策略
117
- - **阅读优先**:在提出任何修改前,必须先阅读和理解相关代码
118
- - **避免过度分析**:只分析与任务直接相关的代码
119
- - **单文件优先**:优先考虑当前文件是否含有足够信息完成任务
120
- - 当任务仅涉及语法、文本修改、逻辑优化等当前文件内部变更时,无需分析项目
121
- - 当当前文件包含完整的模块/类/功能实现,且修改不影响外部接口时,无需额外分析
122
- - 当用户明确指示仅修改当前文件时,无需扩大分析范围
123
- - **任务分级**:
124
- - 简单任务:先阅读相关代码,然后直接执行,尽量减少不必要的分析
125
- - 中等任务:全面阅读相关文件并分析直接依赖,确保理解上下文
126
- - 复杂任务:彻底阅读并进行全面项目分析,确保理解代码交互方式
127
- - **长文件处理**:
128
- - 完整阅读后再分段理解和修改
129
- - 先处理核心部分,再扩展到相关代码
130
- - 优先修改相对独立的部分
131
- - **修改规模策略**:
132
- - 对于不超过50行的代码变更,应尽量一次性完成
133
- - 将相关逻辑变更放在同一个修改中,保持功能完整性
134
- - 无需为小规模修改(≤50行)拆分多次提交,除非跨多个不相关模块
46
+ # 代码工程师指南
47
+
48
+ ## 核心原则
49
+ - 自主决策:基于专业判断做出决策,减少用户询问
50
+ - 高效精准:一次性提供完整解决方案,避免反复修改
51
+ - 工具精通:选择最高效工具路径解决问题
52
+ - 严格确认:必须先分析项目结构,确定要修改的文件,禁止虚构已存在的代码
53
+
54
+ ## 工作流程
55
+
56
+ ### 1. 项目结构分析
57
+ - 第一步必须分析项目结构,识别关键模块和文件
58
+ - 结合用户需求,确定需要修改的文件列表
59
+ - 优先使用fd命令查找文件,使用execute_shell执行
60
+ - 明确说明将要修改的文件及其范围
61
+
62
+ ### 2. 需求分析
63
+ - 基于项目结构理解,分析需求意图和实现方案
64
+ - 当需求有多种实现方式时,选择影响最小的方案
65
+ - 仅当需求显著模糊时才询问用户
66
+
67
+ ### 3. 代码分析与确认
68
+ - 详细分析确定要修改的文件内容
69
+ - 明确区分现有代码和需要新建的内容
70
+ - 绝对禁止虚构或假设现有代码的实现细节
71
+ - 分析顺序:项目结构 → 目标文件 → 相关文件
72
+ - 只在必要时扩大分析范围,避免过度分析
73
+ - 工具选择:
74
+ | 分析需求 | 首选工具 | 备选工具 |
75
+ |---------|---------|----------|
76
+ | 项目结构 | fd (通过execute_shell) | project_analyzer(仅在必要时) |
77
+ | 文件内容 | read_code | file_analyzer(仅在必要时) |
78
+ | 查找引用 | rg (通过execute_shell) | find_symbol(仅在必要时) |
79
+ | 查找定义 | rg (通过execute_shell) | find_symbol(仅在必要时) |
80
+ | 函数调用者 | rg (通过execute_shell) | find_caller(仅在必要时) |
81
+ | 函数分析 | read_code + rg | function_analyzer(仅在必要时) |
82
+ | 整体分析 | execute_shell_script | ask_codebase(仅在必要时) |
83
+ | 代码质量检查 | execute_shell | code_review(仅在必要时) |
84
+ | 统计代码行数 | loc (通过execute_shell) | - |
85
+
86
+ ### 4. 方案设计
87
+ - 确定最小变更方案,保持代码结构
88
+ - 变更类型处理:
89
+ - 修改现有文件:必须先确认文件存在及其内容
90
+ - 创建新文件:可以根据需求创建,但要符合项目结构和风格
91
+ - 变更规模处理:
92
+ - ≤50行:一次性完成所有修改
93
+ - 50-200行:按功能模块分组
94
+ - >200行:按功能拆分,但尽量减少提交次数
95
+
96
+ ### 5. 实施修改
97
+ - 遵循"先读后写"原则,在修改已有代码前,必须已经读取了对应文件
98
+ - 保持代码风格一致性
99
+ - 自动匹配项目现有命名风格
100
+ - 允许创建新文件和结构,但不得假设或虚构现有代码
101
+
102
+ ### 6. 验证
103
+ - 修改后自动验证:
104
+ 1. 优先使用execute_shell运行相关静态检查命令(如pylint、flake8或单元测试)
105
+ 2. 只有在shell命令不足时才使用lsp_get_diagnostics
106
+ 3. 只有在特殊情况下才使用code_review
107
+ - 发现问题自动修复,无需用户指导
108
+
109
+ ## 专用工具简介
110
+ 仅在必要时使用以下专用工具:
111
+
112
+ - **project_analyzer**: 项目整体结构分析,仅在fd命令无法满足需求时使用
113
+ - **file_analyzer**: 单文件深度分析,应优先使用read_code替代
114
+ - **find_caller**: 函数调用者查找,应优先使用rg命令替代
115
+ - **find_symbol**: 符号引用查找,应优先使用rg命令替代
116
+ - **function_analyzer**: 函数实现分析,应优先使用read_code和rg组合替代
117
+ - **ask_codebase**: 代码库整体查询,应优先使用fd、rg和read_code组合替代
118
+ - **code_review**: 代码质量检查,应优先使用语言特定的lint工具替代
119
+
120
+ ## Shell命令优先策略
121
+
122
+ ### 优先使用的Shell命令
123
+ - **项目结构分析**:
124
+ - `fd -t f -e py` 查找所有Python文件
125
+ - `fd -t f -e js -e ts` 查找所有JavaScript/TypeScript文件
126
+ - `fd -t d` 列出所有目录
127
+ - `fd -t f -e java -e kt` 查找所有Java/Kotlin文件
128
+ - `fd -t f -e go` 查找所有Go文件
129
+ - `fd -t f -e rs` 查找所有Rust文件
130
+ - `fd -t f -e c -e cpp -e h -e hpp` 查找所有C/C++文件
131
+
132
+ - **代码内容搜索**:
133
+ - `rg "pattern" --type py` 在Python文件中搜索
134
+ - `rg "pattern" --type js` 在JavaScript文件中搜索
135
+ - `rg "pattern" --type java` 在Java文件中搜索
136
+ - `rg "pattern" --type c` 在C文件中搜索
137
+ - `rg "class ClassName"` 查找类定义
138
+ - `rg "func|function|def" -g "*.py" -g "*.js" -g "*.go" -g "*.rs"` 查找函数定义
139
+ - `rg -w "word"` 精确匹配单词
140
+
141
+ - **代码统计分析**:
142
+ - `loc <file_path>` 统计单个文件
143
+ - `loc --include="*.py"` 统计所有Python文件
144
+ - `loc --include="*.js" --include="*.ts"` 统计所有JavaScript/TypeScript文件
145
+ - `loc --exclude="test"` 排除测试文件
146
+ - `loc --sort=code` 按代码量排序
147
+
148
+ - **代码质量检查**:
149
+ - Python: `pylint <file_path>`, `flake8 <file_path>`
150
+ - JavaScript: `eslint <file_path>`
151
+ - TypeScript: `tsc --noEmit <file_path>`
152
+ - Java: `checkstyle <file_path>`
153
+ - Go: `go vet <file_path>`
154
+ - Rust: `cargo clippy`
155
+ - C/C++: `cppcheck <file_path>`
156
+
157
+ - **整体代码分析**:
158
+ - 使用execute_shell_script编写和执行脚本,批量分析多个文件
159
+ - 简单脚本示例:`find . -name "*.py" | xargs pylint`
160
+ - 使用多工具组合:`fd -e py | xargs pylint`
161
+
162
+ ### read_code工具使用
163
+ 读取文件应优先使用read_code工具,而非shell命令:
164
+ - 完整读取:使用read_code读取整个文件内容
165
+ - 部分读取:使用read_code指定行范围
166
+ - 大文件处理:对大型文件使用read_code指定行范围,避免全部加载
167
+
168
+ ### 仅在命令行工具不足时使用专用工具
169
+ 只有当fd、rg、loc和read_code工具无法获取足够信息时,才考虑使用专用工具(ask_codebase、code_review等)。在每次使用专用工具前,应先尝试使用上述工具获取所需信息。
170
+
171
+ ### 注意事项
172
+ - read_code比cat或grep更适合阅读代码
173
+ - rg比grep更快更强大,应优先使用
174
+ - fd比find更快更易用,应优先使用
175
+ - loc比wc -l提供更多代码统计信息,应优先使用
176
+ - 针对不同编程语言选择对应的代码质量检查工具
135
177
  """
136
178
  # Dynamically add ask_codebase based on task complexity if really needed
137
- self.agent = Agent(system_prompt=code_system_prompt,
138
- name="CodeAgent",
139
- auto_complete=False,
140
- is_sub_agent=False,
141
- use_methodology=False,
179
+ # 处理platform参数
180
+ platform_instance = (PlatformRegistry().create_platform(platform)
181
+ if platform
182
+ else PlatformRegistry().get_normal_platform())
183
+ if model:
184
+ platform_instance.set_model_name(model) # type: ignore
185
+
186
+ self.agent = Agent(system_prompt=code_system_prompt,
187
+ name="CodeAgent",
188
+ auto_complete=False,
142
189
  output_handler=[tool_registry, PatchOutputHandler()],
143
- platform=PlatformRegistry().get_codegen_platform(),
144
- record_methodology=False,
190
+ platform=platform_instance,
145
191
  input_handler=[shell_input_handler, file_input_handler, builtin_input_handler],
146
- need_summary=False)
192
+ need_summary=need_summary)
147
193
 
148
194
 
149
195
 
@@ -212,6 +258,11 @@ def main():
212
258
  # Add argument parser
213
259
  init_env()
214
260
 
261
+ parser = argparse.ArgumentParser(description='Jarvis Code Agent')
262
+ parser.add_argument('-p', '--platform', type=str, help='Target platform name', default=None)
263
+ parser.add_argument('-m', '--model', type=str, help='Model name to use', default=None)
264
+ args = parser.parse_args()
265
+
215
266
  curr_dir = os.getcwd()
216
267
  git_dir = find_git_root(curr_dir)
217
268
  PrettyOutput.print(f"当前目录: {git_dir}", OutputType.INFO)
@@ -221,7 +272,7 @@ def main():
221
272
  user_input = get_multiline_input("请输入你的需求(输入空行退出):")
222
273
  if not user_input:
223
274
  return 0
224
- agent = CodeAgent()
275
+ agent = CodeAgent(platform=args.platform, model=args.model, need_summary=False)
225
276
  agent.run(user_input)
226
277
 
227
278
  except Exception as e:
jarvis/jarvis_dev/main.py CHANGED
@@ -425,8 +425,6 @@ def create_dev_team() -> MultiAgent:
425
425
  "file_operation",
426
426
  "ask_codebase",
427
427
  "lsp_get_diagnostics",
428
- "lsp_find_references",
429
- "lsp_find_definition",
430
428
  "execute_shell",
431
429
  "code_review",
432
430
  "find_symbol",
@@ -441,8 +439,6 @@ def create_dev_team() -> MultiAgent:
441
439
  "file_operation",
442
440
  "ask_codebase",
443
441
  "execute_shell",
444
- "lsp_find_definition",
445
- "lsp_find_references",
446
442
  "find_symbol",
447
443
  "function_analyzer",
448
444
  "file_analyzer",
@@ -545,8 +541,6 @@ def create_dev_team() -> MultiAgent:
545
541
  - **file_operation**:管理技术文档和指导文件
546
542
  - **ask_codebase**:分析代码库,理解实现细节
547
543
  - **lsp_get_diagnostics**:检查代码问题和警告
548
- - **lsp_find_references**:查找代码引用关系
549
- - **lsp_find_definition**:查找符号定义位置
550
544
  - **execute_shell**:执行开发工具和命令
551
545
  - **code_review**:进行代码审查,确保代码质量
552
546
  - **find_symbol**:查找关键符号在代码中的使用
@@ -574,8 +568,6 @@ def create_dev_team() -> MultiAgent:
574
568
  - **file_operation**:管理源代码和配置文件
575
569
  - **ask_codebase**:了解代码库实现细节
576
570
  - **execute_shell**:执行开发命令和测试脚本
577
- - **lsp_find_definition**:查找符号定义位置
578
- - **lsp_find_references**:查找代码引用关系
579
571
  - **find_symbol**:查找关键符号在代码中的使用
580
572
  - **function_analyzer**:分析函数实现和优化空间
581
573
  - **file_analyzer**:分析文件结构和功能
jarvis/jarvis_lsp/base.py CHANGED
@@ -25,48 +25,6 @@ class BaseLSP(ABC):
25
25
  """
26
26
  return False
27
27
 
28
- @abstractmethod
29
- def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
30
- """Find all references of symbol at position.
31
-
32
- Args:
33
- file_path: Path to the file
34
- position: (line, character) tuple
35
-
36
- Returns:
37
- List of references with location info:
38
- [
39
- {
40
- "uri": "file path",
41
- "range": {
42
- "start": {"line": int, "character": int},
43
- "end": {"line": int, "character": int}
44
- }
45
- }
46
- ]
47
- """
48
- return []
49
-
50
- @abstractmethod
51
- def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
52
- """Find definition of symbol at position.
53
-
54
- Args:
55
- file_path: Path to the file
56
- position: (line, character) tuple
57
-
58
- Returns:
59
- Location of definition:
60
- {
61
- "uri": "file path",
62
- "range": {
63
- "start": {"line": int, "character": int},
64
- "end": {"line": int, "character": int}
65
- }
66
- }
67
- """
68
- return None
69
-
70
28
 
71
29
  @abstractmethod
72
30
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
jarvis/jarvis_lsp/cpp.py CHANGED
@@ -66,21 +66,6 @@ class CPPLSP(BaseLSP):
66
66
  except Exception:
67
67
  return None
68
68
 
69
- def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
70
- result = self._send_request("textDocument/references", {
71
- "textDocument": {"uri": f"file://{file_path}"},
72
- "position": {"line": position[0], "character": position[1]},
73
- "context": {"includeDeclaration": True}
74
- })
75
- return result or [] # type: ignore
76
-
77
- def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
78
- result = self._send_request("textDocument/definition", {
79
- "textDocument": {"uri": f"file://{file_path}"},
80
- "position": {"line": position[0], "character": position[1]}
81
- })
82
- return result[0] if result else None
83
-
84
69
 
85
70
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
86
71
  # Send didOpen notification to trigger diagnostics
jarvis/jarvis_lsp/go.py CHANGED
@@ -72,21 +72,6 @@ class GoLSP(BaseLSP):
72
72
  except Exception:
73
73
  return None
74
74
 
75
- def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
76
- result = self._send_request("textDocument/references", {
77
- "textDocument": {"uri": f"file://{file_path}"},
78
- "position": {"line": position[0], "character": position[1]},
79
- "context": {"includeDeclaration": True}
80
- })
81
- return result or [] # type: ignore
82
-
83
- def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
84
- result = self._send_request("textDocument/definition", {
85
- "textDocument": {"uri": f"file://{file_path}"},
86
- "position": {"line": position[0], "character": position[1]}
87
- })
88
- return result[0] if result else None
89
-
90
75
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
91
76
  # Send didOpen notification to trigger diagnostics
92
77
  self._send_request("textDocument/didOpen", {
@@ -25,25 +25,6 @@ class PythonLSP(BaseLSP):
25
25
  return None
26
26
  return self.script_cache[file_path]
27
27
 
28
- def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
29
- script = self._get_script(file_path)
30
- if not script:
31
- return []
32
- try:
33
- refs = script.get_references(line=position[0] + 1, column=position[1])
34
- return [self._location_to_dict(ref) for ref in refs]
35
- except Exception:
36
- return []
37
-
38
- def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
39
- script = self._get_script(file_path)
40
- if not script:
41
- return None
42
- try:
43
- defs = script.goto(line=position[0] + 1, column=position[1])
44
- return self._location_to_dict(defs[0]) if defs else None
45
- except Exception:
46
- return None
47
28
 
48
29
  def _location_to_dict(self, location) -> Dict[str, Any]:
49
30
  return {
@@ -9,8 +9,6 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
9
 
10
10
  REQUIRED_METHODS = [
11
11
  ('initialize', ['workspace_path']),
12
- ('find_references', ['file_path', 'position']),
13
- ('find_definition', ['file_path', 'position']),
14
12
  ('get_diagnostics', ['file_path']),
15
13
  ('shutdown', [])
16
14
  ]
@@ -167,63 +165,3 @@ class LSPRegistry:
167
165
  with open(file_path, 'r', errors="ignore") as file:
168
166
  lines = file.readlines()
169
167
  return lines[line]
170
-
171
- def main():
172
- """CLI entry point for LSP testing."""
173
- import argparse
174
-
175
- parser = argparse.ArgumentParser(description='LSP functionality testing')
176
- parser.add_argument('--language', type=str, required=True, help='Programming language')
177
- parser.add_argument('--file', type=str, required=True, help='File to analyze')
178
- parser.add_argument('--action', choices=['symbols', 'diagnostics', 'references', 'definition'],
179
- required=True, help='Action to perform')
180
- parser.add_argument('--line', type=int, help='Line number (0-based) for references/definition')
181
- parser.add_argument('--character', type=int, help='Character position for references/definition')
182
-
183
- args = parser.parse_args()
184
-
185
- # Initialize LSP
186
- registry = LSPRegistry.get_global_lsp_registry()
187
- lsp = registry.create_lsp(args.language)
188
-
189
- if not lsp:
190
- PrettyOutput.print(f"没有 LSP 支持的语言: {args.language}", OutputType.WARNING)
191
- return 1
192
-
193
- if not lsp.initialize(os.path.abspath(os.getcwd())):
194
- PrettyOutput.print("LSP 初始化失败", OutputType.WARNING)
195
- return 1
196
-
197
- try:
198
- if args.action == 'diagnostics':
199
- diagnostics = lsp.get_diagnostics(args.file)
200
- for diag in diagnostics:
201
- severity = ['Error', 'Warning', 'Info', 'Hint'][diag['severity'] - 1]
202
- PrettyOutput.print(f"{severity} 在 {diag['range']['start']['line']}:{diag['range']['start']['character']}: {diag['message']}", OutputType.INFO)
203
-
204
- elif args.action in ('references', 'definition'):
205
- if args.line is None or args.character is None:
206
- PrettyOutput.print("需要行和字符位置用于 references/definition", OutputType.WARNING)
207
- return 1
208
-
209
- if args.action == 'references':
210
- refs = lsp.find_references(args.file, (args.line, args.character))
211
- for ref in refs:
212
- PrettyOutput.print(f"引用在 {ref['uri']} 在 {ref['range']['start']['line']}:{ref['range']['start']['character']}\n行: {LSPRegistry.get_line_at_position(ref['uri'], ref['range']['start']['line'])}", OutputType.INFO)
213
- else:
214
- defn = lsp.find_definition(args.file, (args.line, args.character))
215
- if defn:
216
- PrettyOutput.print(f"定义在 {defn['uri']} 在 {defn['range']['start']['line']}:{defn['range']['start']['character']}\n行: {LSPRegistry.get_line_at_position(defn['uri'], defn['range']['start']['line'])}", OutputType.INFO)
217
- else:
218
- PrettyOutput.print("没有找到定义", OutputType.WARNING)
219
-
220
- except Exception as e:
221
- PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
222
- return 1
223
- finally:
224
- lsp.shutdown()
225
-
226
- return 0
227
-
228
- if __name__ == "__main__":
229
- exit(main())
jarvis/jarvis_lsp/rust.py CHANGED
@@ -74,21 +74,6 @@ class RustLSP(BaseLSP):
74
74
  except Exception:
75
75
  return None
76
76
 
77
- def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
78
- result = self._send_request("textDocument/references", {
79
- "textDocument": {"uri": f"file://{file_path}"},
80
- "position": {"line": position[0], "character": position[1]},
81
- "context": {"includeDeclaration": True}
82
- })
83
- return result or [] # type: ignore
84
-
85
- def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
86
- result = self._send_request("textDocument/definition", {
87
- "textDocument": {"uri": f"file://{file_path}"},
88
- "position": {"line": position[0], "character": position[1]}
89
- })
90
- return result[0] if result else None
91
-
92
77
 
93
78
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
94
79
  # Send didOpen notification to trigger diagnostics