jarvis-ai-assistant 0.1.120__py3-none-any.whl → 0.1.121__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 CHANGED
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.120"
3
+ __version__ = "0.1.121"
@@ -222,7 +222,7 @@ Please continue the task based on the above information.
222
222
  if handler.can_handle(response):
223
223
  tool_list.append(handler)
224
224
  if len(tool_list) > 1:
225
- PrettyOutput.print(f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([handler.name() for handler in tool_list])}", OutputType.ERROR)
225
+ PrettyOutput.print(f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([handler.name() for handler in tool_list])}", OutputType.WARNING)
226
226
  return False, f"Action failed: Multiple actions detected. Please only perform one action at a time. Actions attempted: {', '.join([handler.name() for handler in tool_list])}"
227
227
  if len(tool_list) == 0:
228
228
  return False, ""
@@ -376,7 +376,7 @@ def _load_tasks() -> dict:
376
376
  if desc: # Ensure description is not empty
377
377
  tasks[str(name)] = str(desc)
378
378
  else:
379
- PrettyOutput.print("警告: ~/.jarvis/pre-command 文件应该包含一个字典,键为任务名称,值为任务描述", OutputType.ERROR)
379
+ PrettyOutput.print("警告: ~/.jarvis/pre-command 文件应该包含一个字典,键为任务名称,值为任务描述", OutputType.WARNING)
380
380
  except Exception as e:
381
381
  PrettyOutput.print(f"加载 ~/.jarvis/pre-command 文件失败: {str(e)}", OutputType.ERROR)
382
382
 
@@ -392,7 +392,7 @@ def _load_tasks() -> dict:
392
392
  if desc: # Ensure description is not empty
393
393
  tasks[str(name)] = str(desc)
394
394
  else:
395
- PrettyOutput.print("警告: .jarvis/pre-command 文件应该包含一个字典,键为任务名称,值为任务描述", OutputType.ERROR)
395
+ PrettyOutput.print("警告: .jarvis/pre-command 文件应该包含一个字典,键为任务名称,值为任务描述", OutputType.WARNING)
396
396
  except Exception as e:
397
397
  PrettyOutput.print(f"加载 .jarvis/pre-command 文件失败: {str(e)}", OutputType.ERROR)
398
398
 
@@ -231,7 +231,7 @@ def file_input_handler(user_input: str, agent: Any) -> str:
231
231
  file_refs = re.findall(r'`([^`]+)`', user_input)
232
232
 
233
233
  for ref in file_refs:
234
- # Handle file:start,end format
234
+ # Handle file:start,end or file:start:end format
235
235
  if ':' in ref:
236
236
  file_path, line_range = ref.split(':', 1)
237
237
  # Initialize with default values
@@ -239,9 +239,9 @@ def file_input_handler(user_input: str, agent: Any) -> str:
239
239
  end_line = -1
240
240
 
241
241
  # Process line range if specified
242
- if ',' in line_range:
242
+ if ',' in line_range or ':' in line_range:
243
243
  try:
244
- raw_start, raw_end = map(int, line_range.split(','))
244
+ raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
245
245
 
246
246
  # Handle special values and Python-style negative indices
247
247
  with open(file_path, 'r', encoding='utf-8') as f:
@@ -138,6 +138,37 @@ File: src/obsolete.py
138
138
  6. Handle edge cases properly
139
139
  7. Include error handling
140
140
  8. Maintain code consistency
141
+
142
+ # 🚫 Invalid Format Examples
143
+ ## BAD EXAMPLE 1 - Do not use diff format
144
+ <REPLACE>
145
+ File: src/file.py
146
+ Lines: [5,8)
147
+ - old_line_1
148
+ + new_line_1
149
+ </REPLACE>
150
+
151
+ ## BAD EXAMPLE 2 - Do not include previous and new tags
152
+ <REPLACE>
153
+ File: src/file.py
154
+ Lines: [10,12]
155
+ <PREVIOUS>
156
+ old_code
157
+ </PREVIOUS>
158
+ <NEW>
159
+ new_code
160
+ </NEW>
161
+ </REPLACE>
162
+
163
+ ## BAD EXAMPLE 3 - Do not use comment to explain
164
+ <REPLACE>
165
+ File: src/file.py
166
+ Lines: [15,18]
167
+ # Replace the following code
168
+ old_function()
169
+ # With the new implementation
170
+ new_function()
171
+ </REPLACE>
141
172
  """
142
173
 
143
174
 
@@ -164,13 +195,13 @@ def _parse_patch(patch_str: str) -> Dict[str, List[Dict[str, Any]]]:
164
195
  if patch_type in ['REPLACE', 'DELETE']:
165
196
  # 增强正则表达式兼容性
166
197
  line_match = re.match(
167
- r"^Lines:\s*\[\s*(\d+)\s*,\s*(\d+)\s*([\]\)])\s*$", # 匹配行尾
198
+ r"^Lines:\s*\[\s*(\d+)\s*(?:,\s*(\d+)\s*)?([\]\)])\s*$", # 支持单数字格式
168
199
  lines[1].strip(), # 去除前后空格
169
200
  re.IGNORECASE
170
201
  )
171
202
  if line_match:
172
203
  start_line = int(line_match.group(1))
173
- end_value = int(line_match.group(2))
204
+ end_value = int(line_match.group(2) or line_match.group(1)) # 第二个数字不存在时使用第一个
174
205
  bracket_type = line_match.group(3).strip()
175
206
 
176
207
  # 根据括号类型处理区间
@@ -209,7 +240,8 @@ def _parse_patch(patch_str: str) -> Dict[str, List[Dict[str, Any]]]:
209
240
  content_start = 1 # File
210
241
 
211
242
  content_lines = lines[content_start:]
212
- content = '\n'.join(content_lines).strip()
243
+ # 保留原始缩进和空行
244
+ content = '\n'.join(content_lines).rstrip('\n') + '\n' # 保留末尾换行
213
245
 
214
246
  if filepath not in result:
215
247
  result[filepath] = []
@@ -260,7 +292,8 @@ def apply_patch(output_str: str) -> str:
260
292
  continue
261
293
 
262
294
  if has_uncommitted_changes():
263
- if handle_commit_workflow():
295
+ diff = get_diff()
296
+ if handle_commit_workflow(diff):
264
297
  ret += "Successfully applied the patch\n"
265
298
  # Get modified line ranges
266
299
  modified_ranges = get_modified_line_ranges()
@@ -269,25 +302,27 @@ def apply_patch(output_str: str) -> str:
269
302
  ret += "New code:\n"
270
303
  ret += modified_code["stdout"]
271
304
  else:
272
- ret += "User rejected the patch"
273
- user_input = get_multiline_input("你可以继续输入: ")
305
+ ret += "User rejected the patch\nThis is your patch preview:\n"
306
+ ret += diff
307
+ user_input = get_multiline_input("你可以继续输入(输入空行重试,Ctrl+C退出): ")
274
308
  if user_input:
275
309
  ret += "\n" + user_input
276
310
  else:
277
- return ""
311
+ ret += "Please check the patch again"
278
312
 
279
313
  return ret # Ensure a string is always returned
280
-
281
- def handle_commit_workflow()->bool:
314
+
315
+ def get_diff()->str:
316
+ os.system("git add .")
317
+ diff = os.popen("git diff HEAD").read()
318
+ os.system("git reset HEAD")
319
+ return diff
320
+ def handle_commit_workflow(diff:str)->bool:
282
321
  """Handle the git commit workflow and return the commit details.
