jarvis-ai-assistant 0.1.128__py3-none-any.whl → 0.1.130__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 (32) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +26 -31
  3. jarvis/jarvis_agent/main.py +77 -0
  4. jarvis/jarvis_c2rust/c2rust.yaml +734 -0
  5. jarvis/jarvis_code_agent/builtin_input_handler.py +43 -0
  6. jarvis/jarvis_code_agent/code_agent.py +82 -156
  7. jarvis/jarvis_code_agent/file_input_handler.py +88 -0
  8. jarvis/jarvis_code_agent/patch.py +262 -80
  9. jarvis/jarvis_code_agent/shell_input_handler.py +8 -2
  10. jarvis/jarvis_dev/main.py +832 -740
  11. jarvis/jarvis_multi_agent/__init__.py +113 -92
  12. jarvis/jarvis_platform/registry.py +0 -1
  13. jarvis/jarvis_tools/create_sub_agent.py +1 -8
  14. jarvis/jarvis_tools/git_commiter.py +2 -1
  15. jarvis/jarvis_tools/read_code.py +143 -0
  16. jarvis/jarvis_tools/registry.py +35 -39
  17. jarvis/jarvis_tools/tool_generator.py +45 -17
  18. jarvis/jarvis_utils/__init__.py +17 -17
  19. jarvis/jarvis_utils/config.py +87 -51
  20. jarvis/jarvis_utils/embedding.py +49 -48
  21. jarvis/jarvis_utils/git_utils.py +34 -34
  22. jarvis/jarvis_utils/globals.py +26 -26
  23. jarvis/jarvis_utils/input.py +61 -45
  24. jarvis/jarvis_utils/methodology.py +22 -22
  25. jarvis/jarvis_utils/output.py +64 -64
  26. jarvis/jarvis_utils/utils.py +2 -2
  27. {jarvis_ai_assistant-0.1.128.dist-info → jarvis_ai_assistant-0.1.130.dist-info}/METADATA +1 -1
  28. {jarvis_ai_assistant-0.1.128.dist-info → jarvis_ai_assistant-0.1.130.dist-info}/RECORD +32 -27
  29. {jarvis_ai_assistant-0.1.128.dist-info → jarvis_ai_assistant-0.1.130.dist-info}/entry_points.txt +2 -0
  30. {jarvis_ai_assistant-0.1.128.dist-info → jarvis_ai_assistant-0.1.130.dist-info}/LICENSE +0 -0
  31. {jarvis_ai_assistant-0.1.128.dist-info → jarvis_ai_assistant-0.1.130.dist-info}/WHEEL +0 -0
  32. {jarvis_ai_assistant-0.1.128.dist-info → jarvis_ai_assistant-0.1.130.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,43 @@
1
+ import re
2
+ from typing import Any, Tuple
3
+
4
+ from jarvis.jarvis_utils.output import PrettyOutput, OutputType
5
+
6
+
7
+ def builtin_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
8
+ """
9
+ 处理内置的特殊输入标记,并追加相应的提示词
10
+
11
+ 参数:
12
+ user_input: 用户输入
13
+ agent: 代理对象
14
+
15
+ 返回:
16
+ Tuple[str, bool]: 处理后的输入和是否需要进一步处理
17
+ """
18
+ # 查找特殊标记
19
+ special_tags = re.findall(r"'<([^>]+)>'", user_input)
20
+
21
+ if not special_tags:
22
+ return user_input, False
23
+
24
+ # 使用集合去重
25
+ processed_tags = set()
26
+ # 处理每个标记
27
+ for tag in special_tags:
28
+ if tag in processed_tags:
29
+ continue
30
+ processed_tags.add(tag)
31
+
32
+ if tag == "CodeBase":
33
+ user_input = user_input.replace(f"'<{tag}>'", "")
34
+ user_input += "\n请使用ask_codebase工具查询代码库"
35
+ elif tag == "Web":
36
+ user_input = user_input.replace(f"'<{tag}>'", "")
37
+ user_input += "\n请使用search_web工具进行网页搜索"
38
+ elif tag == "RAG":
39
+ user_input = user_input.replace(f"'<{tag}>'", "")
40
+ user_input += "\n请使用rag工具进行知识库检索"
41
+ # 移除对未知标记的警告输出
42
+
43
+ return user_input, False
@@ -6,6 +6,8 @@ from typing import Any, Tuple
6
6
  from yaspin import yaspin
7
7
 
8
8
  from jarvis.jarvis_agent import Agent
9
+ from jarvis.jarvis_code_agent.builtin_input_handler import builtin_input_handler
10
+ from jarvis.jarvis_code_agent.file_input_handler import file_input_handler
9
11
  from jarvis.jarvis_code_agent.shell_input_handler import shell_input_handler
10
12
  from jarvis.jarvis_code_agent.patch import PatchOutputHandler
11
13
  from jarvis.jarvis_platform.registry import PlatformRegistry
@@ -21,83 +23,6 @@ from jarvis.jarvis_utils.utils import init_env, user_confirm
21
23
 
22
24
 
23
25
 
24
- def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
25
- prompt = user_input
26
- files = []
27
-
28
- file_refs = re.findall(r"'([^']+)'", user_input)
29
- for ref in file_refs:
30
- # Handle file:start,end or file:start:end format
31
- if ':' in ref:
32
- file_path, line_range = ref.split(':', 1)
33
- # Initialize with default values
34
- start_line = 1 # 1-based
35
- end_line = -1
36
-
37
- # Process line range if specified
38
- if ',' in line_range or ':' in line_range:
39
- try:
40
- raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
41
-
42
- # Handle special values and Python-style negative indices
43
- try:
44
- with open(file_path, 'r', encoding='utf-8') as f:
45
- total_lines = len(f.readlines())
46
- except FileNotFoundError:
47
- PrettyOutput.print(f"文件不存在: {file_path}", OutputType.WARNING)
48
- continue
49
- # Process start line
50
- if raw_start == 0: # 0表示整个文件
51
- start_line = 1
52
- end_line = total_lines
53
- else:
54
- start_line = raw_start if raw_start > 0 else total_lines + raw_start + 1
55
-
56
- # Process end line
57
- if raw_end == 0: # 0表示整个文件(如果start也是0)
58
- end_line = total_lines
59
- else:
60
- end_line = raw_end if raw_end > 0 else total_lines + raw_end + 1
61
-
62
- # Auto-correct ranges
63
- start_line = max(1, min(start_line, total_lines))
64
- end_line = max(start_line, min(end_line, total_lines))
65
-
66
- # Final validation
67
- if start_line < 1 or end_line > total_lines or start_line > end_line:
68
- raise ValueError
69
-
70
- except:
71
- continue
72
-
73
- # Add file if it exists
74
- if os.path.isfile(file_path):
75
- files.append({
76
- "path": file_path,
77
- "start_line": start_line,
78
- "end_line": end_line
79
- })
80
- else:
81
- # Handle simple file path
82
- if os.path.isfile(ref):
83
- files.append({
84
- "path": ref,
85
- "start_line": 1, # 1-based
86
- "end_line": -1
87
- })
88
-
89
- # Read and process files if any were found
90
- if files:
91
- with yaspin(text="正在读取文件...", color="cyan") as spinner:
92
- result = FileOperationTool().execute({"operation":"read","files": files})
93
- if result["success"]:
94
- spinner.text = "文件读取完成"
95
- spinner.ok("✅")
96
- return result["stdout"] + "\n" + prompt, False
97
-
98
- return prompt, False
99
-
100
-
101
26
 
102
27
  class CodeAgent:
103
28
  def __init__(self):
@@ -116,89 +41,91 @@ class CodeAgent:
116
41
  "lsp_prepare_rename"
117
42
  ])
