jarvis-ai-assistant 0.1.201__py3-none-any.whl → 0.1.203__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
jarvis/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.1.201"
4
+ __version__ = "0.1.203"
@@ -1,6 +1,5 @@
1
1
  import os
2
2
  import re
3
- from abc import ABC, abstractmethod
4
3
  from typing import Any, Dict, List, Tuple
5
4
 
6
5
  from yaspin import yaspin
@@ -8,7 +7,6 @@ from yaspin.core import Yaspin
8
7
 
9
8
  from jarvis.jarvis_agent.output_handler import OutputHandler
10
9
  from jarvis.jarvis_platform.registry import PlatformRegistry
11
- from jarvis.jarvis_tools.file_operation import FileOperationTool
12
10
  from jarvis.jarvis_utils.git_utils import revert_file
13
11
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
14
12
  from jarvis.jarvis_utils.tag import ct, ot
@@ -18,16 +16,16 @@ from jarvis.jarvis_utils.utils import is_context_overflow
18
16
  class EditFileHandler(OutputHandler):
19
17
  def __init__(self):
20
18
  self.patch_pattern = re.compile(
21
- ot("PATCH file=([^>]+)") + r"\s*"
19
+ ot("PATCH file=(?:'([^']+)'|\"([^\"]+)\"|([^>]+))") + r"\s*"
22
20
  r"(?:"
23
21
  + ot("DIFF")
24
22
  + r"\s*"
25
23
  + ot("SEARCH")
26
- + r"\s*(.*?)\s*"
24
+ + r"(.*?)"
27
25
  + ct("SEARCH")
28
26
  + r"\s*"
29
27
  + ot("REPLACE")
30
- + r"\s*(.*?)\s*"
28
+ + r"(.*?)"
31
29
  + ct("REPLACE")
32
30
  + r"\s*"
33
31
  + ct("DIFF")
@@ -39,11 +37,11 @@ class EditFileHandler(OutputHandler):
39
37
  ot("DIFF")
40
38
  + r"\s*"
41
39
  + ot("SEARCH")
42
- + r"\s*(.*?)\s*"
40
+ + r"(.*?)"
43
41
  + ct("SEARCH")
44
42
  + r"\s*"
45
43
  + ot("REPLACE")
46
- + r"\s*(.*?)\s*"
44
+ + r"(.*?)"
47
45
  + ct("REPLACE")
48
46
  + r"\s*"
49
47
  + ct("DIFF"),
@@ -65,12 +63,11 @@ class EditFileHandler(OutputHandler):
65
63
  return False, "未找到有效的文件编辑指令"
66
64
 
67
65
  results = []
68
- overall_success = True
69
66
 
70
67
  for file_path, diffs in patches.items():
71
68
  file_path = os.path.abspath(file_path)
72
69
  file_patches = [
73
- {"search": diff["search"], "replace": diff["replace"]} for diff in diffs
70
+ {"SEARCH": diff["SEARCH"], "REPLACE": diff["REPLACE"]} for diff in diffs
74
71
  ]
75
72
 
76
73
  with yaspin(text=f"正在处理文件 {file_path}...", color="cyan") as spinner:
@@ -110,15 +107,12 @@ class EditFileHandler(OutputHandler):
110
107
  return f"""文件编辑指令格式:
111
108
  {ot("PATCH file=文件路径")}
112
109
  {ot("DIFF")}
113
- {ot("SEARCH")}
114
- 原始代码
115
- {ct("SEARCH")}
116
- {ot("REPLACE")}
117
- 新代码
118
- {ct("REPLACE")}
110
+ {ot("SEARCH")}原始代码{ct("SEARCH")}
111
+ {ot("REPLACE")}新代码{ct("REPLACE")}
119
112
  {ct("DIFF")}
120
113
  {ct("PATCH")}
121
114
 
115
+ 可以返回多个PATCH块用于同时修改多个文件
122
116
  每个PATCH块可以包含多个DIFF块,每个DIFF块包含一组搜索和替换内容。
123
117
  搜索文本必须能在文件中唯一匹配,否则编辑将失败。"""
124
118
 
@@ -136,6 +130,7 @@ class EditFileHandler(OutputHandler):
136
130
  该方法使用正则表达式从响应文本中提取文件编辑指令(PATCH块),
137
131
  每个PATCH块可以包含多个DIFF块,每个DIFF块包含一组搜索和替换内容。
138
132
  解析后会返回一个字典,键是文件路径,值是该文件对应的补丁列表。
133
+ 如果同一个文件路径出现多次,会将所有DIFF块合并到一起。
139
134
 
140
135
  Args:
141
136
  response: 包含补丁信息的响应字符串,格式应符合PATCH指令规范
@@ -145,25 +140,29 @@ class EditFileHandler(OutputHandler):
145
140
  返回解析后的补丁信息字典,结构为:
146
141
  {
147
142
  "文件路径1": [
148
- {"search": "搜索文本1", "replace": "替换文本1"},
149
- {"search": "搜索文本2", "replace": "替换文本2"}
143
+ {"SEARCH": "搜索文本1", "REPLACE": "替换文本1"},
144
+ {"SEARCH": "搜索文本2", "REPLACE": "替换文本2"}
150
145
  ],
151
146
  "文件路径2": [...]
152
147
  }
153
148
  """
154
149
  patches = {}
155
150
  for match in self.patch_pattern.finditer(response):
156
- file_path = match.group(1)
151
+ # Get the file path from the appropriate capture group
152
+ file_path = match.group(1) or match.group(2) or match.group(3)
157
153
  diffs = []
158
154
  for diff_match in self.diff_pattern.finditer(match.group(0)):
159
155
  diffs.append(
160
156
  {
161
- "search": diff_match.group(1).strip(),
162
- "replace": diff_match.group(2).strip(),
157
+ "SEARCH": diff_match.group(1).strip(),
158
+ "REPLACE": diff_match.group(2).strip(),
163
159
  }
164
160
  )
165
161
  if diffs:
166
- patches[file_path] = diffs
162
+ if file_path in patches:
163
+ patches[file_path].extend(diffs)
164
+ else:
165
+ patches[file_path] = diffs
167
166
  return patches
168
167
 
169
168
  @staticmethod
@@ -203,12 +202,16 @@ class EditFileHandler(OutputHandler):
203
202
  modified_content = file_content
204
203
  patch_count = 0
205
204
  for patch in patches:
206
- search_text = patch["search"]
207
- replace_text = patch["replace"]
205
+ search_text = patch["SEARCH"]
206
+ replace_text = patch["REPLACE"]
208
207
  patch_count += 1
209
208
 
210
209
  if search_text in modified_content:
211
210
  if modified_content.count(search_text) > 1:
211
+ PrettyOutput.print(
212
+ f"搜索文本在文件中存在多处匹配:\n{search_text}",
213
+ output_type=OutputType.WARNING,
214
+ )
212
215
  return False, f"搜索文本在文件中存在多处匹配:\n{search_text}"
213
216
  modified_content = modified_content.replace(
214
217
  search_text, replace_text
@@ -228,6 +231,10 @@ class EditFileHandler(OutputHandler):
228
231
  )
229
232
  if indented_search in modified_content:
230
233
  if modified_content.count(indented_search) > 1:
234
+ PrettyOutput.print(
235
+ f"搜索文本在文件中存在多处匹配:\n{indented_search}",
236
+ output_type=OutputType.WARNING,
237
+ )
231
238
  return (
232
239
  False,
233
240
  f"搜索文本在文件中存在多处匹配:\n{indented_search}",
@@ -242,6 +249,10 @@ class EditFileHandler(OutputHandler):
242
249
  break
243
250
 
244
251
  if not found:
252
+ PrettyOutput.print(
253
+ f"搜索文本在文件中不存在:\n{search_text}",
254
+ output_type=OutputType.WARNING,
255
+ )
245
256
  return False, f"搜索文本在文件中不存在:\n{search_text}"
246
257
 
247
258
  # 写入修改后的内容
@@ -312,8 +323,8 @@ class EditFileHandler(OutputHandler):
312
323
  patch_content.append(
313
324
  {
314
325
  "reason": "根据用户指令修改代码",
315
- "search": patch["search"],
316
- "replace": patch["replace"],
326
+ "SEARCH": patch["SEARCH"],
327
+ "REPLACE": patch["REPLACE"],
317
328
  }
318
329
  )
319
330
 
@@ -345,19 +356,13 @@ class EditFileHandler(OutputHandler):
345
356
 
346
357
  ## 输出模板
347
358
  {ot("DIFF")}
348
- {">" * 5} SEARCH
349
- [需要查找的原始代码,包含足够上下文,避免出现可匹配多处的情况]
350
- {'='*5}
351
- [替换后的新代码]
352
- {"<" * 5} REPLACE
359
+ {ot("SEARCH")}[需要查找的原始代码,包含足够上下文,避免出现可匹配多处的情况]{ct("SEARCH")}
360
+ {ot("REPLACE")}[替换后的新代码]{ct("REPLACE")}
353
361
  {ct("DIFF")}
354
362
 
355
363
  {ot("DIFF")}
356
- {">" * 5} SEARCH
357
- [另一处需要查找的原始代码,包含足够上下文,避免出现可匹配多处的情况]
358
- {'='*5}
359
- [另一处替换后的新代码]
360
- {"<" * 5} REPLACE
364
+ {ot("SEARCH")}[另一处需要查找的原始代码,包含足够上下文,避免出现可匹配多处的情况]{ct("SEARCH")}
365
+ {ot("REPLACE")}[另一处替换后的新代码]{ct("REPLACE")}
361
366
  {ct("DIFF")}
362
367
  """
363
368
 
@@ -383,7 +388,14 @@ class EditFileHandler(OutputHandler):
383
388
  diff_blocks = re.finditer(
384
389
  ot("DIFF")
385
390
  + r"\s*"
386
- + r">{4,} SEARCH\n?(.*?)\n?={4,}\n?(.*?)\s*<{4,} REPLACE\n?"
391
+ + ot("SEARCH")
392
+ + r"(.*?)"
393
+ + ct("SEARCH")
394
+ + r"\s*"
395
+ + ot("REPLACE")
396
+ + r"(.*?)"
397
+ + ct("REPLACE")
398
+ + r"\s*"
387
399
  + ct("DIFF"),
388
400
  response,
389
401
  re.DOTALL,
@@ -393,8 +405,8 @@ class EditFileHandler(OutputHandler):
393
405
  for match in diff_blocks:
394
406
  generated_patches.append(
395
407
  {
396
- "search": match.group(1).strip(),
397
- "replace": match.group(2).strip(),
408
+ "SEARCH": match.group(1).strip(),
409
+ "REPLACE": match.group(2).strip(),
398
410
  }
399
411
  )
400
412
 
@@ -82,7 +82,7 @@ class BasePlatform(ABC):
82
82
  while_true(
83
83
  lambda: while_success(
84
84
  lambda: self.chat(
85
- f"<part_content>{input}</part_content>请返回已收到"
85
+ f"<part_content>{input}</part_content>\n\n请返回已收到"
86
86
  ),
87
87
  5,
88
88
  ),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.201
3
+ Version: 0.1.203
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -1,7 +1,7 @@
1
- jarvis/__init__.py,sha256=XoMsxsLPrhfMd065rmFmYUdR1fphq5QSppiLCyiyHnU,75
1
+ jarvis/__init__.py,sha256=6vjQIk71IT0f_EPgzrHvjWl2bp3n_NOJMy-NtNfAZ-g,75
2
2
  jarvis/jarvis_agent/__init__.py,sha256=X5BWIOzxXUWtCbpDkTFfUYskf6sbNzb1qQu8nQ4NN1k,34371
3
3
  jarvis/jarvis_agent/builtin_input_handler.py,sha256=1V7kV5Zhw2HE3Xgjs1R-43RZ2huq3Kg-32NCdNnyZmA,2216
4
- jarvis/jarvis_agent/edit_file_handler.py,sha256=Su25_idE9UCXn3uB2pJV4VisYcUTpeBtmkX9OI3tIIo,15336
4
+ jarvis/jarvis_agent/edit_file_handler.py,sha256=EVEKZUon2CbLHQ1id1_5nka_oGJALGv1k1jmKJva3JA,16478
5
5
  jarvis/jarvis_agent/jarvis.py,sha256=GH2zi8eXNpW8twiY3LKDEZgGmFC5geB0jlkwFrm7hOQ,6279
6
6
  jarvis/jarvis_agent/main.py,sha256=c6bQe-8LXvW2-NBn9Rn_yPYdrwnkJ8KQaSFY2cPvkxw,2775
7
7
  jarvis/jarvis_agent/output_handler.py,sha256=P7oWpXBGFfOsWq7cIhS_z9crkQ19ES7qU5pM92KKjAs,1172
@@ -46,7 +46,7 @@ jarvis/jarvis_methodology/main.py,sha256=NMtd6DRn-Q8NcYtQ3qgTKUp9RW0cDGJod8ZXebl
46
46
  jarvis/jarvis_multi_agent/__init__.py,sha256=sDd3sK88dS7_qAz2ywIAaEWdQ4iRVCiuBu2rQQmrKbU,4512
47
47
  jarvis/jarvis_multi_agent/main.py,sha256=h7VUSwoPrES0XTK8z5kt3XLX1mmcm8UEuFEHQOUWPH4,1696
48
48
  jarvis/jarvis_platform/__init__.py,sha256=WLQHSiE87PPket2M50_hHzjdMIgPIBx2VF8JfB_NNRk,105
49
- jarvis/jarvis_platform/base.py,sha256=69DFeYZjtyvOF12YReLZHQINcW-w-LseogwAYQRff7k,7880
49
+ jarvis/jarvis_platform/base.py,sha256=dv_O3IcUTRhi_jfoRIG2g_FwnYpFRZo8g8tWIanOgVo,7884
50
50
  jarvis/jarvis_platform/human.py,sha256=r8Vlltp_LirJZeZh1Mmi30iJr9tl1JaNFoqthSRHF6o,2826
51
51
  jarvis/jarvis_platform/kimi.py,sha256=uIpSWQ3MqDBYYMROeXin_YqM2LFrovMICKpwLWO1ODo,12784
52
52
  jarvis/jarvis_platform/openai.py,sha256=uEjBikfFj7kp5wondLvOx4WdkmTX0aqF6kixxAufcHg,4806
@@ -91,9 +91,9 @@ jarvis/jarvis_utils/methodology.py,sha256=MhPrMxMqElyAn54BDfpQdUqrRr7IbSlrLvAI39
91
91
  jarvis/jarvis_utils/output.py,sha256=PRCgudPOB8gMEP3u-g0FGD2c6tBgJhLXUMqNPglfjV8,10813
92
92
  jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
93
93
  jarvis/jarvis_utils/utils.py,sha256=RYFQx7OkOu3fe_QhS-5jx7O06k_58X14S-9PFJgwOa4,12178
94
- jarvis_ai_assistant-0.1.201.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
95
- jarvis_ai_assistant-0.1.201.dist-info/METADATA,sha256=EbsPZQI2mPfbeRv6WsJen2ky8nuzILlVZboR0ZaVWBU,20215
96
- jarvis_ai_assistant-0.1.201.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
97
- jarvis_ai_assistant-0.1.201.dist-info/entry_points.txt,sha256=Gy3DOP1PYLMK0GCj4rrP_9lkOyBQ39EK_lKGUSwn41E,869
98
- jarvis_ai_assistant-0.1.201.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
99
- jarvis_ai_assistant-0.1.201.dist-info/RECORD,,
94
+ jarvis_ai_assistant-0.1.203.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
95
+ jarvis_ai_assistant-0.1.203.dist-info/METADATA,sha256=Z2KYARBymf4cu82o1L_vXEo8KXujcOUkbFnb8qZx5Lc,20215
96
+ jarvis_ai_assistant-0.1.203.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
97
+ jarvis_ai_assistant-0.1.203.dist-info/entry_points.txt,sha256=Gy3DOP1PYLMK0GCj4rrP_9lkOyBQ39EK_lKGUSwn41E,869
98
+ jarvis_ai_assistant-0.1.203.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
99
+ jarvis_ai_assistant-0.1.203.dist-info/RECORD,,