jarvis-ai-assistant 0.1.174__py3-none-any.whl → 0.1.176__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.

@@ -1,7 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
- from typing import Dict, List, Tuple
2
+ from typing import Dict, Generator, List, Tuple
3
3
  import os
4
4
  from openai import OpenAI
5
+ from rich.live import Live
6
+ from rich.text import Text
7
+ from rich.panel import Panel
8
+ from rich import box
5
9
  from jarvis.jarvis_platform.base import BasePlatform
6
10
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
11
 
@@ -69,7 +73,7 @@ class OpenAIModel(BasePlatform):
69
73
  self.system_message = message
70
74
  self.messages.append({"role": "system", "content": self.system_message})
71
75
 
72
- def chat(self, message: str) -> str:
76
+ def chat(self, message: str) -> Generator[str, None, None]:
73
77
  """Execute conversation"""
74
78
  try:
75
79
 
@@ -83,21 +87,16 @@ class OpenAIModel(BasePlatform):
83
87
  ) # type: ignore
84
88
 
85
89
  full_response = ""
86
-
87
90
  for chunk in response:
88
91
  if chunk.choices and chunk.choices[0].delta.content:
89
92
  text = chunk.choices[0].delta.content
90
- if not self.suppress_output:
91
- PrettyOutput.print_stream(text)
92
93
  full_response += text
93
-
94
- if not self.suppress_output:
95
- PrettyOutput.print_stream_end()
94
+ yield text
96
95
 
97
96
  # Add assistant reply to history
98
97
  self.messages.append({"role": "assistant", "content": full_response})
99
98
 
100
- return full_response
99
+ return None
101
100
 
102
101
  except Exception as e:
103
102
  PrettyOutput.print(f"对话失败:{str(e)}", OutputType.ERROR)
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- from typing import Dict, List, Tuple
2
+ from typing import Dict, Generator, List, Tuple
3
3
  import requests
4
4
  import json
5
5
  import os
@@ -11,6 +11,10 @@ from PIL import Image
11
11
  from yaspin import yaspin
12
12
  from yaspin.spinners import Spinners
13
13
  from yaspin.api import Yaspin
14
+ from rich.live import Live
15
+ from rich.text import Text
16
+ from rich.panel import Panel
17
+ from rich import box
14
18
  from jarvis.jarvis_platform.base import BasePlatform
15
19
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
16
20
  from jarvis.jarvis_utils.utils import while_success
@@ -382,12 +386,11 @@ class YuanbaoPlatform(BasePlatform):
382
386
  PrettyOutput.print(f"生成签名时出错: {str(e)}", OutputType.ERROR)
383
387
  raise e
384
388
 
