jarvis-ai-assistant 0.1.120__py3-none-any.whl → 0.1.122__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.
Files changed (28) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +3 -3
  3. jarvis/jarvis_code_agent/code_agent.py +36 -58
  4. jarvis/jarvis_code_agent/file_select.py +3 -3
  5. jarvis/jarvis_code_agent/patch.py +155 -298
  6. jarvis/jarvis_code_agent/relevant_files.py +2 -4
  7. jarvis/jarvis_codebase/main.py +2 -2
  8. jarvis/jarvis_lsp/registry.py +7 -7
  9. jarvis/jarvis_platform/ai8.py +10 -10
  10. jarvis/jarvis_platform/kimi.py +3 -5
  11. jarvis/jarvis_platform/oyi.py +11 -11
  12. jarvis/jarvis_platform/registry.py +3 -3
  13. jarvis/jarvis_platform_manager/main.py +2 -2
  14. jarvis/jarvis_tools/ask_codebase.py +1 -1
  15. jarvis/jarvis_tools/code_review.py +1 -1
  16. jarvis/jarvis_tools/create_code_agent.py +1 -1
  17. jarvis/jarvis_tools/file_operation.py +0 -3
  18. jarvis/jarvis_tools/git_commiter.py +26 -7
  19. jarvis/jarvis_tools/rag.py +1 -1
  20. jarvis/jarvis_tools/read_code.py +1 -2
  21. jarvis/jarvis_utils/__init__.py +120 -47
  22. {jarvis_ai_assistant-0.1.120.dist-info → jarvis_ai_assistant-0.1.122.dist-info}/METADATA +1 -1
  23. {jarvis_ai_assistant-0.1.120.dist-info → jarvis_ai_assistant-0.1.122.dist-info}/RECORD +27 -28
  24. {jarvis_ai_assistant-0.1.120.dist-info → jarvis_ai_assistant-0.1.122.dist-info}/entry_points.txt +0 -1
  25. jarvis/jarvis_dev/main.py +0 -878
  26. {jarvis_ai_assistant-0.1.120.dist-info → jarvis_ai_assistant-0.1.122.dist-info}/LICENSE +0 -0
  27. {jarvis_ai_assistant-0.1.120.dist-info → jarvis_ai_assistant-0.1.122.dist-info}/WHEEL +0 -0
  28. {jarvis_ai_assistant-0.1.120.dist-info → jarvis_ai_assistant-0.1.122.dist-info}/top_level.txt +0 -0
@@ -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)
@@ -350,8 +350,6 @@ class KimiModel(BasePlatform):
350
350
  output.append("")
351
351
 
352
352
  PrettyOutput.print("\n".join(output), OutputType.PROGRESS)
353
-
354
- PrettyOutput.print(full_response, OutputType.RESULT)
355
353
 
356
354
  return full_response
357
355
 
@@ -375,7 +373,7 @@ class KimiModel(BasePlatform):
375
373
  self.reset()
376
374
  return True
377
375
  else:
378
- PrettyOutput.print(f"删除会话失败: HTTP {response.status_code}", OutputType.ERROR)
376
+ PrettyOutput.print(f"删除会话失败: HTTP {response.status_code}", OutputType.WARNING)
379
377
  return False
380
378
  except Exception as e:
381
379
  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()
@@ -57,9 +57,6 @@ class FileOperationTool:
57
57
  content = open(abs_path, 'r', encoding='utf-8').read()
58
58
  output = f"File: {abs_path}\n{content}"
59
59
 
60
- # Print file content
61
- PrettyOutput.print(f"读取文件: {abs_path}\n{content}", OutputType.INFO)
62
-
63
60
  return {
64
61
  "success": True,
65
62
  "stdout": output,
@@ -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()
@@ -52,7 +52,7 @@ class ReadCodeTool:
52
52
  """
53
53
  try:
54
54
  abs_path = os.path.abspath(filepath.strip())
55
- PrettyOutput.print(f"正在读取代码文件:{abs_path}", OutputType.INFO)
55
+ PrettyOutput.print(f"正在读取代码文件:{abs_path} [范围: [{start_line},{end_line}]]", OutputType.INFO)
56
56
 
57
57
  if not os.path.exists(abs_path):
58
58
  PrettyOutput.print(f"文件不存在: {abs_path}", OutputType.WARNING)
@@ -120,7 +120,6 @@ class ReadCodeTool:
120
120
 
121
121
  content = "".join(formatted_lines)
122
122
  output = f"File: {filepath}\nLines: [{start_line}, {end_line}]\n{content}"
123
- PrettyOutput.print(output, OutputType.CODE)
124
123
  return {
125
124
  "success": True,
126
125
  "stdout": output,
@@ -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,20 @@ 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
+ agent_info = get_agent_list()
178
+ if agent_info: # Only add brackets if there's agent info
179
+ formatted.append(f"[{agent_info}]", style="blue")
176
180
  # Add icon
177
181
  icon = PrettyOutput._ICONS.get(output_type, "")
178
- formatted.append(f"{icon} ", style=output_type.value)
182
+ formatted.append(f" {icon} ", style=output_type.value)
179
183
 
180
184
  return formatted
181
185
 
@@ -190,27 +194,86 @@ class PrettyOutput:
190
194
  lang: Language for syntax highlighting
191
195
  traceback: Whether to show traceback for errors
192
196
  """
193
- from rich.style import Style as RichStyle
197
+
194
198
 
195
199
  # Define styles for different output types
196
200
  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)
201
+ OutputType.SYSTEM: RichStyle(
202
+ color="bright_cyan",
203
+ italic=True,
204
+ bold=True,
205
+ ),
206
+ OutputType.CODE: RichStyle(
207
+ color="green",
208
+ italic=True,
209
+ bgcolor="#1a1a1a",
210
+ frame=True
211
+ ),
212
+ OutputType.RESULT: RichStyle(
213
+ color="bright_blue",
214
+ bold=True,
215
+ italic=True,
216
+ bgcolor="navy_blue"
217
+ ),
218
+ OutputType.ERROR: RichStyle(
219
+ color="red",
220
+ bold=True,
221
+ italic=True,
222
+ blink=True,
223
+ bgcolor="dark_red",
224
+ ),
225
+ OutputType.INFO: RichStyle(
226
+ color="gold1",
227
+ dim=True,
228
+ bgcolor="grey11",
229
+ italic=True
230
+ ),
231
+ OutputType.PLANNING: RichStyle(
232
+ color="purple",
233
+ italic=True,
234
+ bold=True,
235
+ ),
236
+ OutputType.PROGRESS: RichStyle(
237
+ color="white",
238
+ encircle=True,
239
+ italic=True,
240
+ ),
241
+ OutputType.SUCCESS: RichStyle(
242
+ color="bright_green",
243
+ bold=True,
244
+ strike=False,
245
+ meta={"icon": "✓"},
246
+ italic=True
247
+ ),
248
+ OutputType.WARNING: RichStyle(
249
+ color="yellow",
250
+ bold=True,
251
+ blink2=True,
252
+ bgcolor="dark_orange",
253
+ italic=True
254
+ ),
255
+ OutputType.DEBUG: RichStyle(
256
+ color="grey58",
257
+ dim=True,
258
+ italic=True,
259
+ conceal=True
260
+ ),
261
+ OutputType.USER: RichStyle(
262
+ color="spring_green2",
263
+ reverse=True,
264
+ frame=True,
265
+ italic=True
266
+ ),
267
+ OutputType.TOOL: RichStyle(
268
+ color="dark_sea_green4",
269
+ italic=True,
270
+ bgcolor="grey19",
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.122
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