283
322
 
284
323
  Returns:
285
324
  tuple[bool, str, str]: (continue_execution, commit_id, commit_message)
286
325
  """
287
- os.system("git add .")
288
- diff = os.popen("git diff HEAD").read()
289
- os.system("git reset HEAD")
290
- PrettyOutput.print(diff, OutputType.CODE, lang="diff")
291
326
  if not user_confirm("是否要提交代码?", default=True):
292
327
  os.system("git reset HEAD")
293
328
  os.system("git checkout -- .")
@@ -303,7 +338,7 @@ def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
303
338
 
304
339
  Returns:
305
340
  Dictionary mapping file paths to tuple with (start_line, end_line) ranges
306
- for modified sections. Line numbers are 0-based.
341
+ for modified sections. Line numbers are 1-based.
307
342
  """
308
343
  # Get git diff for all files
309
344
  diff_output = os.popen("git show").read()
@@ -322,13 +357,12 @@ def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
322
357
  # Match lines like "@@ -100,5 +100,7 @@" where the + part shows new lines
323
358
  range_match = re.match(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@", line)
324
359
  if range_match and current_file:
325
- start_line = int(range_match.group(1)) - 1 # Convert to 0-based
360
+ start_line = int(range_match.group(1)) # Keep as 1-based
326
361
  line_count = int(range_match.group(2)) if range_match.group(2) else 1
327
- end_line = start_line + line_count
362
+ end_line = start_line + line_count - 1
328
363
  result[current_file] = (start_line, end_line)
329
364
 
330
365
  return result
331
-
332
366
  # New handler functions below ▼▼▼
333
367
 
334
368
  def handle_move_file(filepath: str, patch: Dict[str, Any]):
@@ -370,7 +404,7 @@ def handle_code_operation(filepath: str, patch: Dict[str, Any]):
370
404
  if not new_content:
371
405
  new_content = ['']
372
406
 
373
- PrettyOutput.print(f"patch_type: {patch_type}\nstart_line: {start_line}\nend_line: {end_line}\nnew_content:\n{new_content}", OutputType.INFO)
407
+ PrettyOutput.print(f"patch_type: {patch_type}\nstart_line: {start_line}\nend_line: {end_line}\nnew_content:\n{''.join(new_content)}", OutputType.INFO)
374
408
 
375
409
  if new_content and new_content[-1] and new_content[-1][-1] != '\n':
376
410
  new_content[-1] += '\n'
@@ -336,7 +336,7 @@ Content: {content}
336
336
  vectors = np.vstack(vectors)
337
337
  if len(vectors) != len(ids):
338
338
  PrettyOutput.print(f"向量数量不匹配: {len(vectors)} 个向量 vs {len(ids)} 个ID",
339
- output_type=OutputType.ERROR)
339
+ output_type=OutputType.WARNING)
340
340
  self.index = None
341
341
  return
342
342
 
@@ -441,7 +441,7 @@ Content: {content}
441
441
  output_lines.append("删除的文件:")
442
442
  output_lines.extend(f" {f}" for f in deleted_files)
443
443
 
444
- PrettyOutput.print("\n".join(output_lines), output_type=OutputType.WARNING)
444
+ PrettyOutput.print("\n".join(output_lines), output_type=OutputType.INFO)
445
445
 
446
446
  # If force is True, continue directly
447
447
  if not force:
@@ -59,8 +59,8 @@ class LSPRegistry:
59
59
 
60
60
  if missing_methods:
61
61
  PrettyOutput.print(
62
- f"LSP {lsp_class.__name__} is missing necessary methods: {', '.join(missing_methods)}",
63
- OutputType.ERROR
62
+ f"LSP {lsp_class.__name__} 缺少必要的方法: {', '.join(missing_methods)}",
63
+ OutputType.WARNING
64
64
  )
65
65
  return False
66
66
 
@@ -72,7 +72,7 @@ class LSPRegistry:
72
72
  lsp_servers = {}
73
73
 
74
74
  if not os.path.exists(directory):
75
- PrettyOutput.print(f"LSP 目录不存在: {directory}", OutputType.ERROR)
75
+ PrettyOutput.print(f"LSP 目录不存在: {directory}", OutputType.WARNING)
76
76
  return lsp_servers
77
77
 
78
78
  package_name = None
@@ -138,7 +138,7 @@ class LSPRegistry:
138
138
  def create_lsp(self, language: str) -> Optional[BaseLSP]:
139
139
  """Create LSP instance for specified language."""
140
140
  if language not in self.lsp_servers:
141
- PrettyOutput.print(f"没有找到 LSP 支持的语言: {language}", OutputType.ERROR)
141
+ PrettyOutput.print(f"没有找到 LSP 支持的语言: {language}", OutputType.WARNING)
142
142
  return None
143
143
 
144
144
  try:
@@ -186,11 +186,11 @@ def main():
186
186
  lsp = registry.create_lsp(args.language)
187
187
 
188
188
  if not lsp:
189
- PrettyOutput.print(f"没有 LSP 支持的语言: {args.language}", OutputType.ERROR)
189
+ PrettyOutput.print(f"没有 LSP 支持的语言: {args.language}", OutputType.WARNING)
190
190
  return 1
191
191
 
192
192
  if not lsp.initialize(os.path.dirname(os.path.abspath(args.file))):
193
- PrettyOutput.print("LSP 初始化失败", OutputType.ERROR)
193
+ PrettyOutput.print("LSP 初始化失败", OutputType.WARNING)
194
194
  return 1
195
195
 
196
196
  try:
@@ -208,7 +208,7 @@ def main():
208
208
 
209
209
  elif args.action in ('references', 'definition'):
210
210
  if args.line is None or args.character is None:
211
- PrettyOutput.print("需要行和字符位置用于 references/definition", OutputType.ERROR)
211
+ PrettyOutput.print("需要行和字符位置用于 references/definition", OutputType.WARNING)
212
212
  return 1
213
213
 
214
214
  if args.action == 'references':
