jarvis-ai-assistant 0.1.160__py3-none-any.whl → 0.1.162__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 +1 -2
- jarvis/jarvis_agent/jarvis.py +2 -3
- jarvis/jarvis_code_agent/code_agent.py +135 -20
- jarvis/jarvis_dev/main.py +11 -4
- jarvis/jarvis_git_utils/git_commiter.py +9 -6
- jarvis/{jarvis_agent/patch.py → jarvis_tools/edit_file.py} +147 -175
- jarvis/jarvis_utils/input.py +40 -37
- {jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/METADATA +1 -1
- {jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/RECORD +14 -14
- {jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
|
@@ -5,7 +5,6 @@ from typing import Any, Callable, List, Optional, Tuple, Union
|
|
|
5
5
|
from yaspin import yaspin # type: ignore
|
|
6
6
|
|
|
7
7
|
from jarvis.jarvis_agent.output_handler import OutputHandler
|
|
8
|
-
from jarvis.jarvis_agent.patch import PatchOutputHandler
|
|
9
8
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
10
9
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
11
10
|
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
@@ -180,7 +179,7 @@ class Agent:
|
|
|
180
179
|
self.model.set_suppress_output(False)
|
|
181
180
|
|
|
182
181
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
183
|
-
self.output_handler = output_handler if output_handler else [ToolRegistry()
|
|
182
|
+
self.output_handler = output_handler if output_handler else [ToolRegistry()]
|
|
184
183
|
self.multiline_inputer = multiline_inputer if multiline_inputer else get_multiline_input
|
|
185
184
|
|
|
186
185
|
self.prompt = ""
|
jarvis/jarvis_agent/jarvis.py
CHANGED
|
@@ -15,7 +15,6 @@ from jarvis.jarvis_agent import (
|
|
|
15
15
|
Agent,
|
|
16
16
|
origin_agent_system_prompt
|
|
17
17
|
)
|
|
18
|
-
from jarvis.jarvis_agent.patch import PatchOutputHandler
|
|
19
18
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
20
19
|
from jarvis.jarvis_utils.utils import init_env
|
|
21
20
|
from jarvis.jarvis_agent.file_input_handler import file_input_handler
|
|
@@ -94,7 +93,7 @@ def _select_task(tasks: Dict[str, str]) -> str:
|
|
|
94
93
|
# 询问是否需要补充信息
|
|
95
94
|
need_additional = user_confirm("需要为此任务添加补充信息吗?", default=False)
|
|
96
95
|
if need_additional:
|
|
97
|
-
additional_input = get_multiline_input("
|
|
96
|
+
additional_input = get_multiline_input("请输入补充信息:")
|
|
98
97
|
if additional_input:
|
|
99
98
|
selected_task = f"{selected_task}\n\n补充信息:\n{additional_input}"
|
|
100
99
|
return selected_task
|
|
@@ -123,7 +122,7 @@ def main() -> None:
|
|
|
123
122
|
platform=args.platform,
|
|
124
123
|
model_name=args.model,
|
|
125
124
|
input_handler=[file_input_handler, shell_input_handler, builtin_input_handler],
|
|
126
|
-
output_handler=[ToolRegistry()
|
|
125
|
+
output_handler=[ToolRegistry()],
|
|
127
126
|
need_summary=False
|
|
128
127
|
)
|
|
129
128
|
|
|
@@ -7,7 +7,7 @@ import os
|
|
|
7
7
|
import sys
|
|
8
8
|
import subprocess
|
|
9
9
|
import argparse
|
|
10
|
-
from typing import Optional, List, Tuple
|
|
10
|
+
from typing import Any, Dict, Optional, List, Tuple
|
|
11
11
|
|
|
12
12
|
# 忽略yaspin的类型检查
|
|
13
13
|
from yaspin import yaspin # type: ignore
|
|
@@ -16,7 +16,6 @@ from jarvis.jarvis_agent import Agent
|
|
|
16
16
|
from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
|
|
17
17
|
from jarvis.jarvis_agent.file_input_handler import file_input_handler
|
|
18
18
|
from jarvis.jarvis_agent.shell_input_handler import shell_input_handler
|
|
19
|
-
from jarvis.jarvis_agent.patch import PatchOutputHandler
|
|
20
19
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
21
20
|
from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
|
|
22
21
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
@@ -51,9 +50,8 @@ class CodeAgent:
|
|
|
51
50
|
"read_code",
|
|
52
51
|
"methodology",
|
|
53
52
|
"chdir",
|
|
54
|
-
"create_code_agent",
|
|
55
53
|
"find_methodology",
|
|
56
|
-
"
|
|
54
|
+
"edit_file",
|
|
57
55
|
])
|
|
58
56
|
code_system_prompt = """
|
|
59
57
|
<code_engineer_guide>
|
|
@@ -204,7 +202,13 @@ class CodeAgent:
|
|
|
204
202
|
- loc比wc -l提供更多代码统计信息,应优先使用
|
|
205
203
|
- 针对不同编程语言选择对应的代码质量检查工具
|
|
206
204
|
- 不要留下未实现的代码
|
|
207
|
-
|
|
205
|
+
|
|
206
|
+
### 代码编辑规范
|
|
207
|
+
- 使用edit_file工具进行代码修改时,必须遵循最小补丁原则
|
|
208
|
+
- 只提供需要修改的代码部分,不要提供完整文件内容
|
|
209
|
+
- 保持原始代码的缩进、空行和格式风格
|
|
210
|
+
- 每个修改必须包含清晰的修改理由
|
|
211
|
+
- 新建文件时可以提供完整内容,修改现有文件时只提供差异部分
|
|
208
212
|
</notes>
|
|
209
213
|
</code_engineer_guide>
|
|
210
214
|
"""
|
|
@@ -220,7 +224,7 @@ class CodeAgent:
|
|
|
220
224
|
system_prompt=code_system_prompt,
|
|
221
225
|
name="CodeAgent",
|
|
222
226
|
auto_complete=False,
|
|
223
|
-
output_handler=[tool_registry
|
|
227
|
+
output_handler=[tool_registry],
|
|
224
228
|
platform=platform_instance,
|
|
225
229
|
input_handler=[
|
|
226
230
|
shell_input_handler,
|
|
@@ -243,6 +247,83 @@ class CodeAgent:
|
|
|
243
247
|
"""
|
|
244
248
|
return self.root_dir
|
|
245
249
|
|
|
250
|
+
def get_loc_stats(self) -> str:
|
|
251
|
+
"""使用loc命令获取当前目录的代码统计信息
|
|
252
|
+
|
|
253
|
+
返回:
|
|
254
|
+
str: loc命令输出的原始字符串,失败时返回空字符串
|
|
255
|
+
"""
|
|
256
|
+
try:
|
|
257
|
+
result = subprocess.run(
|
|
258
|
+
['loc'],
|
|
259
|
+
cwd=self.root_dir,
|
|
260
|
+
capture_output=True,
|
|
261
|
+
text=True
|
|
262
|
+
)
|
|
263
|
+
return result.stdout if result.returncode == 0 else ""
|
|
264
|
+
except FileNotFoundError:
|
|
265
|
+
return ""
|
|
266
|
+
|
|
267
|
+
def get_recent_commits_with_files(self) -> List[Dict[str, Any]]:
|
|
268
|
+
"""获取最近5次提交的commit信息和文件清单
|
|
269
|
+
|
|
270
|
+
返回:
|
|
271
|
+
List[Dict[str, Any]]: 包含commit信息和文件清单的字典列表,格式为:
|
|
272
|
+
[
|
|
273
|
+
{
|
|
274
|
+
'hash': 提交hash,
|
|
275
|
+
'message': 提交信息,
|
|
276
|
+
'author': 作者,
|
|
277
|
+
'date': 提交日期,
|
|
278
|
+
'files': [修改的文件列表] (最多50个文件)
|
|
279
|
+
},
|
|
280
|
+
...
|
|
281
|
+
]
|
|
282
|
+
失败时返回空列表
|
|
283
|
+
"""
|
|
284
|
+
try:
|
|
285
|
+
# 获取最近5次提交的基本信息
|
|
286
|
+
result = subprocess.run(
|
|
287
|
+
['git', 'log', '-5', '--pretty=format:%H%n%s%n%an%n%ad'],
|
|
288
|
+
cwd=self.root_dir,
|
|
289
|
+
capture_output=True,
|
|
290
|
+
text=True
|
|
291
|
+
)
|
|
292
|
+
if result.returncode != 0:
|
|
293
|
+
return []
|
|
294
|
+
|
|
295
|
+
# 解析提交信息
|
|
296
|
+
commits = []
|
|
297
|
+
lines = result.stdout.splitlines()
|
|
298
|
+
for i in range(0, len(lines), 4):
|
|
299
|
+
if i + 3 >= len(lines):
|
|
300
|
+
break
|
|
301
|
+
commit = {
|
|
302
|
+
'hash': lines[i],
|
|
303
|
+
'message': lines[i+1],
|
|
304
|
+
'author': lines[i+2],
|
|
305
|
+
'date': lines[i+3],
|
|
306
|
+
'files': []
|
|
307
|
+
}
|
|
308
|
+
commits.append(commit)
|
|
309
|
+
|
|
310
|
+
# 获取每个提交的文件修改清单
|
|
311
|
+
for commit in commits:
|
|
312
|
+
files_result = subprocess.run(
|
|
313
|
+
['git', 'show', '--name-only', '--pretty=format:', commit['hash']],
|
|
314
|
+
cwd=self.root_dir,
|
|
315
|
+
capture_output=True,
|
|
316
|
+
text=True
|
|
317
|
+
)
|
|
318
|
+
if files_result.returncode == 0:
|
|
319
|
+
files = list(set(filter(None, files_result.stdout.splitlines())))
|
|
320
|
+
commit['files'] = files[:50] # 限制最多50个文件
|
|
321
|
+
|
|
322
|
+
return commits
|
|
323
|
+
|
|
324
|
+
except subprocess.CalledProcessError:
|
|
325
|
+
return []
|
|
326
|
+
|
|
246
327
|
def _init_env(self) -> None:
|
|
247
328
|
"""初始化环境"""
|
|
248
329
|
with yaspin(text="正在初始化环境...", color="cyan") as spinner:
|
|
@@ -261,8 +342,29 @@ class CodeAgent:
|
|
|
261
342
|
if has_uncommitted_changes():
|
|
262
343
|
PrettyOutput.print("检测到未提交的修改,是否要提交?", OutputType.WARNING)
|
|
263
344
|
if user_confirm("是否要提交?", True):
|
|
264
|
-
|
|
265
|
-
|
|
345
|
+
import subprocess
|
|
346
|
+
try:
|
|
347
|
+
# 获取当前分支的提交总数
|
|
348
|
+
commit_count = subprocess.run(
|
|
349
|
+
['git', 'rev-list', '--count', 'HEAD'],
|
|
350
|
+
capture_output=True,
|
|
351
|
+
text=True
|
|
352
|
+
)
|
|
353
|
+
if commit_count.returncode != 0:
|
|
354
|
+
return
|
|
355
|
+
|
|
356
|
+
commit_count = int(commit_count.stdout.strip())
|
|
357
|
+
|
|
358
|
+
# 暂存所有修改
|
|
359
|
+
subprocess.run(['git', 'add', '.'], check=True)
|
|
360
|
+
|
|
361
|
+
# 提交变更
|
|
362
|
+
subprocess.run(
|
|
363
|
+
['git', 'commit', '-m', f'CheckPoint #{commit_count + 1}'],
|
|
364
|
+
check=True
|
|
365
|
+
)
|
|
366
|
+
except subprocess.CalledProcessError as e:
|
|
367
|
+
PrettyOutput.print(f"提交失败: {str(e)}", OutputType.ERROR)
|
|
266
368
|
|
|
267
369
|
def _show_commit_history(
|
|
268
370
|
self,
|
|
@@ -301,17 +403,14 @@ class CodeAgent:
|
|
|
301
403
|
) -> None:
|
|
302
404
|
"""处理提交确认和可能的重置"""
|
|
303
405
|
if commits and user_confirm("是否接受以上提交记录?", True):
|
|
304
|
-
|
|
305
|
-
"
|
|
306
|
-
|
|
307
|
-
subprocess.
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
)
|
|
313
|
-
git_commiter = GitCommitTool()
|
|
314
|
-
git_commiter.execute({})
|
|
406
|
+
subprocess.run(
|
|
407
|
+
["git", "reset", "--mixed", str(start_commit)],
|
|
408
|
+
stdout=subprocess.DEVNULL,
|
|
409
|
+
stderr=subprocess.DEVNULL,
|
|
410
|
+
check=True
|
|
411
|
+
)
|
|
412
|
+
git_commiter = GitCommitTool()
|
|
413
|
+
git_commiter.execute({})
|
|
315
414
|
elif start_commit:
|
|
316
415
|
os.system(f"git reset --hard {str(start_commit)}") # 确保转换为字符串
|
|
317
416
|
PrettyOutput.print("已重置到初始提交", OutputType.INFO)
|
|
@@ -329,8 +428,24 @@ class CodeAgent:
|
|
|
329
428
|
self._init_env()
|
|
330
429
|
start_commit = get_latest_commit_hash()
|
|
331
430
|
|
|
431
|
+
# 获取项目统计信息并附加到用户输入
|
|
432
|
+
loc_stats = self.get_loc_stats()
|
|
433
|
+
commits_info = self.get_recent_commits_with_files()
|
|
434
|
+
|
|
435
|
+
project_info = []
|
|
436
|
+
if loc_stats:
|
|
437
|
+
project_info.append(f"代码统计:\n{loc_stats}")
|
|
438
|
+
if commits_info:
|
|
439
|
+
commits_str = "\n".join(
|
|
440
|
+
f"提交 {i+1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)"
|
|
441
|
+
for i, commit in enumerate(commits_info)
|
|
442
|
+
)
|
|
443
|
+
project_info.append(f"最近提交:\n{commits_str}")
|
|
444
|
+
|
|
445
|
+
enhanced_input = f"{user_input}\n\n项目概况:\n" + "\n\n".join(project_info) if project_info else user_input
|
|
446
|
+
|
|
332
447
|
try:
|
|
333
|
-
self.agent.run(
|
|
448
|
+
self.agent.run(enhanced_input)
|
|
334
449
|
except RuntimeError as e:
|
|
335
450
|
PrettyOutput.print(f"执行失败: {str(e)}", OutputType.WARNING)
|
|
336
451
|
return str(e)
|
jarvis/jarvis_dev/main.py
CHANGED
|
@@ -3,7 +3,8 @@ from jarvis.jarvis_multi_agent import MultiAgent
|
|
|
3
3
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
4
4
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
5
5
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
6
|
-
from jarvis.jarvis_utils.
|
|
6
|
+
from jarvis.jarvis_utils.tag import ct, ot
|
|
7
|
+
from jarvis.jarvis_utils.utils import init_env
|
|
7
8
|
|
|
8
9
|
# 定义每个角色的系统提示
|
|
9
10
|
PM_PROMPT = f"""
|
|
@@ -994,7 +995,8 @@ def create_dev_team() -> MultiAgent:
|
|
|
994
995
|
"search_web",
|
|
995
996
|
"execute_script",
|
|
996
997
|
"methodology",
|
|
997
|
-
"ask_codebase"
|
|
998
|
+
"ask_codebase",
|
|
999
|
+
"edit_file",
|
|
998
1000
|
])
|
|
999
1001
|
|
|
1000
1002
|
BA_output_handler = ToolRegistry()
|
|
@@ -1005,7 +1007,8 @@ def create_dev_team() -> MultiAgent:
|
|
|
1005
1007
|
"execute_script",
|
|
1006
1008
|
"read_webpage",
|
|
1007
1009
|
"methodology",
|
|
1008
|
-
"ask_codebase"
|
|
1010
|
+
"ask_codebase",
|
|
1011
|
+
"edit_file",
|
|
1009
1012
|
])
|
|
1010
1013
|
|
|
1011
1014
|
SA_output_handler = ToolRegistry()
|
|
@@ -1015,7 +1018,8 @@ def create_dev_team() -> MultiAgent:
|
|
|
1015
1018
|
"ask_codebase",
|
|
1016
1019
|
"execute_script",
|
|
1017
1020
|
"read_code",
|
|
1018
|
-
"methodology"
|
|
1021
|
+
"methodology",
|
|
1022
|
+
"edit_file",
|
|
1019
1023
|
])
|
|
1020
1024
|
|
|
1021
1025
|
TL_output_handler = ToolRegistry()
|
|
@@ -1025,6 +1029,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
1025
1029
|
"lsp_get_diagnostics",
|
|
1026
1030
|
"execute_script",
|
|
1027
1031
|
"methodology",
|
|
1032
|
+
"edit_file",
|
|
1028
1033
|
])
|
|
1029
1034
|
|
|
1030
1035
|
DEV_output_handler = ToolRegistry()
|
|
@@ -1036,6 +1041,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
1036
1041
|
"read_code",
|
|
1037
1042
|
"create_sub_agent",
|
|
1038
1043
|
"methodology",
|
|
1044
|
+
"edit_file",
|
|
1039
1045
|
])
|
|
1040
1046
|
|
|
1041
1047
|
QA_output_handler = ToolRegistry()
|
|
@@ -1048,6 +1054,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
1048
1054
|
"execute_script",
|
|
1049
1055
|
"read_code",
|
|
1050
1056
|
"methodology",
|
|
1057
|
+
"edit_file",
|
|
1051
1058
|
])
|
|
1052
1059
|
|
|
1053
1060
|
# Update PM prompt with tool usage guidance
|
|
@@ -153,9 +153,10 @@ class GitCommitTool:
|
|
|
153
153
|
except Exception as e:
|
|
154
154
|
spinner.write(f"⚠️ 上传文件时出错: {str(e)}")
|
|
155
155
|
upload_success = False
|
|
156
|
-
|
|
157
156
|
# 根据上传状态准备完整的提示
|
|
158
157
|
if upload_success:
|
|
158
|
+
# 尝试生成提交信息
|
|
159
|
+
spinner.text = "正在生成提交消息..."
|
|
159
160
|
# 使用上传的文件
|
|
160
161
|
prompt = base_prompt + f'''
|
|
161
162
|
# 变更概述
|
|
@@ -164,6 +165,7 @@ class GitCommitTool:
|
|
|
164
165
|
|
|
165
166
|
请详细分析已上传的代码差异文件,生成符合上述格式的提交信息。
|
|
166
167
|
'''
|
|
168
|
+
commit_message = platform.chat_until_success(prompt)
|
|
167
169
|
else:
|
|
168
170
|
# 如果上传失败但内容较大,使用chat_big_content
|
|
169
171
|
if is_large_content and hasattr(platform, 'chat_big_content'):
|
|
@@ -177,14 +179,14 @@ class GitCommitTool:
|
|
|
177
179
|
'''
|
|
178
180
|
commit_message = platform.chat_until_success(prompt)
|
|
179
181
|
|
|
180
|
-
# 尝试生成提交信息
|
|
181
|
-
spinner.text = "正在生成提交消息..."
|
|
182
182
|
while True:
|
|
183
|
-
|
|
183
|
+
# 只在特定情况下重新获取commit_message
|
|
184
|
+
if not upload_success and not is_large_content and not commit_message:
|
|
184
185
|
commit_message = platform.chat_until_success(prompt)
|
|
185
|
-
|
|
186
|
+
extracted_message = self._extract_commit_message(commit_message)
|
|
186
187
|
# 如果成功提取,就跳出循环
|
|
187
|
-
if
|
|
188
|
+
if extracted_message:
|
|
189
|
+
commit_message = extracted_message
|
|
188
190
|
break
|
|
189
191
|
prompt = f"""格式错误,请按照以下格式重新生成提交信息:
|
|
190
192
|
{ot("COMMIT_MESSAGE")}
|
|
@@ -193,6 +195,7 @@ class GitCommitTool:
|
|
|
193
195
|
[可选] 详细描述变更内容和原因
|
|
194
196
|
{ct("COMMIT_MESSAGE")}
|
|
195
197
|
"""
|
|
198
|
+
commit_message = platform.chat_until_success(prompt)
|
|
196
199
|
spinner.write("✅ 生成提交消息")
|
|
197
200
|
|
|
198
201
|
# 执行提交
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
from pydoc import describe
|
|
1
2
|
import re
|
|
2
3
|
from typing import Dict, Any, Tuple
|
|
3
4
|
import os
|
|
4
5
|
|
|
6
|
+
from networkx import descendants
|
|
7
|
+
|
|
5
8
|
from yaspin import yaspin # type: ignore
|
|
6
9
|
|
|
7
10
|
from jarvis.jarvis_agent.output_handler import OutputHandler
|
|
@@ -18,35 +21,15 @@ from jarvis.jarvis_utils.utils import is_context_overflow, get_file_line_count,
|
|
|
18
21
|
from jarvis.jarvis_utils.tag import ot, ct
|
|
19
22
|
|
|
20
23
|
|
|
21
|
-
class PatchOutputHandler
|
|
22
|
-
def name(self) -> str:
|
|
23
|
-
return "PATCH"
|
|
24
|
-
|
|
25
|
-
def handle(self, response: str, agent: Any) -> Tuple[bool, Any]:
|
|
26
|
-
return False, apply_patch(response, agent)
|
|
27
|
-
|
|
28
|
-
def can_handle(self, response: str) -> bool:
|
|
29
|
-
if _has_patch_block(response):
|
|
30
|
-
return True
|
|
31
|
-
return False
|
|
24
|
+
class PatchOutputHandler:
|
|
32
25
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
#
|
|
26
|
+
name = "edit_file"
|
|
27
|
+
description = """代码编辑工具,用于编辑文件
|
|
28
|
+
# 代码编辑规范
|
|
36
29
|
|
|
37
30
|
## 重要提示
|
|
38
31
|
我可以看到完整的代码,所以不需要生成完整的代码,只需要提供修改的代码片段即可。请尽量精简补丁内容,只包含必要的上下文和修改部分。特别注意:不要提供完整文件内容,只提供需要修改的部分!
|
|
39
32
|
|
|
40
|
-
## 补丁格式定义
|
|
41
|
-
使用{ot("PATCH")}块来精确指定代码更改:
|
|
42
|
-
```
|
|
43
|
-
{ot("PATCH")}
|
|
44
|
-
File: [文件路径]
|
|
45
|
-
Reason: [修改原因]
|
|
46
|
-
[代码修改说明,不用输出完整的代码,仅输出修改的片段即可]
|
|
47
|
-
{ct("PATCH")}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
33
|
## 核心原则
|
|
51
34
|
1. **精准修改**:只显示需要修改的代码部分,不需要展示整个文件内容
|
|
52
35
|
2. **最小补丁原则**:始终生成最小范围的补丁,只包含必要的上下文和实际修改
|
|
@@ -71,22 +54,6 @@ Reason: [修改原因]
|
|
|
71
54
|
- 如果原代码行尾没有空格,补丁也不应添加行尾空格
|
|
72
55
|
- 如果原代码使用特定的行尾注释风格,补丁也应保持该风格
|
|
73
56
|
|
|
74
|
-
## 补丁示例
|
|
75
|
-
```
|
|
76
|
-
{ot("PATCH")}
|
|
77
|
-
File: src/utils/math.py
|
|
78
|
-
Reason: 修复除零错误,增加参数验证以提高函数健壮性
|
|
79
|
-
def safe_divide(a, b):
|
|
80
|
-
# 添加参数验证
|
|
81
|
-
if b == 0:
|
|
82
|
-
raise ValueError("除数不能为零")
|
|
83
|
-
return a / b
|
|
84
|
-
# 现有代码 ...
|
|
85
|
-
def add(a, b):
|
|
86
|
-
return a + b
|
|
87
|
-
{ct("PATCH")}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
57
|
## 最佳实践
|
|
91
58
|
- 每个补丁专注于单一职责的修改
|
|
92
59
|
- 避免包含过多无关代码
|
|
@@ -96,77 +63,47 @@ def add(a, b):
|
|
|
96
63
|
- 绝不提供完整文件内容,除非是新建文件
|
|
97
64
|
- 每个文件的修改是独立的,不能出现“参照xxx文件的修改”这样的描述
|
|
98
65
|
- 不要出现未实现的代码,如:TODO
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
result = {}
|
|
110
|
-
patches = re.findall(ot("PATCH")+r'\n?(.*?)\n?' +
|
|
111
|
-
ct("PATCH"), patch_str, re.DOTALL)
|
|
112
|
-
if patches:
|
|
113
|
-
for patch in patches:
|
|
114
|
-
first_line = patch.splitlines()[0]
|
|
115
|
-
sm = re.match(r'^File:\s*(.+)$', first_line)
|
|
116
|
-
if not sm:
|
|
117
|
-
return ({}, f"""无效的补丁格式,正确格式应该为:
|
|
118
|
-
{ot("PATCH")}
|
|
119
|
-
File: [文件路径]
|
|
120
|
-
Reason: [修改原因]
|
|
121
|
-
[代码修改说明,不用输出完整的代码,仅输出修改的片段即可]
|
|
122
|
-
{ct("PATCH")}""")
|
|
123
|
-
filepath = os.path.abspath(sm.group(1).strip())
|
|
124
|
-
if filepath not in result:
|
|
125
|
-
result[filepath] = patch
|
|
126
|
-
else:
|
|
127
|
-
result[filepath] += "\n\n" + patch
|
|
128
|
-
return result, ""
|
|
66
|
+
- 如果要修改的内容较多,请分多次修改
|
|
67
|
+
"""
|
|
68
|
+
parameters = {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"properties": {
|
|
71
|
+
"file": {"type": "string", "description": "文件路径"},
|
|
72
|
+
"reason": {"type": "string", "description": "修改原因"},
|
|
73
|
+
"content": {"type": "string", "description": "补丁内容"}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
129
76
|
|
|
130
77
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
78
|
+
|
|
79
|
+
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
80
|
+
"""Apply patches to files"""
|
|
81
|
+
|
|
82
|
+
from jarvis.jarvis_agent import Agent
|
|
83
|
+
filepath = args["file"]
|
|
84
|
+
patch_content = args["content"]
|
|
85
|
+
agent: Agent = args["agent"]
|
|
86
|
+
|
|
87
|
+
with yaspin(text="正在应用补丁...", color="cyan") as spinner:
|
|
88
|
+
|
|
89
|
+
# 获取当前提交hash作为起始点
|
|
90
|
+
spinner.text = "开始获取当前提交hash..."
|
|
91
|
+
start_hash = get_latest_commit_hash()
|
|
92
|
+
spinner.write("✅ 当前提交hash获取完成")
|
|
93
|
+
|
|
94
|
+
not_read_file = not has_read_file(filepath) and os.path.exists(filepath) and os.path.getsize(filepath) > 0
|
|
95
|
+
if not_read_file:
|
|
96
|
+
spinner.text=f"以下文件未读取: {filepath},应用补丁存在风险,将先读取文件后再生成补丁"
|
|
138
97
|
spinner.fail("❌")
|
|
139
|
-
return
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
# 获取当前提交hash作为起始点
|
|
146
|
-
spinner.text = "开始获取当前提交hash..."
|
|
147
|
-
start_hash = get_latest_commit_hash()
|
|
148
|
-
spinner.write("✅ 当前提交hash获取完成")
|
|
149
|
-
|
|
150
|
-
not_read_file = [
|
|
151
|
-
f for f in patches.keys()
|
|
152
|
-
if not has_read_file(f)
|
|
153
|
-
and os.path.exists(f)
|
|
154
|
-
and os.path.getsize(f) > 0
|
|
155
|
-
]
|
|
156
|
-
if not_read_file:
|
|
157
|
-
spinner.text=f"以下文件未读取: {not_read_file},应用补丁存在风险,将先读取文件后再生成补丁"
|
|
158
|
-
spinner.fail("❌")
|
|
159
|
-
return f"以下文件未读取: {not_read_file},应用补丁存在风险,请先读取文件后再生成补丁"
|
|
98
|
+
return {
|
|
99
|
+
"success": False,
|
|
100
|
+
"stdout": f"以下文件未读取: {filepath},应用补丁存在风险,请先读取文件后再生成补丁",
|
|
101
|
+
"stderr": ""
|
|
102
|
+
}
|
|
160
103
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
for filepath in patches.keys():
|
|
164
|
-
if not _is_file_in_git_repo(filepath):
|
|
165
|
-
in_git_repo = False
|
|
166
|
-
break
|
|
104
|
+
# 检查是否有文件在Git仓库外
|
|
105
|
+
in_git_repo = _is_file_in_git_repo(filepath)
|
|
167
106
|
|
|
168
|
-
# 按文件逐个处理
|
|
169
|
-
for filepath, patch_content in patches.items():
|
|
170
107
|
try:
|
|
171
108
|
spinner.text = f"正在处理文件: {filepath}"
|
|
172
109
|
if not os.path.exists(filepath):
|
|
@@ -188,63 +125,74 @@ def apply_patch(output_str: str, agent: Any) -> str:
|
|
|
188
125
|
revert_file(filepath) # 回滚单个文件
|
|
189
126
|
spinner.write(f"✅ 文件 {filepath} 回滚完成")
|
|
190
127
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
addon_prompt += "如果有任何信息不清楚,调用工具获取信息\n"
|
|
219
|
-
addon_prompt += "每次响应必须且只能包含一个操作\n"
|
|
220
|
-
|
|
221
|
-
agent.set_addon_prompt(addon_prompt)
|
|
128
|
+
final_ret = ""
|
|
129
|
+
if in_git_repo:
|
|
130
|
+
diff = get_diff()
|
|
131
|
+
if diff:
|
|
132
|
+
PrettyOutput.print(diff, OutputType.CODE, lang="diff")
|
|
133
|
+
with spinner.hidden():
|
|
134
|
+
commited = handle_commit_workflow()
|
|
135
|
+
if commited:
|
|
136
|
+
# 获取提交信息
|
|
137
|
+
end_hash = get_latest_commit_hash()
|
|
138
|
+
commits = get_commits_between(start_hash, end_hash)
|
|
139
|
+
|
|
140
|
+
# 添加提交信息到final_ret
|
|
141
|
+
if commits:
|
|
142
|
+
final_ret += "✅ 补丁已应用\n"
|
|
143
|
+
final_ret += "# 提交信息:\n"
|
|
144
|
+
for commit_hash, commit_message in commits:
|
|
145
|
+
final_ret += f"- {commit_hash[:7]}: {commit_message}\n"
|
|
146
|
+
|
|
147
|
+
final_ret += f"# 应用补丁:\n```diff\n{diff}\n```"
|
|
148
|
+
|
|
149
|
+
# 修改后的提示逻辑
|
|
150
|
+
addon_prompt = f"如果用户的需求未完成,请继续生成补丁,如果已经完成,请终止,不要输出新的PATCH,不要实现任何超出用户需求外的内容\n"
|
|
151
|
+
addon_prompt += "如果有任何信息不明确,调用工具获取信息\n"
|
|
152
|
+
addon_prompt += "每次响应必须且只能包含一个操作\n"
|
|
153
|
+
|
|
154
|
+
agent.set_addon_prompt(addon_prompt)
|
|
222
155
|
|
|
156
|
+
else:
|
|
157
|
+
final_ret += "✅ 补丁已应用(没有新的提交)"
|
|
223
158
|
else:
|
|
224
|
-
final_ret += "
|
|
159
|
+
final_ret += "❌ 补丁应用被拒绝\n"
|
|
160
|
+
final_ret += f"# 补丁预览:\n```diff\n{diff}\n```"
|
|
225
161
|
else:
|
|
226
|
-
|
|
227
|
-
final_ret +=
|
|
162
|
+
commited = False
|
|
163
|
+
final_ret += "❌ 没有要提交的更改\n"
|
|
228
164
|
else:
|
|
229
|
-
|
|
230
|
-
final_ret += "
|
|
231
|
-
|
|
232
|
-
#
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
165
|
+
# 对于Git仓库外的文件,直接返回成功
|
|
166
|
+
final_ret += "✅ 补丁已应用(文件不在Git仓库中)"
|
|
167
|
+
commited = True
|
|
168
|
+
# 用户确认最终结果
|
|
169
|
+
with spinner.hidden():
|
|
170
|
+
if commited:
|
|
171
|
+
return {
|
|
172
|
+
"success": True,
|
|
173
|
+
"stdout": final_ret,
|
|
174
|
+
"stderr": ""
|
|
175
|
+
}
|
|
176
|
+
PrettyOutput.print(final_ret, OutputType.USER, lang="markdown")
|
|
177
|
+
if not is_confirm_before_apply_patch() or user_confirm("是否使用此回复?", default=True):
|
|
178
|
+
return {
|
|
179
|
+
"success": True,
|
|
180
|
+
"stdout": final_ret,
|
|
181
|
+
"stderr": ""
|
|
182
|
+
}
|
|
183
|
+
custom_reply = get_multiline_input("请输入自定义回复")
|
|
184
|
+
if not custom_reply.strip(): # 如果自定义回复为空,返回空字符串
|
|
185
|
+
return {
|
|
186
|
+
"success": True,
|
|
187
|
+
"stdout": final_ret,
|
|
188
|
+
"stderr": ""
|
|
189
|
+
}
|
|
190
|
+
agent.set_addon_prompt(custom_reply)
|
|
191
|
+
return {
|
|
192
|
+
"success": True,
|
|
193
|
+
"stdout": final_ret,
|
|
194
|
+
"stderr": ""
|
|
195
|
+
}
|
|
248
196
|
|
|
249
197
|
def _is_file_in_git_repo(filepath: str) -> bool:
|
|
250
198
|
"""检查文件是否在当前Git仓库中"""
|
|
@@ -347,14 +295,36 @@ def handle_commit_workflow() -> bool:
|
|
|
347
295
|
"""Handle the git commit workflow and return the commit details.
|
|
348
296
|
|
|
349
297
|
Returns:
|
|
350
|
-
|
|
298
|
+
bool: 提交是否成功
|
|
351
299
|
"""
|
|
352
300
|
if is_confirm_before_apply_patch() and not user_confirm("是否要提交代码?", default=True):
|
|
353
301
|
revert_change()
|
|
354
302
|
return False
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
303
|
+
|
|
304
|
+
import subprocess
|
|
305
|
+
try:
|
|
306
|
+
# 获取当前分支的提交总数
|
|
307
|
+
commit_count = subprocess.run(
|
|
308
|
+
['git', 'rev-list', '--count', 'HEAD'],
|
|
309
|
+
capture_output=True,
|
|
310
|
+
text=True
|
|
311
|
+
)
|
|
312
|
+
if commit_count.returncode != 0:
|
|
313
|
+
return False
|
|
314
|
+
|
|
315
|
+
commit_count = int(commit_count.stdout.strip())
|
|
316
|
+
|
|
317
|
+
# 暂存所有修改
|
|
318
|
+
subprocess.run(['git', 'add', '.'], check=True)
|
|
319
|
+
|
|
320
|
+
# 提交变更
|
|
321
|
+
subprocess.run(
|
|
322
|
+
['git', 'commit', '-m', f'CheckPoint #{commit_count + 1}'],
|
|
323
|
+
check=True
|
|
324
|
+
)
|
|
325
|
+
return True
|
|
326
|
+
except subprocess.CalledProcessError as e:
|
|
327
|
+
return False
|
|
358
328
|
|
|
359
329
|
|
|
360
330
|
def handle_code_operation(filepath: str, patch_content: str) -> bool:
|
|
@@ -377,7 +347,7 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
|
|
|
377
347
|
model = PlatformRegistry().get_normal_platform()
|
|
378
348
|
file_content = FileOperationTool().execute({"operation":"read", "files":[{"path":filepath}]})["stdout"]
|
|
379
349
|
|
|
380
|
-
model.set_suppress_output(
|
|
350
|
+
model.set_suppress_output(False)
|
|
381
351
|
|
|
382
352
|
prompt = f"""
|
|
383
353
|
# 代码合并专家指南
|
|
@@ -419,7 +389,8 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
|
|
|
419
389
|
finished = False
|
|
420
390
|
while count > 0:
|
|
421
391
|
count -= 1
|
|
422
|
-
|
|
392
|
+
with spinner.hidden():
|
|
393
|
+
response = model.chat_until_success(prompt).splitlines()
|
|
423
394
|
try:
|
|
424
395
|
start_line = response.index(ot("MERGED_CODE")) + 1
|
|
425
396
|
try:
|
|
@@ -481,7 +452,7 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
|
|
|
481
452
|
upload_success = True
|
|
482
453
|
|
|
483
454
|
|
|
484
|
-
model.set_suppress_output(
|
|
455
|
+
model.set_suppress_output(False)
|
|
485
456
|
|
|
486
457
|
main_prompt = f"""
|
|
487
458
|
# 代码补丁生成专家指南
|
|
@@ -513,19 +484,19 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
|
|
|
513
484
|
|
|
514
485
|
## 输出模板
|
|
515
486
|
{ot("DIFF")}
|
|
516
|
-
|
|
487
|
+
{">" * 5} SEARCH
|
|
517
488
|
[需要查找的原始代码,包含足够上下文,避免出现可匹配多处的情况]
|
|
518
489
|
{'='*5}
|
|
519
490
|
[替换后的新代码]
|
|
520
|
-
|
|
491
|
+
{"<" * 5} REPLACE
|
|
521
492
|
{ct("DIFF")}
|
|
522
493
|
|
|
523
494
|
{ot("DIFF")}
|
|
524
|
-
|
|
495
|
+
{">" * 5} SEARCH
|
|
525
496
|
[另一处需要查找的原始代码,包含足够上下文,避免出现可匹配多处的情况]
|
|
526
497
|
{'='*5}
|
|
527
498
|
[另一处替换后的新代码]
|
|
528
|
-
|
|
499
|
+
{"<" * 5} REPLACE
|
|
529
500
|
{ct("DIFF")}
|
|
530
501
|
"""
|
|
531
502
|
|
|
@@ -536,12 +507,15 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
|
|
|
536
507
|
# 原始代码
|
|
537
508
|
{file_content}
|
|
538
509
|
"""
|
|
539
|
-
|
|
510
|
+
with spinner.hidden():
|
|
511
|
+
response = model.chat_until_success(main_prompt + file_prompt)
|
|
540
512
|
else:
|
|
541
513
|
if upload_success:
|
|
542
|
-
|
|
514
|
+
with spinner.hidden():
|
|
515
|
+
response = model.chat_until_success(main_prompt)
|
|
543
516
|
else:
|
|
544
|
-
|
|
517
|
+
with spinner.hidden():
|
|
518
|
+
response = model.chat_big_content(file_content, main_prompt)
|
|
545
519
|
|
|
546
520
|
# 解析差异化补丁
|
|
547
521
|
diff_blocks = re.finditer(ot("DIFF")+r'\s*>{4,} SEARCH\n?(.*?)\n?={4,}\n?(.*?)\s*<{4,} REPLACE\n?'+ct("DIFF"),
|
|
@@ -563,7 +537,6 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
|
|
|
563
537
|
if search_text in modified_content:
|
|
564
538
|
# 如果有多处,报错
|
|
565
539
|
if modified_content.count(search_text) > 1:
|
|
566
|
-
prompt = f"补丁 #{patch_count} 应用失败:找到多个匹配的代码段"
|
|
567
540
|
spinner.write(f"❌ 补丁 #{patch_count} 应用失败:找到多个匹配的代码段")
|
|
568
541
|
success = False
|
|
569
542
|
break
|
|
@@ -573,7 +546,6 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
|
|
|
573
546
|
spinner.write(f"✅ 补丁 #{patch_count} 应用成功")
|
|
574
547
|
else:
|
|
575
548
|
spinner.write(f"❌ 补丁 #{patch_count} 应用失败:无法找到匹配的代码段")
|
|
576
|
-
prompt = f"补丁 #{patch_count} 应用失败:无法找到匹配的代码段"
|
|
577
549
|
success = False
|
|
578
550
|
break
|
|
579
551
|
if not success:
|
jarvis/jarvis_utils/input.py
CHANGED
|
@@ -82,29 +82,20 @@ class FileCompleter(Completer):
|
|
|
82
82
|
# 计算替换长度
|
|
83
83
|
replace_length = len(text_after_at) + 1
|
|
84
84
|
|
|
85
|
-
#
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
# 获取所有可能的补全项
|
|
86
|
+
all_completions = []
|
|
87
|
+
|
|
88
|
+
# 1. 添加特殊标记
|
|
89
|
+
all_completions.extend([
|
|
90
|
+
(ot(tag), self._get_description(tag))
|
|
91
|
+
for tag in self.replace_map.keys()
|
|
92
|
+
])
|
|
93
|
+
all_completions.extend([
|
|
94
94
|
(ot("Summary"), '总结'),
|
|
95
95
|
(ot("Clear"), '清除历史'),
|
|
96
96
|
])
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
text=f"'{name}'",
|
|
100
|
-
start_position=-replace_length,
|
|
101
|
-
display=name,
|
|
102
|
-
display_meta=desc
|
|
103
|
-
) # type: ignore
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
# 使用git ls-files获取所有可能的文件
|
|
107
|
-
all_files = []
|
|
97
|
+
|
|
98
|
+
# 2. 添加文件列表
|
|
108
99
|
try:
|
|
109
100
|
import subprocess
|
|
110
101
|
result = subprocess.run(['git', 'ls-files'],
|
|
@@ -112,28 +103,40 @@ class FileCompleter(Completer):
|
|
|
112
103
|
stderr=subprocess.PIPE,
|
|
113
104
|
text=True)
|
|
114
105
|
if result.returncode == 0:
|
|
115
|
-
|
|
106
|
+
all_completions.extend([
|
|
107
|
+
(path, "File")
|
|
108
|
+
for path in result.stdout.splitlines()
|
|
109
|
+
if path.strip()
|
|
110
|
+
])
|
|
116
111
|
except Exception:
|
|
117
112
|
pass
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
display_text = f"{path} ({score}%)"
|
|
113
|
+
|
|
114
|
+
# 统一过滤和排序
|
|
115
|
+
if file_path:
|
|
116
|
+
# 使用模糊匹配过滤
|
|
117
|
+
scored_items = process.extract(file_path, [item[0] for item in all_completions], limit=self.max_suggestions)
|
|
118
|
+
scored_items = [(item[0], item[1]) for item in scored_items if item[1] > self.min_score]
|
|
119
|
+
# 创建映射以便查找描述
|
|
120
|
+
completion_map = {item[0]: item[1] for item in all_completions}
|
|
121
|
+
# 生成补全项
|
|
122
|
+
for text, score in scored_items:
|
|
123
|
+
display_text = text
|
|
124
|
+
if score < 100:
|
|
125
|
+
display_text = f"{text} ({score}%)"
|
|
132
126
|
yield Completion(
|
|
133
|
-
text=f"'{
|
|
127
|
+
text=f"'{text}'",
|
|
134
128
|
start_position=-replace_length,
|
|
135
129
|
display=display_text,
|
|
136
|
-
display_meta="
|
|
130
|
+
display_meta=completion_map.get(text, "")
|
|
131
|
+
) # type: ignore
|
|
132
|
+
else:
|
|
133
|
+
# 没有输入时返回前max_suggestions个建议
|
|
134
|
+
for text, desc in all_completions[:self.max_suggestions]:
|
|
135
|
+
yield Completion(
|
|
136
|
+
text=f"'{text}'",
|
|
137
|
+
start_position=-replace_length,
|
|
138
|
+
display=text,
|
|
139
|
+
display_meta=desc
|
|
137
140
|
) # type: ignore
|
|
138
141
|
|
|
139
142
|
def _get_description(self, tag: str) -> str:
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
jarvis/__init__.py,sha256=
|
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=
|
|
1
|
+
jarvis/__init__.py,sha256=f8wg5GALz7h8klEribpOjtvP8qwhjEN7ycs1Z0a32JE,50
|
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=RCFx4Hz755PRYI01Y3VoUKXXJCj0pOGrEg4qP099o_g,24745
|
|
3
3
|
jarvis/jarvis_agent/builtin_input_handler.py,sha256=3rRA-7v_VUSFG1s7tTKhriq9vv0nsa3t69ReV0xH5gs,1505
|
|
4
4
|
jarvis/jarvis_agent/file_input_handler.py,sha256=88VqJLe3oO9GtIRsqyx3KwZl10Apob2ddFMH3HQ2RMg,3413
|
|
5
|
-
jarvis/jarvis_agent/jarvis.py,sha256=
|
|
5
|
+
jarvis/jarvis_agent/jarvis.py,sha256=EQDK7CEfoJXg-KkZ7DGDi0lALauFR4tPRvW2O-CxJAQ,5795
|
|
6
6
|
jarvis/jarvis_agent/main.py,sha256=Jlw_Tofh2C-sMVnkeOZBrwWJOWNH3IhsKDUn-WBlgU8,2602
|
|
7
7
|
jarvis/jarvis_agent/output_handler.py,sha256=4limQ-Kf-YYvQjT5SMjJIyyvD1DVG8tINv1A_qbv4ho,405
|
|
8
|
-
jarvis/jarvis_agent/patch.py,sha256=qeRZ6r1qpgHnWpX5uOX4dB3qRCPI1ibk4J50NmoJ74s,23531
|
|
9
8
|
jarvis/jarvis_agent/shell_input_handler.py,sha256=9IoGQCe6FF4HA2V5S11q63AtnWDZFpNeRd3hcqCAlBw,1237
|
|
10
9
|
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
jarvis/jarvis_code_agent/code_agent.py,sha256=
|
|
10
|
+
jarvis/jarvis_code_agent/code_agent.py,sha256=yJbVIyJdEEzm2RpqpeBc0jGFQq9mGVWLBYj9Fco1vR8,18118
|
|
12
11
|
jarvis/jarvis_code_analysis/code_review.py,sha256=gB9Xo0-FT6zciDzZb3jF6zxxWA_Aj8QU5008Tmu_Tr4,30192
|
|
13
12
|
jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=PCjlyxLa939613cAzS7pfEPgP57setO-1RvcdzzPivw,54
|
|
14
13
|
jarvis/jarvis_code_analysis/checklists/c_cpp.py,sha256=8lfWmhImAxeTBdHPOgVXDjMllaq280Qki1ZOOSDBnvk,1293
|
|
@@ -30,12 +29,12 @@ jarvis/jarvis_code_analysis/checklists/shell.py,sha256=UBtGhi3d5sIhyUSGmDckYOXwp
|
|
|
30
29
|
jarvis/jarvis_code_analysis/checklists/sql.py,sha256=-bGfYhaFJyHrbcJrUMbkMyPCNVbk8UljNqebqVJJKxM,2331
|
|
31
30
|
jarvis/jarvis_code_analysis/checklists/swift.py,sha256=d-zPPbM_J1G8fgZ2M2-ASQbIxEocsdL1owL4Z2PCnOc,2542
|
|
32
31
|
jarvis/jarvis_code_analysis/checklists/web.py,sha256=phdvLGqRHNijA0OyEwVtgHgz1Hi4ldtJJscOhEQvbSQ,3919
|
|
33
|
-
jarvis/jarvis_dev/main.py,sha256=
|
|
32
|
+
jarvis/jarvis_dev/main.py,sha256=diznR6kvh0X5kYnZ-lsDIcscgmXV-qatS79FbSWZ3iU,42784
|
|
34
33
|
jarvis/jarvis_git_details/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
34
|
jarvis/jarvis_git_details/main.py,sha256=YowncVxYyJ3y2EvGrZhAJeR4yizXp6aB3dqvoYTepFY,6117
|
|
36
35
|
jarvis/jarvis_git_squash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
36
|
jarvis/jarvis_git_squash/main.py,sha256=xBNkAl7_8_pQC-C6RcUImA1mEU4KTqhjtA57rG_mMJ8,2179
|
|
38
|
-
jarvis/jarvis_git_utils/git_commiter.py,sha256=
|
|
37
|
+
jarvis/jarvis_git_utils/git_commiter.py,sha256=T94R496xYx17sjh4P3RtLqVYZkjB3xz8so8Q1aaei64,11963
|
|
39
38
|
jarvis/jarvis_lsp/base.py,sha256=f-76xgNijfQ4G3Q0t8IfOGtCu-q2TSQ7a_in6XwDb_8,2030
|
|
40
39
|
jarvis/jarvis_lsp/cpp.py,sha256=ekci2M9_UtkCSEe9__72h26Gat93r9_knL2VmFr8X5M,3141
|
|
41
40
|
jarvis/jarvis_lsp/go.py,sha256=sSypuQSP5X2YtrVMC8XCc5nXkgfG93SO7sC89lHzoR8,3458
|
|
@@ -66,6 +65,7 @@ jarvis/jarvis_tools/chdir.py,sha256=do_OdtabiH3lZcT_ynjSAX66XgH2gPl9mYiS7dMMDa8,
|
|
|
66
65
|
jarvis/jarvis_tools/code_plan.py,sha256=jNa2rs4J3Fam8Q_RHE2_QvVch21TPp-Zfv-W6iQ3D_0,7729
|
|
67
66
|
jarvis/jarvis_tools/create_code_agent.py,sha256=SRiQXZf57ViIDh6YSEmJkcoSKft0-y3iDfWF8f1bvZU,3387
|
|
68
67
|
jarvis/jarvis_tools/create_sub_agent.py,sha256=wGiHukvi58wb1AKW5beP7R8VvApOn8TOeGmtXsmcETE,3001
|
|
68
|
+
jarvis/jarvis_tools/edit_file.py,sha256=z9ebYOUUWAkBHf0NVgv6vLZJ2vJzwasdAGWLH0UsuPE,22610
|
|
69
69
|
jarvis/jarvis_tools/execute_script.py,sha256=AeuC3yZIg-nBq_LTIyqxu-lG_uLG63lvwO28A6dRDYA,5715
|
|
70
70
|
jarvis/jarvis_tools/file_analyzer.py,sha256=EVl7WqGgZoaQXqEX8vLynpqZDE3aug1hVBJbycT7YiY,4844
|
|
71
71
|
jarvis/jarvis_tools/file_operation.py,sha256=zbc1zX_aJ-9x1wpuUUbZOgg0aN8f5sd9ryaCQ-bi870,9124
|
|
@@ -84,14 +84,14 @@ jarvis/jarvis_utils/embedding.py,sha256=_Q-VurYHQZSsyISClTFjadDaNqNPBMqJe58lMM6b
|
|
|
84
84
|
jarvis/jarvis_utils/file_processors.py,sha256=oNtVlz2JHcQ60NS6sgI-VsvYXOnsQgFUEVenznCXHC4,2952
|
|
85
85
|
jarvis/jarvis_utils/git_utils.py,sha256=j_Jw6h7JD91XhMf0WD3MAH4URkLUBrrYCLnuLm1GeN4,5630
|
|
86
86
|
jarvis/jarvis_utils/globals.py,sha256=Ed2d6diWXCgI74HVV_tI4qW7yXxLpNvQKN2yG0IH9hc,3388
|
|
87
|
-
jarvis/jarvis_utils/input.py,sha256=
|
|
87
|
+
jarvis/jarvis_utils/input.py,sha256=3mQO_Ys1DGQQWCrw_zD9hnTF4Xd6vyQUrer8IastzvQ,7408
|
|
88
88
|
jarvis/jarvis_utils/methodology.py,sha256=a1QJLqZ-_RwhL6i7C6mixhT1BmOvZ0mKmh3PTOiNT9M,7744
|
|
89
89
|
jarvis/jarvis_utils/output.py,sha256=BmWdB1bmizv0xfU4Z___9p_xQodorriIcEgADVq9fk0,8416
|
|
90
90
|
jarvis/jarvis_utils/tag.py,sha256=YtXBYuZWy8j8YbeQX2qRrHRQl6Gp2Vt7W4p-2yjo0a4,405
|
|
91
91
|
jarvis/jarvis_utils/utils.py,sha256=neokG_C9Djw6shwLcBxpQmRF5KFp9P6v52bMJMEFozg,4487
|
|
92
|
-
jarvis_ai_assistant-0.1.
|
|
93
|
-
jarvis_ai_assistant-0.1.
|
|
94
|
-
jarvis_ai_assistant-0.1.
|
|
95
|
-
jarvis_ai_assistant-0.1.
|
|
96
|
-
jarvis_ai_assistant-0.1.
|
|
97
|
-
jarvis_ai_assistant-0.1.
|
|
92
|
+
jarvis_ai_assistant-0.1.162.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
|
93
|
+
jarvis_ai_assistant-0.1.162.dist-info/METADATA,sha256=W8irlmW5HoenF5m40wSEGoL-jV8EYskUWbvChvq_v7M,12669
|
|
94
|
+
jarvis_ai_assistant-0.1.162.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
|
95
|
+
jarvis_ai_assistant-0.1.162.dist-info/entry_points.txt,sha256=cKz_9SEpOvElTubKPMZMAdskD4GHz-NyKWRNssIVAWE,973
|
|
96
|
+
jarvis_ai_assistant-0.1.162.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
97
|
+
jarvis_ai_assistant-0.1.162.dist-info/RECORD,,
|
|
File without changes
|
{jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.160.dist-info → jarvis_ai_assistant-0.1.162.dist-info}/top_level.txt
RENAMED
|
File without changes
|