385
- def chat(self, message: str) -> str:
389
+ def chat(self, message: str) -> Generator[str, None, None]:
386
390
  """发送消息并获取响应,可选文件附件
387
391
 
388
392
  参数:
389
393
  message: 要发送的消息文本
390
- file_list: 可选的上传和附加文件路径列表
391
394
 
392
395
  返回:
393
396
  模型的响应
@@ -425,7 +428,9 @@ class YuanbaoPlatform(BasePlatform):
425
428
  self.multimedia = []
426
429
 
427
430
  if self.web:
428
- payload["supportFunctions"] = ["supportInternetSearch"]
431
+ payload["supportFunctions"] = ["openInternetSearch"]
432
+ else:
433
+ payload["supportFunctions"] = ["autoInternetSearch"]
429
434
 
430
435
  # 添加系统消息(如果是第一次对话)
431
436
  if self.first_chat and self.system_message:
@@ -447,9 +452,6 @@ class YuanbaoPlatform(BasePlatform):
447
452
  error_msg += f", 响应: {response.text}"
448
453
  raise Exception(error_msg)
449
454
 
450
- full_response = ""
451
- is_text_block = False
452
-
453
455
  # 处理SSE流响应
454
456
  for line in response.iter_lines():
455
457
  if not line:
@@ -465,31 +467,23 @@ class YuanbaoPlatform(BasePlatform):
465
467
 
466
468
  # 处理文本类型的消息
467
469
  if data.get("type") == "text":
468
- is_text_block = True
469
470
  msg = data.get("msg", "")
470
471
  if msg:
471
- if not self.suppress_output:
472
- PrettyOutput.print_stream(msg)
473
- full_response += msg
472
+ yield msg
474
473
 
475
- # 处理思考中的消息(可选展示)
476
- elif data.get("type") == "think" and not self.suppress_output:
474
+ # 处理思考中的消息
475
+ elif data.get("type") == "think":
477
476
  think_content = data.get("content", "")
478
- # 可以选择性地显示思考过程,但不加入最终响应
479
- PrettyOutput.print_stream(f"{think_content}", is_thinking=True)
480
- pass
477
+ if think_content:
478
+ yield think_content
481
479
 
482
480
  except json.JSONDecodeError:
483
481
  pass
484
482
 
485
483
  # 检测结束标志
486
484
  elif line_str == "data: [DONE]":
487
- break
488
-
489
- if not self.suppress_output:
490
- PrettyOutput.print_stream_end()
491
-
492
- return full_response
485
+ return None
486
+ return None
493
487
 
494
488
  except Exception as e:
495
489
  raise Exception(f"对话失败: {str(e)}")
@@ -51,6 +51,7 @@ def list_platforms():
51
51
  def chat_with_model(platform_name: str, model_name: str):
52
52
  """Chat with specified platform and model"""
53
53
  registry = PlatformRegistry.get_global_platform_registry()
54
+ conversation_history = [] # 存储对话记录
54
55
 
55
56
  # Create platform instance
56
57
  platform = registry.create_platform(platform_name)
@@ -63,12 +64,13 @@ def chat_with_model(platform_name: str, model_name: str):
63
64
  platform.set_model_name(model_name)
64
65
  platform.set_suppress_output(False)
65
66
  PrettyOutput.print(f"连接到 {platform_name} 平台 {model_name} 模型", OutputType.SUCCESS)
66
- PrettyOutput.print("可用命令: /bye - 退出聊天, /clear - 清除会话, /upload - 上传文件, /shell - 执行shell命令", OutputType.INFO)
67
+ PrettyOutput.print("可用命令: /bye - 退出聊天, /clear - 清除会话, /upload - 上传文件, /shell - 执行shell命令, /save - 保存当前对话, /saveall - 保存所有对话", OutputType.INFO)
67
68
 
68
69
  # Start conversation loop
69
70
  while True:
70
71
  # Get user input
71
72
  user_input = get_multiline_input("")
73
+ conversation_history.append({"role": "user", "content": user_input}) # 记录用户输入
72
74
 
73
75
  # Check if input is cancelled
74
76
  if user_input.strip() == "/bye":
@@ -84,6 +86,7 @@ def chat_with_model(platform_name: str, model_name: str):
84
86
  try:
85
87
  platform.reset()
86
88
  platform.set_model_name(model_name) # Reinitialize session
89
+ conversation_history = [] # 重置对话记录
87
90
  PrettyOutput.print("会话已清除", OutputType.SUCCESS)
88
91
  except Exception as e:
89
92
  PrettyOutput.print(f"清除会话失败: {str(e)}", OutputType.ERROR)
@@ -110,6 +113,52 @@ def chat_with_model(platform_name: str, model_name: str):
110
113
  PrettyOutput.print(f"上传文件失败: {str(e)}", OutputType.ERROR)
111
114
  continue
112
115
 
116
+ # Check if it is a save command
117
+ if user_input.strip().startswith("/save"):
118
+ try:
119
+ file_path = user_input.strip()[5:].strip()
120
+ if not file_path:
121
+ PrettyOutput.print("请指定保存文件名,例如: /save last_message.txt", OutputType.WARNING)
122
+ continue
123
+
124
+ # Remove quotes if present
125
+ if (file_path.startswith('"') and file_path.endswith('"')) or (file_path.startswith("'") and file_path.endswith("'")):
126
+ file_path = file_path[1:-1]
127
+
128
+ # Write last message content to file
129
+ if conversation_history:
130
+ with open(file_path, 'w', encoding='utf-8') as f:
131
+ last_entry = conversation_history[-1]
132
+ f.write(f"{last_entry['content']}\n")
133
+ PrettyOutput.print(f"最后一条消息内容已保存到 {file_path}", OutputType.SUCCESS)
134
+ else:
135
+ PrettyOutput.print("没有可保存的消息", OutputType.WARNING)
136
+ except Exception as e:
137
+ PrettyOutput.print(f"保存消息失败: {str(e)}", OutputType.ERROR)
138
+ continue
139
+
140
+ # Check if it is a saveall command
141
+ if user_input.strip().startswith("/saveall"):
142
+ try:
143
+ file_path = user_input.strip()[8:].strip()
144
+ if not file_path:
145
+ PrettyOutput.print("请指定保存文件名,例如: /saveall all_conversations.txt", OutputType.WARNING)
146
+ continue
147
+
148
+ # Remove quotes if present
149
+ if (file_path.startswith('"') and file_path.endswith('"')) or (file_path.startswith("'") and file_path.endswith("'")):
150
+ file_path = file_path[1:-1]
151
+
152
+ # Write full conversation history to file
153
+ with open(file_path, 'w', encoding='utf-8') as f:
154
+ for entry in conversation_history:
155
+ f.write(f"{entry['role']}: {entry['content']}\n\n")
156
+
157
+ PrettyOutput.print(f"所有对话已保存到 {file_path}", OutputType.SUCCESS)
158
+ except Exception as e:
159
+ PrettyOutput.print(f"保存所有对话失败: {str(e)}", OutputType.ERROR)
160
+ continue
161
+
113
162
  # Check if it is a shell command
114
163
  if user_input.strip().startswith("/shell"):
115
164
  try:
@@ -133,6 +182,8 @@ def chat_with_model(platform_name: str, model_name: str):
133
182
  response = platform.chat_until_success(user_input)
134
183
  if not response:
135
184
  PrettyOutput.print("没有有效的回复", OutputType.WARNING)
185
+ else:
186
+ conversation_history.append({"role": "assistant", "content": response}) # 记录模型回复
136
187
 
137
188
  except Exception as e:
138
189
  PrettyOutput.print(f"聊天失败: {str(e)}", OutputType.ERROR)
@@ -253,20 +253,26 @@ def main():
253
253
  ```
254
254
  python -m jarvis.jarvis_tools.ask_codebase "登录功能在哪个文件实现?" --root_dir /path/to/codebase
255
255
  ```
256
+ 如果没有提供问题参数,则会进入交互式多行输入模式
256
257
  """