@@ -60,12 +60,12 @@ class AI8Model(BasePlatform):
60
60
  )
61
61
 
62
62
  if response.status_code != 200:
63
- PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.ERROR)
63
+ PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.WARNING)
64
64
  return False
65
65
 
66
66
  data = response.json()
67
67
  if data['code'] != 0:
68
- PrettyOutput.print(f"创建会话失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
68
+ PrettyOutput.print(f"创建会话失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
69
69
  return False
70
70
 
71
71
  self.conversation = data['data']
@@ -93,10 +93,10 @@ class AI8Model(BasePlatform):
93
93
  self.conversation = data['data']
94
94
  return True
95
95
  else:
96
- PrettyOutput.print(f"更新会话设置失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
96
+ PrettyOutput.print(f"更新会话设置失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
97
97
  return False
98
98
  else:
99
- PrettyOutput.print(f"更新会话设置失败: {response.status_code}", OutputType.ERROR)
99
+ PrettyOutput.print(f"更新会话设置失败: {response.status_code}", OutputType.WARNING)
100
100
  return False
101
101
 
102
102
  except Exception as e:
@@ -162,7 +162,7 @@ class AI8Model(BasePlatform):
162
162
 
163
163
  if response.status_code != 200:
164
164
  error_msg = f"Failed to chat: {response.status_code} {response.text}"
165
- PrettyOutput.print(error_msg, OutputType.ERROR)
165
+ PrettyOutput.print(error_msg, OutputType.WARNING)
166
166
  raise Exception(error_msg)
167
167
 
168
168
  # 处理流式响应
@@ -229,11 +229,11 @@ class AI8Model(BasePlatform):
229
229
  return True
230
230
  else:
231
231
  error_msg = f"删除会话失败: {data.get('msg', '未知错误')}"
232
- PrettyOutput.print(error_msg, OutputType.ERROR)
232
+ PrettyOutput.print(error_msg, OutputType.WARNING)
233
233
  return False
234
234
  else:
235
235
  error_msg = f"删除会话请求失败: {response.status_code}"
236
- PrettyOutput.print(error_msg, OutputType.ERROR)
236
+ PrettyOutput.print(error_msg, OutputType.WARNING)
237
237
  return False
238
238
 
239
239
  except Exception as e:
@@ -265,12 +265,12 @@ class AI8Model(BasePlatform):
265
265
  )
266
266
 
267
267
  if response.status_code != 200:
268
- PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.ERROR)
268
+ PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.WARNING)
269
269
  return []
270
270
 
271
271
  data = response.json()
272
272
  if data['code'] != 0:
273
- PrettyOutput.print(f"获取模型列表失败: {data.get('msg', '未知错误')}", OutputType.ERROR)
273
+ PrettyOutput.print(f"获取模型列表失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
274
274
  return []
275
275
 
276
276
  # 保存模型信息
@@ -309,6 +309,6 @@ class AI8Model(BasePlatform):
309
309
  return list(self.models.keys())
310
310
 
311
311
  except Exception as e:
312
- PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.WARNING)
312
+ PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.ERROR)
313
313
  return []
314
314
 
@@ -198,11 +198,11 @@ class KimiModel(BasePlatform):
198
198
  if self._wait_for_parse(file_info["id"]):
199
199
  uploaded_files.append(file_info)
200
200
  else:
201
- PrettyOutput.print(f"✗ 文件解析失败: {file_path}", OutputType.ERROR)
201
+ PrettyOutput.print(f"✗ 文件解析失败: {file_path}", OutputType.WARNING)
202
202
  else:
203
203
  uploaded_files.append(file_info)
204
204
  else:
205
- PrettyOutput.print(f"错误:文件上传失败: {file_path}", OutputType.ERROR)
205
+ PrettyOutput.print(f"错误:文件上传失败: {file_path}", OutputType.WARNING)
206
206
 
207
207
  except Exception as e:
208
208
  PrettyOutput.print(f"✗ 处理文件出错 {file_path}: {str(e)}", OutputType.ERROR)
@@ -375,7 +375,7 @@ class KimiModel(BasePlatform):
375
375
  self.reset()
376
376
  return True
377
377
  else:
378
- PrettyOutput.print(f"删除会话失败: HTTP {response.status_code}", OutputType.ERROR)
378
+ PrettyOutput.print(f"删除会话失败: HTTP {response.status_code}", OutputType.WARNING)
379
379
  return False
380
380
  except Exception as e:
381
381
  PrettyOutput.print(f"删除会话时发生错误: {str(e)}", OutputType.ERROR)
@@ -83,10 +83,10 @@ class OyiModel(BasePlatform):
83
83
  self.conversation = data
84
84
  return True
85
85
  else:
86
- PrettyOutput.print(f"创建会话失败: {data['message']}", OutputType.ERROR)
86
+ PrettyOutput.print(f"创建会话失败: {data['message']}", OutputType.WARNING)
87
87
  return False
88
88
  else:
89
- PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.ERROR)
89
+ PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.WARNING)
90
90
  return False
91
91
 
92
92
  except Exception as e:
@@ -157,13 +157,13 @@ class OyiModel(BasePlatform):
157
157
 
158
158
  if response.status_code != 200:
159
159
  error_msg = f"聊天请求失败: {response.status_code}"
160
- PrettyOutput.print(error_msg, OutputType.ERROR)
160
+ PrettyOutput.print(error_msg, OutputType.WARNING)
161
161
  raise Exception(error_msg)
162
162
 
163
163
  data = response.json()
164
164
  if data['code'] != 200 or data['type'] != 'success':
165
165
  error_msg = f"聊天失败: {data.get('message', '未知错误')}"
166
- PrettyOutput.print(error_msg, OutputType.ERROR)
166
+ PrettyOutput.print(error_msg, OutputType.WARNING)
167
167
  raise Exception(error_msg)
168
168
 
169
169
  message_id = data['result'][-1]
@@ -196,7 +196,7 @@ class OyiModel(BasePlatform):
196
196
  return full_response
197
197
  else:
198
198
  error_msg = f"获取响应失败: {response.status_code}"
199
- PrettyOutput.print(error_msg, OutputType.ERROR)
199
+ PrettyOutput.print(error_msg, OutputType.WARNING)
200
200
  raise Exception(error_msg)
201
201
  except Exception as e:
202
202
  PrettyOutput.print(f"聊天失败: {str(e)}", OutputType.ERROR)
@@ -241,11 +241,11 @@ class OyiModel(BasePlatform):
241
241
  return True
242
242
  else:
243
243
  error_msg = f"删除会话失败: {data.get('message', '未知错误')}"
244
- PrettyOutput.print(error_msg, OutputType.ERROR)
244
+ PrettyOutput.print(error_msg, OutputType.WARNING)
245
245
  return False