118
43
  code_system_prompt = """
119
- # 角色:高级代码工程师
120
- 精通安全、精确的代码修改,具有严格的验证流程。
121
-
122
- ## 核心原则
123
- 1. 安全第一:绝不破坏现有功能
124
- 2. 精准工程:最小化、针对性修改
125
- 3. 完整可追溯:记录所有决策
126
- 4. 验证驱动:在每个阶段进行验证
127
-
128
- ## 工具使用协议
129
- 1. 分析工具:
130
- - lsp_get_document_symbols:映射代码结构
131
- - lsp_find_references:理解使用模式
132
- - lsp_find_definition:追踪实现细节
133
-
134
- 2. 验证工具:
135
- - lsp_prepare_rename:安全重构检查
136
- - lsp_get_diagnostics:修改后检查
137
-
138
- 3. 系统工具:
139
- - execute_shell:用于git操作和grep搜索
140
- - ask_codebase:查询代码知识库
141
- - search_web:技术参考查找
142
-
143
- ## 工作流程(PDCA循环)
144
- 1. 计划:
145
- - 使用ask_user分析需求
146
- - 使用LSP工具映射现有代码
147
- - 使用find_references识别影响区域
148
- - 使用git创建回滚计划
149
-
150
- 2. 执行:
151
- - 在受保护的块中进行原子修改
152
- - 每次更改后自动运行lsp_get_diagnostics
153
- - 如果发现错误,使用lsp_find_references和lsp_find_definition进行即时修复
154
- - 每次更改后使用LSP验证语法
155
-
156
- 3. 检查:
157
- - 强制使用lsp_get_diagnostics进行完整诊断报告
158
- - 使用lsp_preprepare_rename验证所有重命名
159
- - 如果检测到错误,进入修复循环直到所有检查通过
160
-
161
- 4. 行动:
162
- - 使用git提交详细消息
163
- - 准备回滚脚本(如果需要)
164
- - 进行实施后审查
165
-
166
- ## 代码修改标准
167
- 1. 修改前要求:
44
+ # 专业代码工程师
45
+
46
+ ## 身份与能力范围
47
+ - **角色定位**:精通精确、安全代码修改的高级代码工程师
48
+ - **核心能力**:代码分析、精准重构和系统化验证
49
+ - **知识领域**:软件架构、设计模式和特定语言的最佳实践
50
+ - **局限性**:复杂系统和特定领域知识需要明确的上下文支持
51
+
52
+ ## 交互原则与策略
53
+ - **沟通风格**:清晰简洁的技术解释,为所有决策提供合理依据
54
+ - **呈现格式**:使用补丁格式展示结构化的代码变更及其上下文
55
+ - **主动引导**:在有益的情况下,提出超出即时需求的改进建议
56
+ - **特殊场景应对**:
57
+ - 对于模糊请求:在继续前提出澄清问题
58
+ - 对于高风险变更:提出带有验证步骤的渐进式方法
59
+ - 对于性能问题:平衡即时修复与长期架构考量
60
+
61
+ ## 任务执行规范
62
+ ### 分析阶段
63
+ - 使用lsp_get_document_symbols映射代码结构
64
+ - 通过lsp_find_references和lsp_find_definition追踪依赖关系
65
+ - 在进行更改前识别潜在影响区域
66
+ - 为安全创建回滚计划
67
+
68
+ ### 实施阶段
69
+ - 进行原子化、聚焦的最小范围更改
70
+ - 保持一致的代码风格和格式
71
+ - 每次重大更改后运行lsp_get_diagnostics
72
+ - 立即修复任何检测到的问题
73
+
74
+ ### 验证阶段
75
+ - 使用lsp_get_diagnostics进行全面诊断
76
+ - 用lsp_prepare_rename验证所有重命名元素
77
+ - 检查相关代码中的意外副作用
78
+ - 确保必要的向后兼容性
79
+
80
+ ### 文档阶段
81
+ - 为每项修改提供清晰的理由
82
+ - 在所有补丁描述中包含上下文
83
+ - 记录任何假设或约束条件
84
+ - 准备详细的提交信息
85
+
86
+ ## 代码修改协议
87
+ 1. **修改前要求**:
168
88
  - 完整的代码分析报告
169
- - 影响评估矩阵
170
- - 回滚程序文档
89
+ - 影响评估
90
+ - 验证策略
171
91
 
172
- 2. 修改实施:
173
- - 单一职责修改
174
- - 严格的代码范围验证(±3行缓冲区)
92
+ 2. **修改实施**:
93
+ - 单一职责变更
94
+ - 严格的范围验证
175
95
  - 接口兼容性检查
176
96
 
177
- 3. 验证清单:
178
- [ ] 执行lsp_get_diagnostics并确保零错误
179
- [ ] 使用lsp_find_references确认影响范围
180
- [ ] 使用lsp_prepare_rename验证重命名安全性
97
+ 3. **验证清单**:
98
+ - 运行lsp_get_diagnostics确保零错误
99
+ - 使用lsp_find_references确认影响范围
100
+ - lsp_prepare_rename验证重命名安全性
181
101
 
182
- 4. 修改后:
102
+ 4. **修改后流程**:
183
103
  - 代码审查模拟
184
104
  - 版本控制审计
185
- - 更新变更日志
186
-
187
- ## 关键要求
188
- 1. 强制分析:
189
- - 修改前完整符号追踪
190
- - 跨文件影响分析
191
- - 依赖关系映射
192
-
193
- 2. 禁止操作:
194
- - 未通过lsp_get_diagnostics检查继续操作
195
- - 多个功能组合修改
196
- - 未经测试的接口修改
197
-
198
- 3. 紧急协议:
199
- - lsp_get_diagnostics出现错误时立即停止并回滚
200
- - 出现意外行为时通知用户
201
- - 对任何回归进行事后分析
105
+ - 更新变更文档
106
+
107
+ ## 工具使用指南
108
+ - **分析工具**:
109
+ - lsp_get_document_symbols:用于映射代码结构
110
+ - lsp_find_references:用于理解使用模式
111
+ - lsp_find_definition:用于追踪实现细节
112
+
113
+ - **验证工具**:
114
+ - lsp_prepare_rename:用于安全重构检查
115
+ - lsp_get_diagnostics:用于修改后检查
116
+
117
+ - **系统工具**:
118
+ - execute_shell:用于git操作和grep搜索
119
+ - ask_codebase:用于查询代码知识库
120
+ - search_web:用于技术参考查找
121
+
122
+ ## 补丁格式要求
123
+ 创建代码补丁时:
124
+ 1. 包含足够的上下文(更改前后各3行)
125
+ 2. 保留原始缩进和格式
126
+ 3. 为新文件提供完整代码
127
+ 4. 对于修改,保留周围未更改的代码
128
+ 5. 为每项更改包含清晰的理由说明
202
129
  """