257
258
  import argparse
258
259
  import sys
260
+ from jarvis.jarvis_utils.input import get_multiline_input
259
261
 
260
262
  init_env()
261
263
 
262
264
  # 创建命令行参数解析器
263
265
  parser = argparse.ArgumentParser(description="智能代码库查询工具")
264
- parser.add_argument("question", help="关于代码库的问题")
266
+ parser.add_argument("question", nargs="?", help="关于代码库的问题")
265
267
  parser.add_argument("--root_dir", "-d", default=".", help="代码库根目录路径")
266
268
 
267
269
  # 解析命令行参数
268
270
  args = parser.parse_args()
269
271
 
272
+ # 如果没有提供问题参数,使用多行输入
273
+ if not args.question:
274
+ args.question = get_multiline_input("请输入关于代码库的问题:")
275
+
270
276
  # 创建并执行工具
271
277
  tool = AskCodebaseTool(auto_complete=False)
272
278
  result = tool.execute({
@@ -33,8 +33,8 @@ tool_call_help = f"""
33
33
  want: 想要从执行结果中获取到的信息,如果工具输出内容过长,会根据此字段尝试提取有效信息
34
34
  name: 工具名称
35
35
  arguments:
36
- param1: 值1
37
- param2: 值2
36
+ param1: 值1
37
+ param2: 值2
38
38
  {ct("TOOL_CALL")}
39
39
  </format>
40
40
 
@@ -49,7 +49,7 @@ arguments:
49
49
  <rule>
50
50
  ### 2. 严格遵守格式
51
51
  - 完全按照上述格式
52
- - 使用正确的YAML缩进
52
+ - 使用正确的YAML格式,2个空格作为缩进
53
53
  - 包含所有必需参数
54
54
  </rule>
55
55
 
@@ -72,15 +72,15 @@ arguments:
72
72
 
73
73
  <string_format>
74
74
  # 📝 字符串参数格式
75
- 始终使用 | 语法表示字符串参数:
75
+ 始终使用 |2 语法表示字符串参数,防止多行字符串行首空格引起歧义:
76
76
 
77
77
  {ot("TOOL_CALL")}
78
78
  want: 当前的git状态,期望获取xxx的提交记录
79
79
  name: execute_script
80
80
  arguments:
81
- interpreter: bash
82
- script_cotent: |
83
- git status --porcelain
81
+ interpreter: bash
82
+ script_cotent: |2
83
+ git status --porcelain
84
84
  {ct("TOOL_CALL")}
85
85
  </string_format>
86
86
 
@@ -96,7 +96,7 @@ arguments:
96
96
  <common_errors>
97
97
  # ⚠️ 常见错误
98
98
  - 同时调用多个工具
99
- - 字符串参数缺少 |
99
+ - 字符串参数缺少 |2
100
100
  - 假设工具结果
101
101
  - 创建虚构对话
102
102
  - 在没有所需信息的情况下继续
@@ -160,4 +160,13 @@ def get_max_big_content_size() -> int:
160
160
  返回:
161
161
  int: 最大大内容大小,默认为1MB
162
162
  """
163
- return int(os.getenv('JARVIS_MAX_BIG_CONTENT_SIZE', '96000'))
163
+ return int(os.getenv('JARVIS_MAX_BIG_CONTENT_SIZE', '96000'))
164
+
165
+ def get_pretty_output() -> bool:
166
+ """
167
+ 获取是否启用PrettyOutput。
168
+
169
+ 返回:
170
+ bool: 如果启用PrettyOutput则返回True,默认为True
171
+ """
172
+ return os.getenv('JARVIS_PRETTY_OUTPUT', 'false') == 'true'
@@ -69,16 +69,7 @@ def split_text_into_chunks(text: str, max_length: int = 512, min_length: int = 5
69
69
 
70
70
  # 处理最后一个块
71
71
  if current_chunk:
72
- if current_tokens >= min_length:
73
- chunks.append(current_chunk)
74
- elif chunks: # 如果最后一个块太短,尝试与前面的块合并
75
- last_chunk = chunks[-1]
76
- combined = last_chunk + current_chunk
77
- combined_tokens = get_context_token_count(combined)
78
- if combined_tokens <= max_length:
79
- chunks[-1] = combined
80
- else:
81
- chunks.append(current_chunk)
72
+ chunks.append(current_chunk) # 直接添加最后一个块,无论长度如何
82
73
 
83
74
  return chunks
84
75
 
@@ -12,6 +12,7 @@ import json
12
12
  import tempfile
13
13
  from typing import Any, Dict, Optional
14
14
 
15
+ from jarvis.jarvis_platform.base import BasePlatform
15
16
  from jarvis.jarvis_utils.config import get_data_dir
16
17
  from jarvis.jarvis_utils.output import PrettyOutput, OutputType
17
18
  from jarvis.jarvis_platform.registry import PlatformRegistry
@@ -92,6 +93,42 @@ def _create_methodology_temp_file(methodologies: Dict[str, str]) -> Optional[str
92
93
  PrettyOutput.print(f"创建方法论临时文件失败: {str(e)}", OutputType.ERROR)
93
94
  return None
94
95
 
96
+ def upload_methodology(platform: BasePlatform) -> bool:
97
+ """
98
+ 上传方法论文件到指定平台
99
+
100
+ 参数:
101
+ platform: 平台实例,需实现upload_files方法
102
+
103
+ 返回:
104
+ bool: 上传是否成功
105
+ """
106
+ methodology_dir = _get_methodology_directory()
107
+ if not os.path.exists(methodology_dir):
108
+ PrettyOutput.print("方法论文档不存在", OutputType.WARNING)
109
+ return False
110
+
111
+ methodologies = _load_all_methodologies()
112
+ if not methodologies:
113
+ PrettyOutput.print("没有可用的方法论文档", OutputType.WARNING)
114
+ return False
115
+
116
+ temp_file_path = _create_methodology_temp_file(methodologies)
117
+ if not temp_file_path:
118
+ return False
119
+
120
+ try:
121
+ if hasattr(platform, 'upload_files'):
122
+ return platform.upload_files([temp_file_path])
123
+ return False
124
+ finally:
125
+ if temp_file_path and os.path.exists(temp_file_path):
126
+ try:
127
+ os.remove(temp_file_path)
128
+ except Exception:
129
+ pass
130
+
131
+
95
132
  def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> str:
96
133
  """
97
134
  加载方法论并上传到大模型。
@@ -17,7 +17,9 @@ from rich.syntax import Syntax
17
17
  from rich.style import Style as RichStyle
18
18
  from pygments.lexers import guess_lexer
19
19
  from pygments.util import ClassNotFound
20
+ from jarvis.jarvis_utils.config import get_pretty_output
20
21
  from jarvis.jarvis_utils.globals import console, get_agent_list
22
+ # from rich.box import HEAVY
21
23
  class OutputType(Enum):
22
24
  """
23
25
  输出类型枚举,用于分类和样式化不同类型的消息。
@@ -125,7 +127,7 @@ class PrettyOutput:
125
127
  except (ClassNotFound, Exception):
126
128
  return default_lang
127
129
  @staticmethod
128
- def _format(output_type: OutputType, timestamp: bool = True) -> Text:
130
+ def _format(output_type: OutputType, timestamp: bool = True) -> str:
129
131
  """
130
132
  使用时间戳和图标格式化输出头。
131
133
 
@@ -136,14 +138,13 @@ class PrettyOutput:
136
138
  返回:
137
139
  Text: 格式化后的rich Text对象
138
140
  """
139
- formatted = Text()
141
+ icon = PrettyOutput._ICONS.get(output_type, "")
142
+ formatted = f"{icon} "
140
143
  if timestamp:
141
- formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}][{output_type.value}]", style=output_type.value)
144
+ formatted+=f"[{datetime.now().strftime('%H:%M:%S')}][{output_type.value}]"
142
145
  agent_info = get_agent_list()
143
146
  if agent_info:
144
- formatted.append(f"[{agent_info}]", style="blue")
145
- icon = PrettyOutput._ICONS.get(output_type, "")
146
- formatted.append(f" {icon} ", style=output_type.value)
147
+ formatted+=f"[{agent_info}]"
147
148
  return formatted
148
149
  @staticmethod
149
150
  def print(text: str, output_type: OutputType, timestamp: bool = True, lang: Optional[str] = None, traceback: bool = False):
@@ -158,35 +159,52 @@ class PrettyOutput:
158
159
  traceback: 是否显示错误的回溯信息
159
160
  """
160
161
  styles = {
161
- OutputType.SYSTEM: RichStyle(color="bright_cyan", bgcolor="#1a1a1a", frame=True, meta={"icon": "🤖"}),
162
- OutputType.CODE: RichStyle(color="green", bgcolor="#1a1a1a", frame=True, meta={"icon": "📝"}),
163
- OutputType.RESULT: RichStyle(color="bright_blue", bgcolor="#1a1a1a", frame=True, meta={"icon": "✨"}),
164
- OutputType.ERROR: RichStyle(color="red", frame=True, bgcolor="dark_red", meta={"icon": "❌"}),
165
- OutputType.INFO: RichStyle(color="gold1", frame=True, bgcolor="grey11", meta={"icon": "ℹ️"}),
166
- OutputType.PLANNING: RichStyle(color="purple", bold=True, frame=True, meta={"icon": "📋"}),
167
- OutputType.PROGRESS: RichStyle(color="white", encircle=True, frame=True, meta={"icon": "⏳"}),
168
- OutputType.SUCCESS: RichStyle(color="bright_green", bold=True, strike=False, meta={"icon": "✅"}),
169
- OutputType.WARNING: RichStyle(color="yellow", bold=True, blink2=True, bgcolor="dark_orange", meta={"icon": "⚠️"}),
170
- OutputType.DEBUG: RichStyle(color="grey58", dim=True, conceal=True, meta={"icon": "🔍"}),
171
- OutputType.USER: RichStyle(color="spring_green2", frame=True, meta={"icon": "👤"}),
172
- OutputType.TOOL: RichStyle(color="dark_sea_green4", bgcolor="grey19", frame=True, meta={"icon": "🔧"}),
162
+ OutputType.SYSTEM: dict( bgcolor="#1e2b3c"),
163
+ OutputType.CODE: dict( bgcolor="#1c2b1c"),
164
+ OutputType.RESULT: dict( bgcolor="#1c1c2b"),
165
+ OutputType.ERROR: dict( bgcolor="#2b1c1c"),
166
+ OutputType.INFO: dict( bgcolor="#2b2b1c", meta={"icon": "ℹ️"}),
167
+ OutputType.PLANNING: dict( bgcolor="#2b1c2b"),
168
+ OutputType.PROGRESS: dict( bgcolor="#1c1c1c"),
169
+ OutputType.SUCCESS: dict( bgcolor="#1c2b1c"),
170
+ OutputType.WARNING: dict( bgcolor="#2b2b1c"),
171
+ OutputType.DEBUG: dict( bgcolor="#1c1c1c"),
172
+ OutputType.USER: dict( bgcolor="#1c2b2b"),
173
+ OutputType.TOOL: dict( bgcolor="#1c2b2b"),
173
174
  }
175
+
176
+ header_styles = {
177
+ OutputType.SYSTEM: RichStyle(color="bright_cyan", bgcolor="#1e2b3c", frame=True, meta={"icon": "🤖"}),
178
+ OutputType.CODE: RichStyle(color="green", bgcolor="#1c2b1c", frame=True, meta={"icon": "📝"}),
179
+ OutputType.RESULT: RichStyle(color="bright_blue", bgcolor="#1c1c2b", frame=True, meta={"icon": "✨"}),
180
+ OutputType.ERROR: RichStyle(color="red", frame=True, bgcolor="#2b1c1c", meta={"icon": "❌"}),
181
+ OutputType.INFO: RichStyle(color="gold1", frame=True, bgcolor="#2b2b1c", meta={"icon": "ℹ️"}),
182
+ OutputType.PLANNING: RichStyle(color="purple", bold=True, frame=True, bgcolor="#2b1c2b", meta={"icon": "📋"}),
183
+ OutputType.PROGRESS: RichStyle(color="white", encircle=True, frame=True, bgcolor="#1c1c1c", meta={"icon": "⏳"}),
184
+ OutputType.SUCCESS: RichStyle(color="bright_green", bold=True, strike=False, bgcolor="#1c2b1c", meta={"icon": "✅"}),
185
+ OutputType.WARNING: RichStyle(color="yellow", bold=True, blink2=True, bgcolor="#2b2b1c", meta={"icon": "⚠️"}),
186
+ OutputType.DEBUG: RichStyle(color="grey58", dim=True, conceal=True, bgcolor="#1c1c1c", meta={"icon": "🔍"}),
187
+ OutputType.USER: RichStyle(color="spring_green2", frame=True, bgcolor="#1c2b2b", meta={"icon": "👤"}),
188
+ OutputType.TOOL: RichStyle(color="dark_sea_green4", bgcolor="#1c2b2b", frame=True, meta={"icon": "🔧"}),
189
+ }
190
+
174
191
  lang = lang if lang is not None else PrettyOutput._detect_language(text, default_lang='markdown')
175
- header = PrettyOutput._format(output_type, timestamp)
176
- content = Syntax(text, lang, theme="monokai", word_wrap=True)
192
+ header = Text(PrettyOutput._format(output_type, timestamp), style=header_styles[output_type])
193
+ content = Syntax(text, lang, theme="dracula", word_wrap=True, background_color=styles[output_type]["bgcolor"])
177
194
  panel = Panel(
178
195
  content,
179
- style=styles[output_type],
180
- border_style=styles[output_type],
196
+ border_style=header_styles[output_type],
181
197
  title=header,
182
198
  title_align="left",
183
199
  padding=(0, 0),
184
200
  highlight=True,
185
- # box=HEAVY,
186
201
  )
187
- console.print()
188
- console.print(panel)
189
- if traceback or output_type == OutputType.ERROR:
202
+ if get_pretty_output():
203
+ console.print(panel)
204
+ else:
205
+ console.print(header)
206
+ console.print(content)
207
+ if traceback:
190
208
  console.print_exception()
191
209
  @staticmethod
192
210
  def section(title: str, output_type: OutputType = OutputType.INFO):
@@ -197,42 +215,13 @@ class PrettyOutput:
197
215
  title: 章节标题文本
198
216
  output_type: 输出类型(影响样式)
199
217
  """
218
+ text = Text(title, style=output_type.value, justify="center")
200
219
  panel = Panel(
201
- Text(title, style=output_type.value, justify="center"),
220
+ text,
202
221
  border_style=output_type.value
203
222
  )
204
- console.print()
205
- console.print(panel)
206
- console.print()
207
- @staticmethod
208
- def print_stream(text: str, is_thinking: bool = False):
209
- """
210
- 打印流式输出,不带换行符。
211
-
212
- 参数:
213
- text: 要打印的文本
214
- """
215
- style = RichStyle(color="bright_cyan", bold=True, frame=True, meta={"icon": "🤖"})
216
- if is_thinking:
217
- style = RichStyle(color="grey58", italic=True, frame=True, meta={"icon": "🤖"})
218
- console.print(text, style=style, end="")
219
- @staticmethod
220
- def print_stream_end():
221
- """
222
- 结束流式输出,带换行符。
223
- """
224
- end_style = PrettyOutput._get_style(OutputType.SUCCESS)
225
- console.print("\n", style=end_style)
226
- console.file.flush()
227
- @staticmethod
228
- def _get_style(output_type: OutputType) -> RichStyle:
229
- """
230
- 获取预定义的RichStyle用于输出类型。
231
-
232
- 参数:
233
- output_type: 要获取样式的输出类型
234
-
235
- 返回:
236
- RichStyle: 对应的样式
237
- """
238
- return console.get_style(output_type.value)
223
+ if get_pretty_output():
224
+ console.print(panel)
225
+ else:
226
+ console.print(text)
227
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.174
3
+ Version: 0.1.176
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
@@ -213,7 +213,8 @@ OPENAI_API_BASE=https://api.openai.com/v1 # 可选,默认为官方API地址
213
213
  | `JARVIS_CONFIRM_BEFORE_APPLY_PATCH` | true | 应用补丁前是否需要确认 |
214
214
  | `JARVIS_MAX_TOOL_CALL_COUNT` | 20 | 最大连续工具调用次数 |
215
215
  | `JARVIS_AUTO_UPDATE` | true | 是否自动更新Jarvis(仅在以git仓库方式安装时有效) |
216
- | `JARVIS_MAX_BIG_CONTENT_SIZE` | 10485760 | 最大大内容大小 |
216
+ | `JARVIS_MAX_BIG_CONTENT_SIZE` | 96000 | 最大大内容大小 |
217
+ | `JARVIS_PRETTY_OUTPUT` | false | 是否启用PrettyOutput |
217
218
 
218
219
  所有配置编写到`~/.jarvis/env`文件中即可生效。
219
220