jarvis-ai-assistant 0.3.3__py3-none-any.whl → 0.3.4__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 +1 -1
- jarvis/jarvis_agent/__init__.py +164 -3
- jarvis/jarvis_agent/file_methodology_manager.py +6 -1
- jarvis/jarvis_agent/tool_executor.py +8 -4
- jarvis/jarvis_code_agent/code_agent.py +1 -8
- jarvis/jarvis_tools/base.py +8 -1
- jarvis/jarvis_utils/git_utils.py +20 -3
- jarvis/jarvis_utils/methodology.py +19 -2
- jarvis/jarvis_utils/utils.py +110 -49
- {jarvis_ai_assistant-0.3.3.dist-info → jarvis_ai_assistant-0.3.4.dist-info}/METADATA +1 -1
- {jarvis_ai_assistant-0.3.3.dist-info → jarvis_ai_assistant-0.3.4.dist-info}/RECORD +15 -15
- {jarvis_ai_assistant-0.3.3.dist-info → jarvis_ai_assistant-0.3.4.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.3.3.dist-info → jarvis_ai_assistant-0.3.4.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.3.3.dist-info → jarvis_ai_assistant-0.3.4.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.3.dist-info → jarvis_ai_assistant-0.3.4.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
import datetime
|
4
4
|
import os
|
5
5
|
import platform
|
6
|
+
from pathlib import Path
|
6
7
|
from typing import Any, Callable, Dict, List, Optional, Protocol, Tuple, Union
|
7
8
|
|
8
9
|
# 第三方库导入
|
@@ -14,6 +15,7 @@ from jarvis.jarvis_agent.protocols import OutputHandlerProtocol
|
|
14
15
|
from jarvis.jarvis_agent.session_manager import SessionManager
|
15
16
|
from jarvis.jarvis_agent.tool_executor import execute_tool_call
|
16
17
|
from jarvis.jarvis_agent.memory_manager import MemoryManager
|
18
|
+
from jarvis.jarvis_memory_organizer.memory_organizer import MemoryOrganizer
|
17
19
|
from jarvis.jarvis_agent.task_analyzer import TaskAnalyzer
|
18
20
|
from jarvis.jarvis_agent.file_methodology_manager import FileMethodologyManager
|
19
21
|
from jarvis.jarvis_agent.prompts import (
|
@@ -28,6 +30,7 @@ from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
28
30
|
|
29
31
|
# jarvis_utils 相关
|
30
32
|
from jarvis.jarvis_utils.config import (
|
33
|
+
get_data_dir,
|
31
34
|
get_max_token_count,
|
32
35
|
get_normal_model_name,
|
33
36
|
get_normal_platform_name,
|
@@ -50,6 +53,98 @@ from jarvis.jarvis_utils.input import get_multiline_input, user_confirm
|
|
50
53
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
51
54
|
from jarvis.jarvis_utils.tag import ct, ot
|
52
55
|
|
56
|
+
|
57
|
+
def show_agent_startup_stats(agent_name: str, model_name: str) -> None:
|
58
|
+
"""输出启动时的统计信息
|
59
|
+
|
60
|
+
参数:
|
61
|
+
agent_name: Agent的名称
|
62
|
+
model_name: 使用的模型名称
|
63
|
+
"""
|
64
|
+
try:
|
65
|
+
from jarvis.jarvis_utils.methodology import _load_all_methodologies
|
66
|
+
from jarvis.jarvis_tools.registry import ToolRegistry
|
67
|
+
from jarvis.jarvis_utils.config import get_data_dir
|
68
|
+
from pathlib import Path
|
69
|
+
from rich.console import Console
|
70
|
+
from rich.panel import Panel
|
71
|
+
from rich.text import Text
|
72
|
+
from rich.align import Align
|
73
|
+
import os
|
74
|
+
|
75
|
+
methodologies = _load_all_methodologies()
|
76
|
+
methodology_count = len(methodologies)
|
77
|
+
|
78
|
+
# 获取工具数量
|
79
|
+
# 创建一个临时的工具注册表类来获取所有工具(不应用过滤)
|
80
|
+
class TempToolRegistry(ToolRegistry):
|
81
|
+
def _apply_tool_config_filter(self) -> None:
|
82
|
+
"""重写过滤方法,不执行任何过滤"""
|
83
|
+
pass
|
84
|
+
|
85
|
+
# 获取所有工具的数量
|
86
|
+
tool_registry_all = TempToolRegistry()
|
87
|
+
total_tool_count = len(tool_registry_all.tools)
|
88
|
+
|
89
|
+
# 获取可用工具的数量(应用过滤)
|
90
|
+
tool_registry = ToolRegistry()
|
91
|
+
available_tool_count = len(tool_registry.get_all_tools())
|
92
|
+
|
93
|
+
global_memory_dir = Path(get_data_dir()) / "memory" / "global_long_term"
|
94
|
+
global_memory_count = 0
|
95
|
+
if global_memory_dir.exists():
|
96
|
+
global_memory_count = len(list(global_memory_dir.glob("*.json")))
|
97
|
+
|
98
|
+
# 检查项目记忆
|
99
|
+
project_memory_dir = Path(".jarvis/memory")
|
100
|
+
project_memory_count = 0
|
101
|
+
if project_memory_dir.exists():
|
102
|
+
project_memory_count = len(list(project_memory_dir.glob("*.json")))
|
103
|
+
|
104
|
+
# 获取当前工作目录
|
105
|
+
current_dir = os.getcwd()
|
106
|
+
|
107
|
+
# 构建欢迎信息
|
108
|
+
welcome_message = f"{agent_name} 初始化完成 - 使用 {model_name} 模型"
|
109
|
+
|
110
|
+
stats_parts = [
|
111
|
+
f"📚 本地方法论: [bold cyan]{methodology_count}[/bold cyan]",
|
112
|
+
f"🛠️ 工具: [bold green]{available_tool_count}/{total_tool_count}[/bold green] (可用/全部)",
|
113
|
+
f"🧠 全局记忆: [bold yellow]{global_memory_count}[/bold yellow]",
|
114
|
+
]
|
115
|
+
|
116
|
+
# 如果有项目记忆,添加到统计信息中
|
117
|
+
if project_memory_count > 0:
|
118
|
+
stats_parts.append(
|
119
|
+
f"📝 项目记忆: [bold magenta]{project_memory_count}[/bold magenta]"
|
120
|
+
)
|
121
|
+
|
122
|
+
stats_text = Text.from_markup(" | ".join(stats_parts), justify="center")
|
123
|
+
|
124
|
+
# 创建包含欢迎信息和统计信息的面板内容
|
125
|
+
panel_content = Text()
|
126
|
+
panel_content.append(welcome_message, style="bold white")
|
127
|
+
panel_content.append("\n")
|
128
|
+
panel_content.append(f"📁 工作目录: {current_dir}", style="dim white")
|
129
|
+
panel_content.append("\n\n")
|
130
|
+
panel_content.append(stats_text)
|
131
|
+
panel_content.justify = "center"
|
132
|
+
|
133
|
+
panel = Panel(
|
134
|
+
panel_content,
|
135
|
+
title="✨ Jarvis 资源概览 ✨",
|
136
|
+
title_align="center",
|
137
|
+
border_style="blue",
|
138
|
+
expand=False,
|
139
|
+
)
|
140
|
+
|
141
|
+
console = Console()
|
142
|
+
console.print(Align.center(panel))
|
143
|
+
|
144
|
+
except Exception as e:
|
145
|
+
PrettyOutput.print(f"加载统计信息失败: {e}", OutputType.WARNING)
|
146
|
+
|
147
|
+
|
53
148
|
origin_agent_system_prompt = f"""
|
54
149
|
<role>
|
55
150
|
# 🤖 角色
|
@@ -175,9 +270,8 @@ class Agent:
|
|
175
270
|
# 设置系统提示词
|
176
271
|
self._setup_system_prompt()
|
177
272
|
|
178
|
-
#
|
179
|
-
|
180
|
-
PrettyOutput.print(welcome_message, OutputType.SYSTEM)
|
273
|
+
# 输出统计信息(包含欢迎信息)
|
274
|
+
show_agent_startup_stats(name, self.model.name()) # type: ignore
|
181
275
|
|
182
276
|
def _init_model(self, llm_type: str, model_group: Optional[str]):
|
183
277
|
"""初始化模型平台"""
|
@@ -515,6 +609,8 @@ class Agent:
|
|
515
609
|
if self.use_analysis:
|
516
610
|
self.task_analyzer.analysis_task(satisfaction_feedback)
|
517
611
|
|
612
|
+
self._check_and_organize_memory()
|
613
|
+
|
518
614
|
if self.need_summary:
|
519
615
|
print("📄 正在生成总结...")
|
520
616
|
self.session.prompt = self.summary_prompt
|
@@ -711,6 +807,71 @@ class Agent:
|
|
711
807
|
|
712
808
|
self.first = False
|
713
809
|
|
810
|
+
def _check_and_organize_memory(self):
|
811
|
+
"""
|
812
|
+
检查记忆库状态,如果满足条件则提示用户整理。
|
813
|
+
每天只检测一次。
|
814
|
+
"""
|
815
|
+
try:
|
816
|
+
# 检查项目记忆
|
817
|
+
self._perform_memory_check("project_long_term", Path(".jarvis"), "project")
|
818
|
+
# 检查全局记忆
|
819
|
+
self._perform_memory_check(
|
820
|
+
"global_long_term",
|
821
|
+
Path(get_data_dir()),
|
822
|
+
"global",
|
823
|
+
)
|
824
|
+
except Exception as e:
|
825
|
+
PrettyOutput.print(f"检查记忆库时发生意外错误: {e}", OutputType.WARNING)
|
826
|
+
|
827
|
+
def _perform_memory_check(self, memory_type: str, base_path: Path, scope_name: str):
|
828
|
+
"""执行特定范围的记忆检查和整理"""
|
829
|
+
check_file = base_path / ".last_memory_organizer_check"
|
830
|
+
now = datetime.datetime.now()
|
831
|
+
|
832
|
+
if check_file.exists():
|
833
|
+
try:
|
834
|
+
last_check_time = datetime.datetime.fromisoformat(
|
835
|
+
check_file.read_text()
|
836
|
+
)
|
837
|
+
if (now - last_check_time).total_seconds() < 24 * 3600:
|
838
|
+
return # 24小时内已检查
|
839
|
+
except (ValueError, FileNotFoundError):
|
840
|
+
# 文件内容无效或文件在读取时被删除,继续执行检查
|
841
|
+
pass
|
842
|
+
|
843
|
+
# 立即更新检查时间,防止并发或重复检查
|
844
|
+
base_path.mkdir(parents=True, exist_ok=True)
|
845
|
+
check_file.write_text(now.isoformat())
|
846
|
+
|
847
|
+
organizer = MemoryOrganizer()
|
848
|
+
# NOTE: 使用受保护方法以避免重复实现逻辑
|
849
|
+
memories = organizer._load_memories(memory_type)
|
850
|
+
|
851
|
+
if len(memories) < 200:
|
852
|
+
return
|
853
|
+
|
854
|
+
# NOTE: 使用受保护方法以避免重复实现逻辑
|
855
|
+
overlap_groups = organizer._find_overlapping_memories(memories, min_overlap=3)
|
856
|
+
has_significant_overlap = any(groups for groups in overlap_groups.values())
|
857
|
+
|
858
|
+
if not has_significant_overlap:
|
859
|
+
return
|
860
|
+
|
861
|
+
prompt = (
|
862
|
+
f"检测到您的 '{scope_name}' 记忆库中包含 {len(memories)} 条记忆,"
|
863
|
+
f"并且存在3个以上标签重叠的记忆。\n"
|
864
|
+
f"是否立即整理记忆库以优化性能和相关性?"
|
865
|
+
)
|
866
|
+
if user_confirm(prompt, default=True):
|
867
|
+
PrettyOutput.print(
|
868
|
+
f"正在开始整理 '{scope_name}' ({memory_type}) 记忆库...",
|
869
|
+
OutputType.INFO,
|
870
|
+
)
|
871
|
+
organizer.organize_memories(memory_type, min_overlap=3)
|
872
|
+
else:
|
873
|
+
PrettyOutput.print(f"已取消 '{scope_name}' 记忆库整理。", OutputType.INFO)
|
874
|
+
|
714
875
|
def clear_history(self):
|
715
876
|
"""
|
716
877
|
Clears conversation history by delegating to the session manager.
|
@@ -80,7 +80,12 @@ class FileMethodologyManager:
|
|
80
80
|
|
81
81
|
memory_manager = MemoryManager(self.agent)
|
82
82
|
memory_tags_prompt = memory_manager.prepare_memory_tags_prompt()
|
83
|
-
methodology = load_methodology(
|
83
|
+
methodology = load_methodology(
|
84
|
+
msg,
|
85
|
+
self.agent.get_tool_registry(),
|
86
|
+
platform_name=self.agent.model.platform_name(),
|
87
|
+
model_name=self.agent.model.name(),
|
88
|
+
)
|
84
89
|
self.agent.session.prompt = f"{self.agent.session.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{methodology}{memory_tags_prompt}"
|
85
90
|
|
86
91
|
def handle_history_with_file_upload(self) -> str:
|
@@ -41,9 +41,13 @@ def execute_tool_call(response: str, agent: "Agent") -> Tuple[bool, Any]:
|
|
41
41
|
if not agent.execute_tool_confirm or user_confirm(
|
42
42
|
f"需要执行{tool_to_execute.name()}确认执行?", True
|
43
43
|
):
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
try:
|
45
|
+
print(f"🔧 正在执行{tool_to_execute.name()}...")
|
46
|
+
result = tool_to_execute.handle(response, agent)
|
47
|
+
print(f"✅ {tool_to_execute.name()}执行完成")
|
48
|
+
return result
|
49
|
+
except Exception as e:
|
50
|
+
PrettyOutput.print(f"工具执行失败: {str(e)}", OutputType.ERROR)
|
51
|
+
return False, str(e)
|
48
52
|
|
49
53
|
return False, ""
|
@@ -398,11 +398,6 @@ class CodeAgent:
|
|
398
398
|
if not user_confirm("是否要提交?", True):
|
399
399
|
return
|
400
400
|
|
401
|
-
# 用户确认修改,统计修改次数
|
402
|
-
from jarvis.jarvis_stats.stats import StatsManager
|
403
|
-
|
404
|
-
StatsManager.increment("code_modification_confirmed", group="code_agent")
|
405
|
-
|
406
401
|
try:
|
407
402
|
confirm_add_new_files()
|
408
403
|
|
@@ -697,9 +692,7 @@ def cli(
|
|
697
692
|
sys.exit(0)
|
698
693
|
|
699
694
|
curr_dir = os.getcwd()
|
700
|
-
|
701
|
-
PrettyOutput.print(f"当前目录: {git_dir}", OutputType.INFO)
|
702
|
-
|
695
|
+
find_git_root_and_cd(curr_dir)
|
703
696
|
try:
|
704
697
|
agent = CodeAgent(
|
705
698
|
llm_type=llm_type,
|
jarvis/jarvis_tools/base.py
CHANGED
jarvis/jarvis_utils/git_utils.py
CHANGED
@@ -309,7 +309,9 @@ def get_modified_line_ranges() -> Dict[str, List[Tuple[int, int]]]:
|
|
309
309
|
start_line = int(range_match.group(1)) # 保持从1开始
|
310
310
|
line_count = int(range_match.group(2)) if range_match.group(2) else 1
|
311
311
|
end_line = start_line + line_count - 1
|
312
|
-
|
312
|
+
if current_file not in result:
|
313
|
+
result[current_file] = []
|
314
|
+
result[current_file].append((start_line, end_line))
|
313
315
|
|
314
316
|
return result
|
315
317
|
|
@@ -414,8 +416,23 @@ def check_and_update_git_repo(repo_path: str) -> bool:
|
|
414
416
|
hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
|
415
417
|
)
|
416
418
|
|
417
|
-
|
418
|
-
|
419
|
+
is_uv_env = False
|
420
|
+
if in_venv:
|
421
|
+
# 检查是否在uv创建的虚拟环境内
|
422
|
+
if sys.platform == "win32":
|
423
|
+
uv_path = os.path.join(sys.prefix, "Scripts", "uv.exe")
|
424
|
+
else:
|
425
|
+
uv_path = os.path.join(sys.prefix, "bin", "uv")
|
426
|
+
if os.path.exists(uv_path):
|
427
|
+
is_uv_env = True
|
428
|
+
|
429
|
+
# 根据环境选择安装命令
|
430
|
+
if is_uv_env:
|
431
|
+
install_cmd = ["uv", "pip", "install", "-e", "."]
|
432
|
+
else:
|
433
|
+
install_cmd = [sys.executable, "-m", "pip", "install", "-e", "."]
|
434
|
+
|
435
|
+
# 尝试安装
|
419
436
|
result = subprocess.run(
|
420
437
|
install_cmd, cwd=git_root, capture_output=True, text=True
|
421
438
|
)
|
@@ -175,13 +175,20 @@ def upload_methodology(platform: BasePlatform, other_files: List[str] = []) -> b
|
|
175
175
|
pass
|
176
176
|
|
177
177
|
|
178
|
-
def load_methodology(
|
178
|
+
def load_methodology(
|
179
|
+
user_input: str,
|
180
|
+
tool_registery: Optional[Any] = None,
|
181
|
+
platform_name: Optional[str] = None,
|
182
|
+
model_name: Optional[str] = None,
|
183
|
+
) -> str:
|
179
184
|
"""
|
180
185
|
加载方法论并上传到大模型。
|
181
186
|
|
182
187
|
参数:
|
183
188
|
user_input: 用户输入文本,用于提示大模型
|
184
189
|
tool_registery: 工具注册表,用于获取工具列表
|
190
|
+
platform_name (str, optional): 指定的平台名称. Defaults to None.
|
191
|
+
model_name (str, optional): 指定的模型名称. Defaults to None.
|
185
192
|
|
186
193
|
返回:
|
187
194
|
str: 相关的方法论提示,如果未找到方法论则返回空字符串
|
@@ -203,7 +210,17 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
203
210
|
return ""
|
204
211
|
print(f"✅ 加载方法论文件完成 (共 {len(methodologies)} 个)")
|
205
212
|
|
206
|
-
|
213
|
+
if platform_name:
|
214
|
+
platform = PlatformRegistry().create_platform(platform_name)
|
215
|
+
if platform and model_name:
|
216
|
+
platform.set_model_name(model_name)
|
217
|
+
else:
|
218
|
+
platform = PlatformRegistry().get_normal_platform()
|
219
|
+
|
220
|
+
if not platform:
|
221
|
+
PrettyOutput.print("无法创建平台实例", OutputType.ERROR)
|
222
|
+
return ""
|
223
|
+
|
207
224
|
platform.set_suppress_output(True)
|
208
225
|
|
209
226
|
# 步骤1:获取所有方法论的标题
|
jarvis/jarvis_utils/utils.py
CHANGED
@@ -79,30 +79,6 @@ def _setup_signal_handler() -> None:
|
|
79
79
|
signal.signal(signal.SIGINT, sigint_handler)
|
80
80
|
|
81
81
|
|
82
|
-
def _show_welcome_message(welcome_str: str) -> None:
|
83
|
-
"""显示欢迎信息
|
84
|
-
|
85
|
-
参数:
|
86
|
-
welcome_str: 欢迎信息字符串
|
87
|
-
"""
|
88
|
-
if not welcome_str:
|
89
|
-
return
|
90
|
-
|
91
|
-
jarvis_ascii_art = f"""
|
92
|
-
██╗ █████╗ ██████╗ ██╗ ██╗██╗███████╗
|
93
|
-
██║██╔══██╗██╔══██╗██║ ██║██║██╔════╝
|
94
|
-
██║███████║██████╔╝██║ ██║██║███████╗
|
95
|
-
██╗██║██╔══██║██╔══██╗╚██╗ ██╔╝██║╚════██║
|
96
|
-
╚████║██║ ██║██║ ██║ ╚████╔╝ ██║███████║
|
97
|
-
╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═══╝ ╚═╝╚══════╝
|
98
|
-
{welcome_str}
|
99
|
-
|
100
|
-
https://github.com/skyfireitdiy/Jarvis
|
101
|
-
v{__version__}
|
102
|
-
"""
|
103
|
-
PrettyOutput.print_gradient_text(jarvis_ascii_art, (0, 120, 255), (0, 255, 200))
|
104
|
-
|
105
|
-
|
106
82
|
def _check_git_updates() -> bool:
|
107
83
|
"""检查并更新git仓库
|
108
84
|
|
@@ -115,7 +91,7 @@ def _check_git_updates() -> bool:
|
|
115
91
|
return check_and_update_git_repo(str(script_dir))
|
116
92
|
|
117
93
|
|
118
|
-
def _show_usage_stats() -> None:
|
94
|
+
def _show_usage_stats(welcome_str: str) -> None:
|
119
95
|
"""显示Jarvis使用统计信息"""
|
120
96
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
121
97
|
|
@@ -127,6 +103,8 @@ def _show_usage_stats() -> None:
|
|
127
103
|
from rich.table import Table
|
128
104
|
from rich.text import Text
|
129
105
|
|
106
|
+
console = Console()
|
107
|
+
|
130
108
|
from jarvis.jarvis_stats.stats import StatsManager
|
131
109
|
|
132
110
|
# 获取所有可用的指标
|
@@ -223,7 +201,6 @@ def _show_usage_stats() -> None:
|
|
223
201
|
table = Table(
|
224
202
|
show_header=True,
|
225
203
|
header_style="bold magenta",
|
226
|
-
title="📊 Jarvis 使用统计",
|
227
204
|
title_justify="center",
|
228
205
|
box=box.ROUNDED,
|
229
206
|
padding=(0, 1),
|
@@ -413,28 +390,117 @@ def _show_usage_stats() -> None:
|
|
413
390
|
summary_content.append(encouragement)
|
414
391
|
|
415
392
|
# 3. 组合并打印
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
render_items.append(centered_table)
|
393
|
+
from rich import box
|
394
|
+
|
395
|
+
# 右侧内容:总体表现 + 使命与愿景
|
396
|
+
right_column_items = []
|
421
397
|
|
398
|
+
# 欢迎信息 Panel
|
399
|
+
if welcome_str:
|
400
|
+
jarvis_ascii_art_str = """
|
401
|
+
██╗ █████╗ ██████╗ ██╗ ██╗██╗███████╗
|
402
|
+
██║██╔══██╗██╔══██╗██║ ██║██║██╔════╝
|
403
|
+
██║███████║██████╔╝██║ ██║██║███████╗
|
404
|
+
██╗██║██╔══██║██╔══██╗╚██╗ ██╔╝██║╚════██║
|
405
|
+
╚████║██║ ██║██║ ██║ ╚████╔╝ ██║███████║
|
406
|
+
╚═══╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═══╝ ╚═╝╚══════╝"""
|
407
|
+
|
408
|
+
welcome_panel_content = Group(
|
409
|
+
Align.center(Text(jarvis_ascii_art_str, style="bold blue")),
|
410
|
+
Align.center(Text(welcome_str, style="bold")),
|
411
|
+
"", # for a blank line
|
412
|
+
Align.center(Text(f"v{__version__}")),
|
413
|
+
Align.center(Text("https://github.com/skyfireitdiy/Jarvis")),
|
414
|
+
)
|
415
|
+
|
416
|
+
welcome_panel = Panel(
|
417
|
+
welcome_panel_content, border_style="yellow", expand=True
|
418
|
+
)
|
419
|
+
right_column_items.append(welcome_panel)
|
422
420
|
if summary_content:
|
423
421
|
summary_panel = Panel(
|
424
422
|
Text("\n".join(summary_content), justify="left"),
|
425
423
|
title="✨ 总体表现 ✨",
|
426
424
|
title_align="center",
|
427
425
|
border_style="green",
|
428
|
-
expand=
|
426
|
+
expand=True,
|
429
427
|
)
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
428
|
+
right_column_items.append(summary_panel)
|
429
|
+
|
430
|
+
# 愿景 Panel
|
431
|
+
vision_text = Text(
|
432
|
+
"重新定义开发者体验,打破人与工具的界限,构建开发者与AI之间真正的共生伙伴关系。",
|
433
|
+
justify="center",
|
434
|
+
style="italic",
|
435
|
+
)
|
436
|
+
vision_panel = Panel(
|
437
|
+
vision_text,
|
438
|
+
title="🔭 愿景 (Vision) 🔭",
|
439
|
+
title_align="center",
|
440
|
+
border_style="cyan",
|
441
|
+
expand=True,
|
442
|
+
)
|
443
|
+
right_column_items.append(vision_panel)
|
444
|
+
|
445
|
+
# 使命 Panel
|
446
|
+
mission_text = Text(
|
447
|
+
"通过深度人机协作,将开发者的灵感(Vibe)高效落地为代码与行动,释放创造之力。",
|
448
|
+
justify="center",
|
449
|
+
style="italic",
|
450
|
+
)
|
451
|
+
mission_panel = Panel(
|
452
|
+
mission_text,
|
453
|
+
title="🎯 使命 (Mission) 🎯",
|
454
|
+
title_align="center",
|
455
|
+
border_style="magenta",
|
456
|
+
expand=True,
|
457
|
+
)
|
458
|
+
right_column_items.append(mission_panel)
|
459
|
+
|
460
|
+
right_column_group = Group(*right_column_items)
|
461
|
+
|
462
|
+
layout_renderable: RenderableType
|
463
|
+
|
464
|
+
if console.width < 200:
|
465
|
+
# 上下布局
|
466
|
+
layout_items: List[RenderableType] = []
|
467
|
+
layout_items.append(right_column_group)
|
468
|
+
if has_content:
|
469
|
+
layout_items.append(table)
|
470
|
+
layout_renderable = Group(*layout_items)
|
471
|
+
else:
|
472
|
+
# 左右布局(当前)
|
473
|
+
layout_table = Table(
|
474
|
+
show_header=False,
|
475
|
+
box=None,
|
476
|
+
padding=0,
|
477
|
+
expand=True,
|
478
|
+
pad_edge=False,
|
479
|
+
)
|
480
|
+
# 左右布局,左侧为总结信息,右侧为统计表格
|
481
|
+
layout_table.add_column(ratio=5) # 左侧
|
482
|
+
layout_table.add_column(ratio=5) # 右侧
|
483
|
+
|
484
|
+
if has_content:
|
485
|
+
# 将总结信息放在左侧,统计表格放在右侧
|
486
|
+
layout_table.add_row(right_column_group, table)
|
487
|
+
else:
|
488
|
+
# 如果没有统计数据,则总结信息占满
|
489
|
+
layout_table.add_row(right_column_group)
|
490
|
+
layout_renderable = layout_table
|
491
|
+
|
492
|
+
# 打印最终的布局
|
493
|
+
if has_content or summary_content:
|
494
|
+
# 将整体布局封装在一个最终的Panel中,以提供整体边框
|
495
|
+
final_panel = Panel(
|
496
|
+
layout_renderable,
|
497
|
+
title="Jarvis AI Assistant",
|
498
|
+
title_align="center",
|
499
|
+
border_style="blue",
|
500
|
+
box=box.HEAVY,
|
501
|
+
padding=(0, 1),
|
502
|
+
)
|
503
|
+
console.print(final_panel)
|
438
504
|
except Exception as e:
|
439
505
|
# 输出错误信息以便调试
|
440
506
|
import traceback
|
@@ -456,20 +522,16 @@ def init_env(welcome_str: str, config_file: Optional[str] = None) -> None:
|
|
456
522
|
# 2. 统计命令使用
|
457
523
|
count_cmd_usage()
|
458
524
|
|
459
|
-
# 3.
|
460
|
-
if welcome_str:
|
461
|
-
_show_welcome_message(welcome_str)
|
462
|
-
|
463
|
-
# 4. 设置配置文件
|
525
|
+
# 3. 设置配置文件
|
464
526
|
global g_config_file
|
465
527
|
g_config_file = config_file
|
466
528
|
load_config()
|
467
529
|
|
468
|
-
#
|
530
|
+
# 4. 显示历史统计数据(仅在显示欢迎信息时显示)
|
469
531
|
if welcome_str:
|
470
|
-
_show_usage_stats()
|
532
|
+
_show_usage_stats(welcome_str)
|
471
533
|
|
472
|
-
#
|
534
|
+
# 5. 检查git更新
|
473
535
|
if _check_git_updates():
|
474
536
|
os.execv(sys.executable, [sys.executable] + sys.argv)
|
475
537
|
sys.exit(0)
|
@@ -654,7 +716,6 @@ def load_config():
|
|
654
716
|
|
655
717
|
from typing import Tuple
|
656
718
|
|
657
|
-
|
658
719
|
from typing import Tuple
|
659
720
|
|
660
721
|
|
@@ -1,10 +1,10 @@
|
|
1
|
-
jarvis/__init__.py,sha256=
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=
|
1
|
+
jarvis/__init__.py,sha256=OeCDz6Z11rF2cp6sXEe7CwvIdTZ_EPzUJwW35kFF6BY,73
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=NF_eUF85RRplGJyLmInIsTn-09aEPtjj4utYvEALvJw,31802
|
3
3
|
jarvis/jarvis_agent/agent_manager.py,sha256=YzpMiF0H2-eyk2kn2o24Bkj3bXsQx7Pv2vfD4gWepo0,2893
|
4
4
|
jarvis/jarvis_agent/builtin_input_handler.py,sha256=Qs4LAr4xdKLBJpQE81YP4CkucAop86ms0iVoKa1nnso,2468
|
5
5
|
jarvis/jarvis_agent/config_editor.py,sha256=Ctk82sO6w2cNW0-_5L7Bomj-hgM4U7WwMc52fwhAJyg,1809
|
6
6
|
jarvis/jarvis_agent/edit_file_handler.py,sha256=w-byNJ4TN_SlV3djjfFC7OksySOFGrM8ku49w662dzc,11854
|
7
|
-
jarvis/jarvis_agent/file_methodology_manager.py,sha256=
|
7
|
+
jarvis/jarvis_agent/file_methodology_manager.py,sha256=qCRh36LLiaF3cXwIRlHurCzQlQQCUvd9BteCdj3CxfQ,4526
|
8
8
|
jarvis/jarvis_agent/jarvis.py,sha256=2XMuMA3A4ihE4RAo-XnYZHnJ0ZrGRFagE1s-eiGdZ9Q,3252
|
9
9
|
jarvis/jarvis_agent/main.py,sha256=Sd4-OnBcMqY5i7vb-Riy_JT2fGfuANtgiAWvWFY8LXM,3345
|
10
10
|
jarvis/jarvis_agent/memory_manager.py,sha256=F7HTNzdN1_-cSygnz7zKSJRJvPLUOosqcXQeiW8zG4U,5266
|
@@ -18,10 +18,10 @@ jarvis/jarvis_agent/share_manager.py,sha256=h3H6PXSTVUBLablFys_h16mdI7a48RVALQhA
|
|
18
18
|
jarvis/jarvis_agent/shell_input_handler.py,sha256=1IboqdxcJuoIqRpmDU10GugR9fWXUHyCEbVF4nIWbyo,1328
|
19
19
|
jarvis/jarvis_agent/task_analyzer.py,sha256=-fQ9YBYFcc-Z1FSoDIPzRfAgkREFoIOXtU2TdBkB-e0,4656
|
20
20
|
jarvis/jarvis_agent/task_manager.py,sha256=HJm4_SMpsFbQMUUsAZeHm7cZuhNbz28YW-DRLYgoarc,4422
|
21
|
-
jarvis/jarvis_agent/tool_executor.py,sha256=
|
21
|
+
jarvis/jarvis_agent/tool_executor.py,sha256=k73cKhZEZpljvui4ZxALlFEIE-iLzJ32Softsmiwzqk,1896
|
22
22
|
jarvis/jarvis_agent/tool_share_manager.py,sha256=R5ONIQlDXX9pFq3clwHFhEW8BAJ3ECaR2DqWCEC9tzM,5205
|
23
23
|
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
-
jarvis/jarvis_code_agent/code_agent.py,sha256=
|
24
|
+
jarvis/jarvis_code_agent/code_agent.py,sha256=49B2079pBLlxMmUaAzToAa-SdwAwDqWCeBhCnaA3Quk,29106
|
25
25
|
jarvis/jarvis_code_agent/lint.py,sha256=LZPsfyZPMo7Wm7LN4osZocuNJwZx1ojacO3MlF870x8,4009
|
26
26
|
jarvis/jarvis_code_analysis/code_review.py,sha256=GHNzJKLRxNIINGxM2dnDg7JV9bxG88bY2ZDh4qgqTV0,36023
|
27
27
|
jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=LIXAYa1sW3l7foP6kohLWnE98I_EQ0T7z5bYKHq6rJA,78
|
@@ -88,7 +88,7 @@ jarvis/jarvis_stats/storage.py,sha256=MBQRxExIWdePXzY1EE8JAs1IEpMqamImpgjruqt_u9
|
|
88
88
|
jarvis/jarvis_stats/visualizer.py,sha256=ZIBmGELzs6c7qM01tQql1HF6eFKn6HDGVQfKXRUUIY0,8529
|
89
89
|
jarvis/jarvis_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
90
90
|
jarvis/jarvis_tools/ask_user.py,sha256=M6DdLNryCE8y1JcdZHEifUgZkPUEPNKc-zDW5p0Mb1k,2029
|
91
|
-
jarvis/jarvis_tools/base.py,sha256=
|
91
|
+
jarvis/jarvis_tools/base.py,sha256=kgDjh64HYr_ox_1FR7j52LsJ4B4W2wSqOejdtSBb2Fc,1413
|
92
92
|
jarvis/jarvis_tools/clear_memory.py,sha256=HQMK70UJhhDgPPHozGaTpYizzQblUzYRwPbvD1z3z6o,8730
|
93
93
|
jarvis/jarvis_tools/edit_file.py,sha256=hM345E9rxS-EkqCZpwwizL6fmPdTadtB798tEO5Ce3g,10417
|
94
94
|
jarvis/jarvis_tools/execute_script.py,sha256=gMarE5yCCSPU6Dp6HlcL2KT-2xCzR-1p-oQNlYOJK58,6157
|
@@ -111,17 +111,17 @@ jarvis/jarvis_utils/clipboard.py,sha256=WgbQIQR2sh7_5ZzeX04eT3zXx_mxQbKyJOZXgGX_
|
|
111
111
|
jarvis/jarvis_utils/config.py,sha256=RSmKvpfB9-cq5PVZPNSirc0qiNtNKw8AUpuz5RKK2vs,15378
|
112
112
|
jarvis/jarvis_utils/embedding.py,sha256=oEOEM2qf16DMYwPsQe6srET9BknyjOdY2ef0jsp3Or8,2714
|
113
113
|
jarvis/jarvis_utils/file_processors.py,sha256=XiM248SHS7lLgQDCbORVFWqinbVDUawYxWDOsLXDxP8,3043
|
114
|
-
jarvis/jarvis_utils/git_utils.py,sha256
|
114
|
+
jarvis/jarvis_utils/git_utils.py,sha256=-WReOr8JvfUHHXC9GDvYP-xA49wmM4_TRa6b4_ZccFs,22568
|
115
115
|
jarvis/jarvis_utils/globals.py,sha256=aTrOHcCgPAeZFLFIWMAMiJCYlmr4XhdFZf5gZ745hnE,8900
|
116
116
|
jarvis/jarvis_utils/http.py,sha256=eRhV3-GYuWmQ0ogq9di9WMlQkFcVb1zGCrySnOgT1x0,4392
|
117
117
|
jarvis/jarvis_utils/input.py,sha256=pl8SanShzaEJZybvNHTjnFdKC2VxDPS1IwONtbwe-7U,12765
|
118
|
-
jarvis/jarvis_utils/methodology.py,sha256=
|
118
|
+
jarvis/jarvis_utils/methodology.py,sha256=IIMU17WVSunsWXsnXROd4G77LxgYs4xEC_xm_0CDkjw,12554
|
119
119
|
jarvis/jarvis_utils/output.py,sha256=QRLlKObQKT0KuRSeZRqYb7NlTQvsd1oZXZ41WxeWEuU,10894
|
120
120
|
jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
|
121
|
-
jarvis/jarvis_utils/utils.py,sha256=
|
122
|
-
jarvis_ai_assistant-0.3.
|
123
|
-
jarvis_ai_assistant-0.3.
|
124
|
-
jarvis_ai_assistant-0.3.
|
125
|
-
jarvis_ai_assistant-0.3.
|
126
|
-
jarvis_ai_assistant-0.3.
|
127
|
-
jarvis_ai_assistant-0.3.
|
121
|
+
jarvis/jarvis_utils/utils.py,sha256=ZyLL-X0EGi8fnofAdP5Qd99lYlP5U5qGY50elR4uS08,44291
|
122
|
+
jarvis_ai_assistant-0.3.4.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
123
|
+
jarvis_ai_assistant-0.3.4.dist-info/METADATA,sha256=rgbEn1DYq_u7mcMyId7rgP4s3oJJwdCc0IQdppTU2_4,18184
|
124
|
+
jarvis_ai_assistant-0.3.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
125
|
+
jarvis_ai_assistant-0.3.4.dist-info/entry_points.txt,sha256=4GcWKFxRJD-QU14gw_3ZaW4KuEVxOcZK9i270rwPdjA,1395
|
126
|
+
jarvis_ai_assistant-0.3.4.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
127
|
+
jarvis_ai_assistant-0.3.4.dist-info/RECORD,,
|
File without changes
|
{jarvis_ai_assistant-0.3.3.dist-info → jarvis_ai_assistant-0.3.4.dist-info}/entry_points.txt
RENAMED
File without changes
|
{jarvis_ai_assistant-0.3.3.dist-info → jarvis_ai_assistant-0.3.4.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
File without changes
|