246
246
  else:
247
247
  error_msg = f"删除会话请求失败: {response.status_code}"
248
- PrettyOutput.print(error_msg, OutputType.ERROR)
248
+ PrettyOutput.print(error_msg, OutputType.WARNING)
249
249
  return False
250
250
 
251
251
  except Exception as e:
@@ -281,7 +281,7 @@ class OyiModel(BasePlatform):
281
281
  # 检查文件类型
282
282
  file_type = mimetypes.guess_type(file_path)[0]
283
283
  if not file_type or not file_type.startswith(('image/', 'text/', 'application/')):
284
- PrettyOutput.print(f"文件类型 {file_type} 不支持", OutputType.ERROR)
284
+ PrettyOutput.print(f"文件类型 {file_type} 不支持", OutputType.WARNING)
285
285
  continue
286
286
 
287
287
  with open(file_path, 'rb') as f:
@@ -300,10 +300,10 @@ class OyiModel(BasePlatform):
300
300
  if data.get('code') == 200:
301
301
  self.files.append(data)
302
302
  else:
303
- PrettyOutput.print(f"文件上传失败: {data.get('message')}", OutputType.ERROR)
303
+ PrettyOutput.print(f"文件上传失败: {data.get('message')}", OutputType.WARNING)
304
304
  return []
305
305
  else:
306
- PrettyOutput.print(f"文件上传失败: {response.status_code}", OutputType.ERROR)
306
+ PrettyOutput.print(f"文件上传失败: {response.status_code}", OutputType.WARNING)
307
307
  return []
308
308
 
309
309
  return self.files
@@ -335,7 +335,7 @@ class OyiModel(BasePlatform):
335
335
  )
336
336
 
337
337
  if response.status_code != 200:
338
- PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.ERROR)
338
+ PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.WARNING)
339
339
  return []
340
340
 
341
341
  data = response.json()
@@ -72,7 +72,7 @@ class PlatformRegistry:
72
72
  if missing_methods:
73
73
  PrettyOutput.print(
74
74
  f"平台 {platform_class.__name__} 缺少必要的方法: {', '.join(missing_methods)}",
75
- OutputType.ERROR
75
+ OutputType.WARNING
76
76
  )
77
77
  return False
78
78
 
@@ -92,7 +92,7 @@ class PlatformRegistry:
92
92
 
93
93
  # 确保目录存在
94
94
  if not os.path.exists(directory):
95
- PrettyOutput.print(f"平台目录不存在: {directory}", OutputType.ERROR)
95
+ PrettyOutput.print(f"平台目录不存在: {directory}", OutputType.WARNING)
96
96
  return platforms
97
97
 
98
98
  # 获取目录的包名
@@ -201,7 +201,7 @@ class PlatformRegistry:
201
201
  BasePlatform: Platform instance