203
130
  self.agent = Agent(system_prompt=code_system_prompt,
204
131
  name="CodeAgent",
@@ -208,7 +135,7 @@ class CodeAgent:
208
135
  output_handler=[tool_registry, PatchOutputHandler()],
209
136
  platform=PlatformRegistry().get_codegen_platform(),
210
137
  record_methodology=False,
211
- input_handler=[shell_input_handler, file_input_handler],
138
+ input_handler=[shell_input_handler, file_input_handler, builtin_input_handler],
212
139
  need_summary=False)
213
140
 
214
141
 
@@ -222,8 +149,7 @@ class CodeAgent:
222
149
  with spinner.hidden():
223
150
  git_commiter = GitCommitTool()
224
151
  git_commiter.execute({})
225
- else:
226
- spinner.text = "环境初始化完成"
152
+ spinner.text = "环境初始化完成"
227
153
  spinner.ok("✅")
228
154
 
229
155
 
@@ -0,0 +1,88 @@
1
+
2
+
3
+ import os
4
+ import re
5
+ from typing import Any, Tuple
6
+
7
+ from yaspin import yaspin
8
+
9
+ from jarvis.jarvis_tools.file_operation import FileOperationTool
10
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
11
+
12
+
13
+ def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
14
+ prompt = user_input
15
+ files = []
16
+
17
+ file_refs = re.findall(r"'([^']+)'", user_input)
18
+ for ref in file_refs:
19
+ # Handle file:start,end or file:start:end format
20
+ if ':' in ref:
21
+ file_path, line_range = ref.split(':', 1)
22
+ # Initialize with default values
23
+ start_line = 1 # 1-based
24
+ end_line = -1
25
+
26
+ # Process line range if specified
27
+ if ',' in line_range or ':' in line_range:
28
+ try:
29
+ raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
30
+
31
+ # Handle special values and Python-style negative indices
32
+ try:
33
+ with open(file_path, 'r', encoding='utf-8') as f:
34
+ total_lines = len(f.readlines())
35
+ except FileNotFoundError:
36
+ PrettyOutput.print(f"文件不存在: {file_path}", OutputType.WARNING)
37
+ continue
38
+ # Process start line
39
+ if raw_start == 0: # 0表示整个文件
40
+ start_line = 1
41
+ end_line = total_lines
42
+ else:
43
+ start_line = raw_start if raw_start > 0 else total_lines + raw_start + 1
44
+
45
+ # Process end line
46
+ if raw_end == 0: # 0表示整个文件(如果start也是0)
47
+ end_line = total_lines
48
+ else:
49
+ end_line = raw_end if raw_end > 0 else total_lines + raw_end + 1
50
+
51
+ # Auto-correct ranges
52
+ start_line = max(1, min(start_line, total_lines))
53
+ end_line = max(start_line, min(end_line, total_lines))
54
+
55
+ # Final validation
56
+ if start_line < 1 or end_line > total_lines or start_line > end_line:
57
+ raise ValueError
58
+
59
+ except:
60
+ continue
61
+
62
+ # Add file if it exists
63
+ if os.path.isfile(file_path):
64
+ files.append({
65
+ "path": file_path,
66
+ "start_line": start_line,
67
+ "end_line": end_line
68
+ })
69
+ else:
70
+ # Handle simple file path
71
+ if os.path.isfile(ref):
72
+ files.append({
73
+ "path": ref,
74
+ "start_line": 1, # 1-based
75
+ "end_line": -1
76
+ })
77
+
78
+ # Read and process files if any were found
79
+ if files:
80
+ with yaspin(text="正在读取文件...", color="cyan") as spinner:
81
+ result = FileOperationTool().execute({"operation":"read","files": files})
82
+ if result["success"]:
83
+ spinner.text = "文件读取完成"
84
+ spinner.ok("✅")
85
+ return result["stdout"] + "\n" + prompt, False
86
+
87
+ return prompt, False
88
+