202
202
  """
203
203
  if name not in self.platforms:
204
- PrettyOutput.print(f"未找到平台: {name}", OutputType.ERROR)
204
+ PrettyOutput.print(f"未找到平台: {name}", OutputType.WARNING)
205
205
  return None
206
206
 
207
207
  try:
@@ -55,7 +55,7 @@ def chat_with_model(platform_name: str, model_name: str):
55
55
  # Create platform instance
56
56
  platform = registry.create_platform(platform_name)
57
57
  if not platform:
58
- PrettyOutput.print(f"创建平台 {platform_name} 失败", OutputType.ERROR)
58
+ PrettyOutput.print(f"创建平台 {platform_name} 失败", OutputType.WARNING)
59
59
  return
60
60
 
61
61
  try:
@@ -108,7 +108,7 @@ def chat_with_model(platform_name: str, model_name: str):
108
108
  # Helper function for platform and model validation
109
109
  def validate_platform_model(args):
110
110
  if not args.platform or not args.model:
111
- PrettyOutput.print("请指定平台和模型。使用 'jarvis info' 查看可用平台和模型。", OutputType.ERROR)
111
+ PrettyOutput.print("请指定平台和模型。使用 'jarvis info' 查看可用平台和模型。", OutputType.WARNING)
112
112
  return False
113
113
  return True
114
114
 
@@ -89,7 +89,7 @@ def main():
89
89
  if result["success"]:
90
90
  PrettyOutput.print(result["stdout"], OutputType.INFO, lang="markdown")
91
91
  else:
92
- PrettyOutput.print(result["stderr"], OutputType.ERROR)
92
+ PrettyOutput.print(result["stderr"], OutputType.WARNING)
93
93
 
94
94
 
95
95
  if __name__ == "__main__":
@@ -241,7 +241,7 @@ def main():
241
241
  PrettyOutput.print(report, OutputType.SUCCESS, lang="yaml")
242
242
 
243
243
  else:
244
- PrettyOutput.print(result["stderr"], OutputType.ERROR)
244
+ PrettyOutput.print(result["stderr"], OutputType.WARNING)
245
245
 
246
246
  if __name__ == "__main__":
247
247
  main()
@@ -109,7 +109,7 @@ def main():
109
109
  if result["success"]:
110
110
  PrettyOutput.print(result["stdout"], OutputType.SUCCESS)
111
111
  else:
112
- PrettyOutput.print(result["stderr"], OutputType.ERROR)
112
+ PrettyOutput.print(result["stderr"], OutputType.WARNING)
113
113
 
114
114
  if __name__ == "__main__":
115
115
  main()
@@ -1,9 +1,9 @@
1
1
  import os
2
2
  import re
3
3
  import shlex
4
+ import subprocess
4
5
  from typing import Dict, Any
5
6
  import tempfile
6
-
7
7
  import yaml
8
8
  from jarvis.jarvis_platform.registry import PlatformRegistry
9
9
  from jarvis.jarvis_utils import OutputType, PrettyOutput, has_uncommitted_changes, init_env
@@ -27,7 +27,13 @@ class GitCommitTool:
27
27
  return "<<FORMAT VIOLATION>> Invalid commit message structure"
28
28
 
29
29
  def _get_last_commit_hash(self):
30
- return os.popen("git log -1 --pretty=%H").read().strip()
30
+ process = subprocess.Popen(
31
+ ["git", "log", "-1", "--pretty=%H"],
32
+ stdout=subprocess.PIPE,
33
+ stderr=subprocess.PIPE
34
+ )
35
+ stdout, _ = process.communicate()
36
+ return stdout.decode().strip()
31
37
 
32
38
  def execute(self, args: Dict) -> Dict[str, Any]:
33
39
  """Execute automatic commit process with support for multi-line messages and special characters"""
@@ -37,10 +43,19 @@ class GitCommitTool:
37
43
  return {"success": True, "stdout": "No changes to commit", "stderr": ""}
38
44
 
39
45
  PrettyOutput.print("准备添加文件到提交...", OutputType.SYSTEM)
40
- os.system("git add .")
46
+ subprocess.Popen(
47
+ ["git", "add", "."],
48
+ stdout=subprocess.DEVNULL,
49
+ stderr=subprocess.DEVNULL
50
+ ).wait()
41
51
 
42
52
  PrettyOutput.print("获取差异...", OutputType.SYSTEM)
43
- diff = os.popen("git diff --cached --exit-code").read()
53
+ process = subprocess.Popen(
54
+ ["git", "diff", "--cached", "--exit-code"],
55
+ stdout=subprocess.PIPE,
56
+ stderr=subprocess.PIPE
57
+ )
58
+ diff = process.communicate()[0].decode()
44
59
  PrettyOutput.print(diff, OutputType.CODE, lang="diff")
45
60
 
46
61
  prompt = f'''Generate commit message with the paranoia of someone who's lost production data:
@@ -69,7 +84,7 @@ YOU MUST USE EXACTLY THIS FORMAT:
69
84
 
70
85
  PrettyOutput.print("生成提交消息...", OutputType.SYSTEM)
71
86
  platform = PlatformRegistry().get_codegen_platform()
72
- # platform.set_suppress_output(True)
87
+ platform.set_suppress_output(True)
73
88
  commit_message = platform.chat_until_success(prompt)
74
89
  commit_message = self._extract_commit_message(commit_message)
75
90
 
@@ -77,9 +92,13 @@ YOU MUST USE EXACTLY THIS FORMAT:
77
92
  with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_file:
78
93
  tmp_file.write(commit_message)
79
94
  tmp_file.flush() # 确保内容写入文件
80
- commit_cmd = f"git commit -F {tmp_file.name}"
95
+ commit_cmd = ["git", "commit", "-F", tmp_file.name]
81
96
  PrettyOutput.print("提交...", OutputType.INFO)
82
- os.system(commit_cmd)
97
+ subprocess.Popen(
98
+ commit_cmd,
99
+ stdout=subprocess.DEVNULL,
100
+ stderr=subprocess.DEVNULL
101
+ ).wait()
83
102
 
84
103
  commit_hash = self._get_last_commit_hash()
85
104
  PrettyOutput.print(f"提交哈希: {commit_hash}\n提交消息: {commit_message}", OutputType.SUCCESS)
@@ -135,7 +135,7 @@ def main():
135
135
  if result["success"]:
136
136
  PrettyOutput.print(f"{result['stdout']}", OutputType.INFO, lang="markdown")
137
137
  else:
138
- PrettyOutput.print(result["stderr"], OutputType.ERROR)
138
+ PrettyOutput.print(result["stderr"], OutputType.WARNING)
139
139
 
140
140
  if __name__ == "__main__":
141
141
  main()
@@ -23,9 +23,11 @@ import psutil
23
23
  from rich.console import Console
24
24
  from rich.theme import Theme
25
25
  from rich.panel import Panel
26
+ from rich.box import HEAVY
26
27
  from rich.text import Text
27
28
  from rich.traceback import install as install_rich_traceback
28
29
  from rich.syntax import Syntax
30
+ from rich.style import Style as RichStyle
29
31
 
30
32
  from prompt_toolkit.completion import Completer, Completion, PathCompleter
31
33
  from prompt_toolkit.document import Document
@@ -45,18 +47,18 @@ install_rich_traceback()
45
47
 
46
48
  # Create console with custom theme
47
49
  custom_theme = Theme({
48
- "info": "yellow",
49
- "warning": "yellow",
50
- "error": "red",
51
- "success": "green",
52
- "system": "cyan",
53
- "code": "green",
54
- "result": "blue",
55
- "planning": "magenta",
56
- "progress": "white",
57
- "debug": "blue",
58
- "user": "green",
59
- "tool": "yellow",
50
+ "INFO": "yellow",
51
+ "WARNING": "yellow",
52
+ "ERROR": "red",
53
+ "SUCCESS": "green",
54
+ "SYSTEM": "cyan",
55
+ "CODE": "green",
56
+ "RESULT": "blue",
57
+ "PLANNING": "magenta",
58
+ "PROGRESS": "white",
59
+ "DEBUG": "blue",
60
+ "USER": "green",
61
+ "TOOL": "yellow",
60
62
  })
61
63
 
62
64
  console = Console(theme=custom_theme)
@@ -76,7 +78,7 @@ def set_agent(agent_name: str, agent: Any):
76
78
  current_agent_name = agent_name
77
79
 
78
80
  def get_agent_list():
79
- return "[" + str(len(global_agents)) + "]" + current_agent_name if global_agents else "No Agent"
81
+ return "[" + str(len(global_agents)) + "]" + current_agent_name if global_agents else ""
80
82
 
81
83
  def delete_agent(agent_name: str):
82
84
  if agent_name in global_agents:
@@ -85,18 +87,18 @@ def delete_agent(agent_name: str):
85
87
  current_agent_name = ""
86
88
 
87
89
  class OutputType(Enum):
88
- SYSTEM = "system" # AI assistant message
89
- CODE = "code" # Code related
90
- RESULT = "result" # Tool execution result
91
- ERROR = "error" # Error information
92
- INFO = "info" # System prompt
93
- PLANNING = "planning" # Task planning
94
- PROGRESS = "progress" # Execution progress
95
- SUCCESS = "success" # Success information
96
- WARNING = "warning" # Warning information
97
- DEBUG = "debug" # Debug information
98
- USER = "user" # User input
99
- TOOL = "tool" # Tool call
90
+ SYSTEM = "SYSTEM" # AI assistant message
91
+ CODE = "CODE" # Code related
92
+ RESULT = "RESULT" # Tool execution result
93
+ ERROR = "ERROR" # Error information
94
+ INFO = "INFO" # System prompt
95
+ PLANNING = "PLANNING" # Task planning
96
+ PROGRESS = "PROGRESS" # Execution progress
97
+ SUCCESS = "SUCCESS" # Success information
98
+ WARNING = "WARNING" # Warning information
99
+ DEBUG = "DEBUG" # Debug information
100
+ USER = "USER" # User input
101
+ TOOL = "TOOL" # Tool call
100
102
 
101
103
  class PrettyOutput:
102
104
  """Pretty output using rich"""
@@ -164,18 +166,18 @@ class PrettyOutput:
164
166
  return default_lang
165
167
 
166
168
  @staticmethod
167
- def _format(text: str, output_type: OutputType, timestamp: bool = True) -> Text:
169
+ def _format(output_type: OutputType, timestamp: bool = True) -> Text:
168
170
  """Format output text using rich Text"""
169
171
  # Create rich Text object
170
172
  formatted = Text()
171
173
 
172
174
  # Add timestamp and agent info
173
175
  if timestamp:
174
- formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}] ", style="white")
175
- formatted.append(f"{get_agent_list()}", style="blue")
176
+ formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}][{output_type.value}]", style=output_type.value)
177
+ formatted.append(f"[{get_agent_list()}]", style="blue")
176
178
  # Add icon
177
179
  icon = PrettyOutput._ICONS.get(output_type, "")
178
- formatted.append(f"{icon} ", style=output_type.value)
180
+ formatted.append(f" {icon} ", style=output_type.value)
179
181
 
180
182
  return formatted
181
183
 
@@ -190,27 +192,88 @@ class PrettyOutput:
190
192
  lang: Language for syntax highlighting
191
193
  traceback: Whether to show traceback for errors
192
194
  """
193
- from rich.style import Style as RichStyle
195
+
194
196
 
195
197
  # Define styles for different output types
196
198
  styles = {
197
- OutputType.SYSTEM: RichStyle(color="cyan", bold=True),
198
- OutputType.CODE: RichStyle(color="green"),
199
- OutputType.RESULT: RichStyle(color="blue"),
200
- OutputType.ERROR: RichStyle(color="red", bold=True),
201
- OutputType.INFO: RichStyle(color="yellow"),
202
- OutputType.PLANNING: RichStyle(color="magenta"),
203
- OutputType.PROGRESS: RichStyle(color="white"),
204
- OutputType.SUCCESS: RichStyle(color="green", bold=True),
205
- OutputType.WARNING: RichStyle(color="yellow", bold=True),
206
- OutputType.DEBUG: RichStyle(color="blue", dim=True),
207
- OutputType.USER: RichStyle(color="green"),
208
- OutputType.TOOL: RichStyle(color="yellow", italic=True)
199
+ OutputType.SYSTEM: RichStyle(
200
+ color="bright_cyan",
201
+ italic=True,
202
+ bold=True,
203
+ ),
204
+ OutputType.CODE: RichStyle(
205
+ color="green",
206
+ italic=True,
207
+ bgcolor="#1a1a1a",
208
+ frame=True
209
+ ),
210
+ OutputType.RESULT: RichStyle(
211
+ color="bright_blue",
212
+ bold=True,
213
+ italic=True,
214
+ overline=True,
215
+ bgcolor="navy_blue"
216
+ ),
217
+ OutputType.ERROR: RichStyle(
218
+ color="red",
219
+ bold=True,
220
+ italic=True,
221
+ blink=True,
222
+ bgcolor="dark_red",
223
+ ),
224
+ OutputType.INFO: RichStyle(
225
+ color="gold1",
226
+ dim=True,
227
+ bgcolor="grey11",
228
+ italic=True
229
+ ),
230
+ OutputType.PLANNING: RichStyle(
231
+ color="purple",
232
+ italic=True,
233
+ bold=True,
234
+ ),
235
+ OutputType.PROGRESS: RichStyle(
236
+ color="white",
237
+ encircle=True,
238
+ italic=True,
239
+ ),
240
+ OutputType.SUCCESS: RichStyle(
241
+ color="bright_green",
242
+ bold=True,
243
+ strike=False,
244
+ meta={"icon": "✓"},
245
+ italic=True
246
+ ),
247
+ OutputType.WARNING: RichStyle(
248
+ color="yellow",
249
+ bold=True,
250
+ blink2=True,
251
+ bgcolor="dark_orange",
252
+ italic=True
253
+ ),
254
+ OutputType.DEBUG: RichStyle(
255
+ color="grey58",
256
+ dim=True,
257
+ italic=True,
258
+ conceal=True
259
+ ),
260
+ OutputType.USER: RichStyle(
261
+ color="spring_green2",
262
+ reverse=True,
263
+ frame=True,
264
+ italic=True
265
+ ),
266
+ OutputType.TOOL: RichStyle(
267
+ color="dark_sea_green4",
268
+ italic=True,
269
+ bgcolor="grey19",
270
+ overline=True
271
+ )
209
272
  }
210
273
 
211
274
  # Get formatted header
212
275
  lang = lang if lang is not None else PrettyOutput._detect_language(text, default_lang='markdown')
213
- header = PrettyOutput._format("", output_type, timestamp)
276
+ header = PrettyOutput._format(output_type, timestamp)
214
277
 
215
278
  # Create syntax highlighted content
216
279
  content = Syntax(
@@ -218,7 +281,6 @@ class PrettyOutput:
218
281
  lang,
219
282
  theme="monokai",
220
283
  word_wrap=True,
221
- background_color="default"
222
284
  )
223
285
 
224
286
  # Create panel with styling
@@ -229,7 +291,8 @@ class PrettyOutput:
229
291
  title=header,
230
292
  title_align="left",
231
293
  padding=(0, 0),
232
- highlight=True
294
+ highlight=True,
295
+ box=HEAVY,
233
296
  )
234
297
 
235
298
  # Print panel
@@ -253,12 +316,22 @@ class PrettyOutput:
253
316
  @staticmethod
254
317
  def print_stream(text: str):
255
318
  """Print stream output without line break"""
256
- console.print(text, style="system", end="")
319
+ # 使用进度类型样式
320
+ style = PrettyOutput._get_style(OutputType.SYSTEM)
321
+ console.print(text, style=style, end="")
257
322
 
258
323
  @staticmethod
259
324
  def print_stream_end():
260
325
  """End stream output with line break"""
261
- console.print()
326
+ # 结束符样式
327
+ end_style = PrettyOutput._get_style(OutputType.SUCCESS)
328
+ console.print("\n", style=end_style)
329
+ console.file.flush()
330
+
331
+ @staticmethod
332
+ def _get_style(output_type: OutputType) -> RichStyle:
333
+ """Get pre-defined RichStyle for output type"""
334
+ return console.get_style(output_type.value)
262
335
 
263
336
  def get_single_line_input(tip: str) -> str:
264
337
  """Get single line input, support direction key, history function, etc."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.120
3
+ Version: 0.1.121
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,47 +1,47 @@
1
- jarvis/__init__.py,sha256=WXicnhWkcCvbf7sM1SBpoWQnsc4VhXTtp1qmcSLHA_g,51
2
- jarvis/jarvis_agent/__init__.py,sha256=V9sQJq-ygUQBvlfqcndkiGsOZd0fKf-mbB2PThK5k9E,22441
1
+ jarvis/__init__.py,sha256=5aelbLSpRiMrR7pAWxlfBAsRE262Nt58D3YeKuUtp4Y,51
2
+ jarvis/jarvis_agent/__init__.py,sha256=4nmQOpFbY68OpyM3sCUsQSHOQGBoTP8Xff8RyX08W4Y,22447
3
3
  jarvis/jarvis_agent/output_handler.py,sha256=kJeFTjjSu0K_2p0wyhq2veSZuhRXoaFC_8wVaoBKX0w,401
4
4
  jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  jarvis/jarvis_code_agent/code_agent.py,sha256=8bOvUtMqq6CvL-SkLOfdJl0DrPQB1G5YN7dJN_bkZrc,7046
6
- jarvis/jarvis_code_agent/file_select.py,sha256=Kfjed4Kfa142dpuq0a6jxWM-v2JwWG1BTwwjlC1BJgc,11754
7
- jarvis/jarvis_code_agent/patch.py,sha256=S4UbHupNUbkx3QrygOm1i0Ynz-w_56jfVURKfYPCw3c,13306
6
+ jarvis/jarvis_code_agent/file_select.py,sha256=imTILJLEfabJ-gI3Weg0FXh-zT5ZUrGImEjbTT1l-rc,11801
7
+ jarvis/jarvis_code_agent/patch.py,sha256=ePauEntZa7TRWKsjtWCoT5P7Kt11HnEHe5td-ECnYyY,14110
8
8
  jarvis/jarvis_code_agent/relevant_files.py,sha256=u9wae9sn-XLaUoSK69-LRLomHWcE-K1y7W10BFdmQVE,3402
9
9
  jarvis/jarvis_codebase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- jarvis/jarvis_codebase/main.py,sha256=bvyYACCBNTrlJvaUCcJAJ8gUklKjy2HrMEfKjGYKtVQ,39779
10
+ jarvis/jarvis_codebase/main.py,sha256=qwB74U9YDgqvBSdvglQ62HmPkBT_Y5x5YF4J8LnzbQU,39778
11
11
  jarvis/jarvis_dev/main.py,sha256=rzVFTAVBkCPSkmOiutU00nfzZkhGrIv3zuv_0vWbUNo,22691
12
12
  jarvis/jarvis_lsp/base.py,sha256=_7pdbMKjdtYBW0DsRbjIodDHM3J7df-YgXHejN_WIrU,4490
13
13
  jarvis/jarvis_lsp/cpp.py,sha256=sYQHEl0FoVC5Iw2pJvvGKpeNLD95XjNuTOINvdZLgME,4986
14
14
  jarvis/jarvis_lsp/go.py,sha256=3soEuID2XV65zaxyR70RxNsvtm02l9PEZ46F_nsDdqY,5311
15
15
  jarvis/jarvis_lsp/python.py,sha256=_Vo2pPwVh_vAsyS0XowXMbT4Syd78naPEZj586bi004,4747
16
- jarvis/jarvis_lsp/registry.py,sha256=x7OFlW10AWQ_tWEbHWkdpngoFHTP3t1vSyGxVVLk46w,9933
16
+ jarvis/jarvis_lsp/registry.py,sha256=CHpwVrDFtcyDimVgUGd3UehP_sRPxk6__kISwnPfFr4,9938
17
17
  jarvis/jarvis_lsp/rust.py,sha256=ZvUoOZm9GWLl3kobfByBuTGrQ8aM2dLuNxS_NHr1aQQ,5542
18
18
  jarvis/jarvis_multi_agent/__init__.py,sha256=Z6QaRZrqUUa6r6Pe_KZi34Ymle5amQe1N-AINxiOi1c,6011
19
19
  jarvis/jarvis_platform/__init__.py,sha256=mrOt67nselz_H1gX9wdAO4y2DY5WPXzABqJbr5Des8k,63
20
- jarvis/jarvis_platform/ai8.py,sha256=AO42OVzrwQMDY74TR2B4gtrsfeRVxJRf5OmHBM3cVQY,11948
20
+ jarvis/jarvis_platform/ai8.py,sha256=rVPcbf0EbXV3lUPEmd_aO6UzYT0AHo4w13iGhHGvbjo,11964
21
21
  jarvis/jarvis_platform/base.py,sha256=HXUAa-Had4r_-4mAtOrF1bPxv7YPUGzvyXuPfomrfIQ,3576
22
- jarvis/jarvis_platform/kimi.py,sha256=WCRyG7jnqnpHNu6M9_pGFE_RBVKqYDtd_F1EPdT_FKU,15761
22
+ jarvis/jarvis_platform/kimi.py,sha256=4mNM7Aqm8XwanbNuVQG2uGx_8IRqdKHcTBwSh7VeODk,15767
23
23
  jarvis/jarvis_platform/ollama.py,sha256=TsBEg8crPmBiLvMRDtXYVa2AIdeog36MmW2tn5j9x8U,5613
24
24
  jarvis/jarvis_platform/openai.py,sha256=rHzc20Frd5LzS0Wm97FxglSai65UKkY2ju8rg6q-gOg,4445
25
- jarvis/jarvis_platform/oyi.py,sha256=3yuWHEGtGV--6IuFCCc1R2F1Y-p21xy4Vk-P5pQRAys,14994
26
- jarvis/jarvis_platform/registry.py,sha256=SmBcf86h6uf4TB7cut-Bhb9Ivj5z2wAg1pWkcJLi_80,8508
25
+ jarvis/jarvis_platform/oyi.py,sha256=YueBOGVMR33eTcQPRdfDdQPlM2g5awnYzYqA6z0Y1cg,15016
26
+ jarvis/jarvis_platform/registry.py,sha256=h6gInSOMkUbvYqzNYwYliFLOyga5fS-WlODaw-YTICU,8514
27
27
  jarvis/jarvis_platform_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- jarvis/jarvis_platform_manager/main.py,sha256=Ja0f-PiYxABIj-Ioh9NNZuqy0dB2Jk7dhrObgzgXApw,20958
28
+ jarvis/jarvis_platform_manager/main.py,sha256=7gir6GbdCugUIANYOkJzmz6I78SBrVbPO_36-J6Pjg8,20962
29
29
  jarvis/jarvis_platform_manager/openai_test.py,sha256=BAoZgOJ431gjjbbdgiX-ARfI0aLXK_cRLAQQJzQI6MI,5200
30
30
  jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  jarvis/jarvis_rag/main.py,sha256=2Nq5d5DBXdZ35_KEeHkdKJPFzxKgxt9bkwp1PMHpLzI,31754
32
32
  jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  jarvis/jarvis_smart_shell/main.py,sha256=ZD_rqV-2S3xA1jW1TPEzM4PHLBYOjZFtgJZxHpZZ0TE,4476
34
34
  jarvis/jarvis_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- jarvis/jarvis_tools/ask_codebase.py,sha256=MF7zeBqVDa7T45JxDR9mePA92kzZm5bQ9op8o5Qo9lM,3003
35
+ jarvis/jarvis_tools/ask_codebase.py,sha256=-4oIe7maa-60w5-QZxOGVt47W0kVd6TB-eIU77fIIMw,3005
36
36
  jarvis/jarvis_tools/ask_user.py,sha256=tIyiKk9F8xchjQ3Yh5fMQjhpflQTuh75HTuXMftGxZY,1827
37
37
  jarvis/jarvis_tools/base.py,sha256=c0DMoDDPxmsqUYJR989zgUs7nIYRY6GWBrAdusIZKjc,656
38
38
  jarvis/jarvis_tools/chdir.py,sha256=06GAtMqoi5fT1FXD2HUUlHKosVtz-Z8KI13lpEFQw3g,1820
39
- jarvis/jarvis_tools/code_review.py,sha256=d9DluFK61jNbHlKlKx-QJSFlC9nbNtNks_0rIb6xXwM,9773
40
- jarvis/jarvis_tools/create_code_agent.py,sha256=suebuzd-z9QyENYKAjnMbVaSfQVcsEd0XKiYoKawDuE,3897
39
+ jarvis/jarvis_tools/code_review.py,sha256=ZMWCrkVECCVaT7UyZV0_v49Gecws-x_dQ0NamFUunEs,9775
40
+ jarvis/jarvis_tools/create_code_agent.py,sha256=i1crlCWrQrpUuTYueLKgenAy_LhwXhEoFNk8xXo56xc,3899
41
41
  jarvis/jarvis_tools/create_sub_agent.py,sha256=ldpNn5LczybExvt9Sz4t1ybetLX-dTJIAF5f_oH-Z3M,2869
42
42
  jarvis/jarvis_tools/execute_shell.py,sha256=MwgVyI1O1wshU9yR-DvSWIgoSQpVjtH9JpjVQvSrKF0,2566
43
43
  jarvis/jarvis_tools/file_operation.py,sha256=8CAWozKfsRx_TzCmRPcNSj-bRo3K69IEDmmN8IWMlmg,5647
44
- jarvis/jarvis_tools/git_commiter.py,sha256=DY-uUjunxZPsiwOqMQ_uXS2X93uKu_Mx5OnIer-bjiM,3879
44
+ jarvis/jarvis_tools/git_commiter.py,sha256=iskOXIhfwvy7XfAQQpjDzy90Tl_dnlZ54hIepiuLBbE,4544
45
45
  jarvis/jarvis_tools/lsp_find_definition.py,sha256=xV8YeN1RJfwd2F3gE6OnDeTwl-AnCmrxueHocbXkQOc,4800
46
46
  jarvis/jarvis_tools/lsp_find_references.py,sha256=FohlJeLfTxcMUASfbjOT93hQGtI2WeyTpMGwRwShW_I,4043
47
47
  jarvis/jarvis_tools/lsp_get_diagnostics.py,sha256=bEvbDk8TnKg9TTFFxMrYOJm5TBDgz5gO04WJFQUwQQE,4490
@@ -49,17 +49,17 @@ jarvis/jarvis_tools/lsp_get_document_symbols.py,sha256=dspL6r9HYnXL5TpARSApFY3IQ
49
49
  jarvis/jarvis_tools/lsp_prepare_rename.py,sha256=RxUyIef4awtp-jgupcD1LcPlno9P3mOE8AS3_Fm71Ys,4832
50
50
  jarvis/jarvis_tools/lsp_validate_edit.py,sha256=M0iglK2QbnIEFv0RYK6o2iAYnv259jB6EU7To-rc51E,5247
51
51
  jarvis/jarvis_tools/methodology.py,sha256=JvHV6rHhC6fbPuSqC6UHFaGEE39d4g7zFLodR72wM0g,5758
52
- jarvis/jarvis_tools/rag.py,sha256=ZhmvwVUHBFsttDRdVncc-S-a-XVOy5jbdNd7Vk4uTlk,4942
52
+ jarvis/jarvis_tools/rag.py,sha256=eY3GrzagaJIPQ8DmrqNUFFJnIF_GfUxqRjeSengEDss,4944
53
53
  jarvis/jarvis_tools/read_code.py,sha256=OGktMs8ONYkWVFHpsPUFs6qdoY8PX3ymCExtH0IpTDU,7306
54
54
  jarvis/jarvis_tools/read_webpage.py,sha256=7QamwBi5s7lD-jTcjD0wsBvkmWPRC9-K-0JkGgeTpvs,3063
55
55
  jarvis/jarvis_tools/registry.py,sha256=XefDvujSfqKX2uLA6tnoJFg5kyBNW0iNAAJZocfIz9w,14836
56
56
  jarvis/jarvis_tools/search.py,sha256=NHrFpAqg6dtws_9wLJvIZimjeJ-kekETi0Bg0AWMG08,11437
57
57
  jarvis/jarvis_tools/select_code_files.py,sha256=vbEdneWWtAN90OFASohtllTgZW400ZxQbrkgroPK1qc,1902
58
58
  jarvis/jarvis_tools/tool_generator.py,sha256=jdniHyKcEyF9KyouudrCoZBH3czZmQXc3ns0_trZ3yU,6332
59
- jarvis/jarvis_utils/__init__.py,sha256=utMWglhmeTc6YagV_BY3X-SkvhwjT13GUAbby7tGJ4Y,29911
60
- jarvis_ai_assistant-0.1.120.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
61
- jarvis_ai_assistant-0.1.120.dist-info/METADATA,sha256=v6tHk0aRBdLovk6oSRHn71341o6hRXJdvYsV2PsXUbk,13701
62
- jarvis_ai_assistant-0.1.120.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
63
- jarvis_ai_assistant-0.1.120.dist-info/entry_points.txt,sha256=H9Y_q7BZGDsgJijaXHD9GbscllATyKYfg22otrpKEoE,619
64
- jarvis_ai_assistant-0.1.120.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
65
- jarvis_ai_assistant-0.1.120.dist-info/RECORD,,
59
+ jarvis/jarvis_utils/__init__.py,sha256=8mSrBfSu_uVYikiGPV1Mqm5iRykncF8ecIYRA1a9RDA,31804
60
+ jarvis_ai_assistant-0.1.121.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
61
+ jarvis_ai_assistant-0.1.121.dist-info/METADATA,sha256=UaGmNy26IgO6bv1A5LHA9JFe7-p5zzb00AiCPvb17Cs,13701
62
+ jarvis_ai_assistant-0.1.121.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
63
+ jarvis_ai_assistant-0.1.121.dist-info/entry_points.txt,sha256=H9Y_q7BZGDsgJijaXHD9GbscllATyKYfg22otrpKEoE,619
64
+ jarvis_ai_assistant-0.1.121.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
65
+ jarvis_ai_assistant-0.1.121.dist-info/RECORD,,