jarvis-ai-assistant 0.2.5__py3-none-any.whl → 0.2.6__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 +67 -9
- jarvis/jarvis_agent/edit_file_handler.py +4 -4
- jarvis/jarvis_code_agent/code_agent.py +10 -11
- jarvis/jarvis_multi_agent/main.py +1 -0
- jarvis/jarvis_tools/retrieve_memory.py +206 -0
- jarvis/jarvis_tools/save_memory.py +142 -0
- jarvis/jarvis_utils/globals.py +120 -1
- jarvis/jarvis_utils/utils.py +59 -41
- {jarvis_ai_assistant-0.2.5.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/METADATA +1 -1
- {jarvis_ai_assistant-0.2.5.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/RECORD +15 -13
- {jarvis_ai_assistant-0.2.5.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.2.5.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.2.5.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.2.5.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
@@ -396,7 +396,7 @@ class Agent:
|
|
396
396
|
"""
|
397
397
|
return execute_tool_call(response, self)
|
398
398
|
|
399
|
-
def _complete_task(self) -> str:
|
399
|
+
def _complete_task(self, auto_completed: bool = False) -> str:
|
400
400
|
"""完成任务并生成总结(如果需要)
|
401
401
|
|
402
402
|
返回:
|
@@ -407,8 +407,26 @@ class Agent:
|
|
407
407
|
2. 对于子Agent: 可能会生成总结(如果启用)
|
408
408
|
3. 使用spinner显示生成状态
|
409
409
|
"""
|
410
|
+
satisfaction_feedback = ""
|
411
|
+
|
412
|
+
if not auto_completed and self.use_analysis:
|
413
|
+
if user_confirm("您对本次任务的完成是否满意?", True):
|
414
|
+
satisfaction_feedback = "\n\n用户对本次任务的完成表示满意。"
|
415
|
+
else:
|
416
|
+
feedback = self.multiline_inputer(
|
417
|
+
"请提供您的反馈意见(可留空直接回车):"
|
418
|
+
)
|
419
|
+
if feedback:
|
420
|
+
satisfaction_feedback = (
|
421
|
+
f"\n\n用户对本次任务的完成不满意,反馈意见如下:\n{feedback}"
|
422
|
+
)
|
423
|
+
else:
|
424
|
+
satisfaction_feedback = (
|
425
|
+
"\n\n用户对本次任务的完成不满意,未提供具体反馈意见。"
|
426
|
+
)
|
427
|
+
|
410
428
|
if self.use_analysis:
|
411
|
-
self._analysis_task()
|
429
|
+
self._analysis_task(satisfaction_feedback)
|
412
430
|
if self.need_summary:
|
413
431
|
print("📄 正在生成总结...")
|
414
432
|
self.session.prompt = self.summary_prompt
|
@@ -420,11 +438,13 @@ class Agent:
|
|
420
438
|
|
421
439
|
return "任务完成"
|
422
440
|
|
423
|
-
def _analysis_task(self):
|
441
|
+
def _analysis_task(self, satisfaction_feedback: str = ""):
|
424
442
|
print("🔍 正在分析任务...")
|
425
443
|
try:
|
426
444
|
# 让模型判断是否需要生成方法论
|
427
445
|
analysis_prompt = TASK_ANALYSIS_PROMPT
|
446
|
+
if satisfaction_feedback:
|
447
|
+
analysis_prompt += satisfaction_feedback
|
428
448
|
|
429
449
|
self.session.prompt = analysis_prompt
|
430
450
|
if not self.model:
|
@@ -452,6 +472,23 @@ class Agent:
|
|
452
472
|
else ""
|
453
473
|
)
|
454
474
|
|
475
|
+
# 检查工具列表并添加记忆工具相关提示
|
476
|
+
memory_prompts = ""
|
477
|
+
tool_registry = self.get_tool_registry()
|
478
|
+
if tool_registry:
|
479
|
+
tool_names = [tool.name for tool in tool_registry.tools.values()]
|
480
|
+
|
481
|
+
# 如果有save_memory工具,添加相关提示
|
482
|
+
if "save_memory" in tool_names:
|
483
|
+
memory_prompts += "\n - 如果有关键信息需要记忆,请调用save_memory工具进行记忆:"
|
484
|
+
memory_prompts += "\n * project_long_term: 保存与当前项目相关的长期信息"
|
485
|
+
memory_prompts += "\n * global_long_term: 保存通用的信息、用户喜好、知识、方法等"
|
486
|
+
memory_prompts += "\n * short_term: 保存当前任务相关的临时信息"
|
487
|
+
|
488
|
+
# 如果有retrieve_memory工具,添加相关提示
|
489
|
+
if "retrieve_memory" in tool_names:
|
490
|
+
memory_prompts += "\n - 如果需要检索相关记忆信息,请调用retrieve_memory工具"
|
491
|
+
|
455
492
|
addon_prompt = f"""
|
456
493
|
<system_prompt>
|
457
494
|
请判断是否已经完成任务,如果已经完成:
|
@@ -461,7 +498,7 @@ class Agent:
|
|
461
498
|
- 仅包含一个操作
|
462
499
|
- 如果信息不明确,请请求用户补充
|
463
500
|
- 如果执行过程中连续失败5次,请使用ask_user询问用户操作
|
464
|
-
- 操作列表:{action_handlers}
|
501
|
+
- 操作列表:{action_handlers}{memory_prompts}
|
465
502
|
</system_prompt>
|
466
503
|
|
467
504
|
请继续。
|
@@ -547,7 +584,7 @@ class Agent:
|
|
547
584
|
continue
|
548
585
|
|
549
586
|
if self.auto_complete and ot("!!!COMPLETE!!!") in current_response:
|
550
|
-
return self._complete_task()
|
587
|
+
return self._complete_task(auto_completed=True)
|
551
588
|
|
552
589
|
# 获取用户输入
|
553
590
|
user_input = self.multiline_inputer(
|
@@ -560,7 +597,7 @@ class Agent:
|
|
560
597
|
continue
|
561
598
|
|
562
599
|
if not user_input:
|
563
|
-
return self._complete_task()
|
600
|
+
return self._complete_task(auto_completed=False)
|
564
601
|
|
565
602
|
except Exception as e:
|
566
603
|
PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
|
@@ -571,6 +608,23 @@ class Agent:
|
|
571
608
|
return f"Task failed: {str(e)}"
|
572
609
|
|
573
610
|
def _first_run(self):
|
611
|
+
# 获取所有记忆标签并添加到提示中
|
612
|
+
from jarvis.jarvis_utils.globals import get_all_memory_tags
|
613
|
+
|
614
|
+
memory_tags = get_all_memory_tags()
|
615
|
+
memory_tags_prompt = ""
|
616
|
+
|
617
|
+
if any(tags for tags in memory_tags.values()):
|
618
|
+
memory_tags_prompt = "\n\n系统中存在以下记忆标签,你可以使用 retrieve_memory 工具检索相关记忆:"
|
619
|
+
for memory_type, tags in memory_tags.items():
|
620
|
+
if tags:
|
621
|
+
type_name = {
|
622
|
+
"short_term": "短期记忆",
|
623
|
+
"project_long_term": "项目长期记忆",
|
624
|
+
"global_long_term": "全局长期记忆"
|
625
|
+
}.get(memory_type, memory_type)
|
626
|
+
memory_tags_prompt += f"\n- {type_name}: {', '.join(tags)}"
|
627
|
+
|
574
628
|
# 如果有上传文件,先上传文件
|
575
629
|
if self.model and self.model.support_upload_files():
|
576
630
|
if self.use_methodology:
|
@@ -583,12 +637,12 @@ class Agent:
|
|
583
637
|
msg = self.session.prompt
|
584
638
|
for handler in self.input_handler:
|
585
639
|
msg, _ = handler(msg, self)
|
586
|
-
self.session.prompt = f"{self.session.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
|
640
|
+
self.session.prompt = f"{self.session.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}{memory_tags_prompt}"
|
587
641
|
else:
|
588
642
|
if self.files:
|
589
|
-
self.session.prompt = f"{self.session.prompt}\n\n上传的文件包含历史对话信息和方法论文件,可以从中获取一些经验信息。"
|
643
|
+
self.session.prompt = f"{self.session.prompt}\n\n上传的文件包含历史对话信息和方法论文件,可以从中获取一些经验信息。{memory_tags_prompt}"
|
590
644
|
else:
|
591
|
-
self.session.prompt = f"{self.session.prompt}\n\n上传的文件包含历史对话信息,可以从中获取一些经验信息。"
|
645
|
+
self.session.prompt = f"{self.session.prompt}\n\n上传的文件包含历史对话信息,可以从中获取一些经验信息。{memory_tags_prompt}"
|
592
646
|
elif self.files:
|
593
647
|
if not self.model.upload_files(self.files):
|
594
648
|
PrettyOutput.print(
|
@@ -604,6 +658,10 @@ class Agent:
|
|
604
658
|
for handler in self.input_handler:
|
605
659
|
msg, _ = handler(msg, self)
|
606
660
|
self.session.prompt = f"{self.session.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
|
661
|
+
|
662
|
+
# 添加记忆标签提示
|
663
|
+
if memory_tags_prompt:
|
664
|
+
self.session.prompt = f"{self.session.prompt}{memory_tags_prompt}"
|
607
665
|
|
608
666
|
self.first = False
|
609
667
|
|
@@ -204,9 +204,9 @@ class EditFileHandler(OutputHandler):
|
|
204
204
|
found = False
|
205
205
|
|
206
206
|
if exact_search in modified_content:
|
207
|
-
#
|
207
|
+
# 直接执行替换(保留所有原始格式),只替换第一个匹配
|
208
208
|
modified_content = modified_content.replace(
|
209
|
-
exact_search, replace_text
|
209
|
+
exact_search, replace_text, 1
|
210
210
|
)
|
211
211
|
print(f"✅ 补丁 #{patch_count} 应用成功")
|
212
212
|
found = True
|
@@ -222,7 +222,7 @@ class EditFileHandler(OutputHandler):
|
|
222
222
|
stripped_replace = replace_text[1:-1]
|
223
223
|
if stripped_search in modified_content:
|
224
224
|
modified_content = modified_content.replace(
|
225
|
-
stripped_search, stripped_replace
|
225
|
+
stripped_search, stripped_replace, 1
|
226
226
|
)
|
227
227
|
print(f"✅ 补丁 #{patch_count} 应用成功 (自动去除首尾换行)")
|
228
228
|
found = True
|
@@ -251,7 +251,7 @@ class EditFileHandler(OutputHandler):
|
|
251
251
|
)
|
252
252
|
if indented_search in modified_content:
|
253
253
|
modified_content = modified_content.replace(
|
254
|
-
indented_search, indented_replace
|
254
|
+
indented_search, indented_replace, 1
|
255
255
|
)
|
256
256
|
print(
|
257
257
|
f"✅ 补丁 #{patch_count} 应用成功 (自动增加 {space_count} 个空格缩进)"
|
@@ -65,6 +65,8 @@ class CodeAgent:
|
|
65
65
|
"ask_user",
|
66
66
|
"read_code",
|
67
67
|
"rewrite_file",
|
68
|
+
"save_memory",
|
69
|
+
"retrieve_memory",
|
68
70
|
]
|
69
71
|
)
|
70
72
|
code_system_prompt = """
|
@@ -269,7 +271,7 @@ class CodeAgent:
|
|
269
271
|
return
|
270
272
|
|
271
273
|
PrettyOutput.print(
|
272
|
-
"⚠️
|
274
|
+
"⚠️ 正在修改git换行符敏感设置,这会影响所有文件的换行符处理方式",
|
273
275
|
OutputType.WARNING,
|
274
276
|
)
|
275
277
|
print("将进行以下设置:")
|
@@ -277,18 +279,15 @@ class CodeAgent:
|
|
277
279
|
current = current_settings.get(key, "未设置")
|
278
280
|
print(f" {key}: {current} -> {value}")
|
279
281
|
|
280
|
-
|
281
|
-
|
282
|
-
|
282
|
+
# 直接执行设置,不需要用户确认
|
283
|
+
for key, value in target_settings.items():
|
284
|
+
subprocess.run(["git", "config", key, value], check=True)
|
283
285
|
|
284
|
-
|
285
|
-
|
286
|
-
|
286
|
+
# 对于Windows系统,提示用户可以创建.gitattributes文件
|
287
|
+
if sys.platform.startswith("win"):
|
288
|
+
self._handle_windows_line_endings()
|
287
289
|
|
288
|
-
|
289
|
-
else:
|
290
|
-
print("❌ 用户取消修改git换行符敏感设置")
|
291
|
-
sys.exit(0)
|
290
|
+
print("✅ git换行符敏感设置已更新")
|
292
291
|
|
293
292
|
def _handle_windows_line_endings(self) -> None:
|
294
293
|
"""在Windows系统上处理换行符问题,提供建议而非强制修改"""
|
@@ -7,6 +7,7 @@ import yaml
|
|
7
7
|
from jarvis.jarvis_multi_agent import MultiAgent
|
8
8
|
from jarvis.jarvis_utils.input import get_multiline_input
|
9
9
|
from jarvis.jarvis_utils.utils import init_env
|
10
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
10
11
|
|
11
12
|
app = typer.Typer(help="多智能体系统启动器")
|
12
13
|
|
@@ -0,0 +1,206 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
import json
|
3
|
+
import random
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import Any, Dict, List, Optional
|
6
|
+
|
7
|
+
from jarvis.jarvis_utils.config import get_data_dir
|
8
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
9
|
+
from jarvis.jarvis_utils.globals import get_short_term_memories
|
10
|
+
|
11
|
+
|
12
|
+
class RetrieveMemoryTool:
|
13
|
+
"""检索记忆工具,用于从长短期记忆系统中检索信息"""
|
14
|
+
|
15
|
+
name = "retrieve_memory"
|
16
|
+
description = """从长短期记忆系统中检索信息。
|
17
|
+
|
18
|
+
支持的记忆类型:
|
19
|
+
- project_long_term: 项目长期记忆(与当前项目相关的信息)
|
20
|
+
- global_long_term: 全局长期记忆(通用的信息、用户喜好、知识、方法等)
|
21
|
+
- short_term: 短期记忆(当前任务相关的信息)
|
22
|
+
- all: 从所有类型中检索
|
23
|
+
|
24
|
+
可以通过标签过滤检索结果,支持多个标签(满足任一标签即可)
|
25
|
+
"""
|
26
|
+
|
27
|
+
parameters = {
|
28
|
+
"type": "object",
|
29
|
+
"properties": {
|
30
|
+
"memory_types": {
|
31
|
+
"type": "array",
|
32
|
+
"items": {
|
33
|
+
"type": "string",
|
34
|
+
"enum": [
|
35
|
+
"project_long_term",
|
36
|
+
"global_long_term",
|
37
|
+
"short_term",
|
38
|
+
"all",
|
39
|
+
],
|
40
|
+
},
|
41
|
+
"description": "要检索的记忆类型列表,如果包含'all'则检索所有类型",
|
42
|
+
},
|
43
|
+
"tags": {
|
44
|
+
"type": "array",
|
45
|
+
"items": {"type": "string"},
|
46
|
+
"description": "用于过滤的标签列表(可选)",
|
47
|
+
},
|
48
|
+
"limit": {
|
49
|
+
"type": "integer",
|
50
|
+
"description": "返回结果的最大数量(可选,默认返回所有)",
|
51
|
+
"minimum": 1,
|
52
|
+
},
|
53
|
+
},
|
54
|
+
"required": ["memory_types"],
|
55
|
+
}
|
56
|
+
|
57
|
+
def __init__(self):
|
58
|
+
"""初始化检索记忆工具"""
|
59
|
+
self.project_memory_dir = Path(".jarvis/memory")
|
60
|
+
self.global_memory_dir = Path(get_data_dir()) / "memory"
|
61
|
+
|
62
|
+
def _get_memory_dir(self, memory_type: str) -> Path:
|
63
|
+
"""根据记忆类型获取存储目录"""
|
64
|
+
if memory_type == "project_long_term":
|
65
|
+
return self.project_memory_dir
|
66
|
+
elif memory_type in ["global_long_term", "short_term"]:
|
67
|
+
return self.global_memory_dir / memory_type
|
68
|
+
else:
|
69
|
+
raise ValueError(f"未知的记忆类型: {memory_type}")
|
70
|
+
|
71
|
+
def _retrieve_from_type(
|
72
|
+
self, memory_type: str, tags: Optional[List[str]] = None
|
73
|
+
) -> List[Dict[str, Any]]:
|
74
|
+
"""从指定类型中检索记忆"""
|
75
|
+
memories: List[Dict[str, Any]] = []
|
76
|
+
|
77
|
+
if memory_type == "short_term":
|
78
|
+
# 从全局变量获取短期记忆
|
79
|
+
memories = get_short_term_memories(tags)
|
80
|
+
else:
|
81
|
+
# 从文件系统获取长期记忆
|
82
|
+
memory_dir = self._get_memory_dir(memory_type)
|
83
|
+
|
84
|
+
if not memory_dir.exists():
|
85
|
+
return memories
|
86
|
+
|
87
|
+
# 遍历记忆文件
|
88
|
+
for memory_file in memory_dir.glob("*.json"):
|
89
|
+
try:
|
90
|
+
with open(memory_file, "r", encoding="utf-8") as f:
|
91
|
+
memory_data = json.load(f)
|
92
|
+
|
93
|
+
# 如果指定了标签,检查是否匹配
|
94
|
+
if tags:
|
95
|
+
memory_tags = memory_data.get("tags", [])
|
96
|
+
if not any(tag in memory_tags for tag in tags):
|
97
|
+
continue
|
98
|
+
|
99
|
+
memories.append(memory_data)
|
100
|
+
except Exception as e:
|
101
|
+
PrettyOutput.print(
|
102
|
+
f"读取记忆文件 {memory_file} 失败: {str(e)}", OutputType.WARNING
|
103
|
+
)
|
104
|
+
|
105
|
+
return memories
|
106
|
+
|
107
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
108
|
+
"""执行检索记忆操作"""
|
109
|
+
try:
|
110
|
+
memory_types = args.get("memory_types", [])
|
111
|
+
tags = args.get("tags", [])
|
112
|
+
limit = args.get("limit", None)
|
113
|
+
|
114
|
+
# 确定要检索的记忆类型
|
115
|
+
if "all" in memory_types:
|
116
|
+
types_to_search = [
|
117
|
+
"project_long_term",
|
118
|
+
"global_long_term",
|
119
|
+
"short_term",
|
120
|
+
]
|
121
|
+
else:
|
122
|
+
types_to_search = memory_types
|
123
|
+
|
124
|
+
# 从各个类型中检索记忆
|
125
|
+
all_memories = []
|
126
|
+
for memory_type in types_to_search:
|
127
|
+
memories = self._retrieve_from_type(memory_type, tags)
|
128
|
+
all_memories.extend(memories)
|
129
|
+
|
130
|
+
# 按创建时间排序(最新的在前)
|
131
|
+
all_memories.sort(key=lambda x: x.get("created_at", ""), reverse=True)
|
132
|
+
|
133
|
+
# 限制最多返回50条记忆,随机选取
|
134
|
+
if len(all_memories) > 50:
|
135
|
+
all_memories = random.sample(all_memories, 50)
|
136
|
+
# 重新排序,保持时间顺序
|
137
|
+
all_memories.sort(key=lambda x: x.get("created_at", ""), reverse=True)
|
138
|
+
|
139
|
+
# 如果指定了限制,只返回前N个
|
140
|
+
if limit:
|
141
|
+
all_memories = all_memories[:limit]
|
142
|
+
|
143
|
+
# 打印结果摘要
|
144
|
+
PrettyOutput.print(f"检索到 {len(all_memories)} 条记忆", OutputType.INFO)
|
145
|
+
|
146
|
+
if tags:
|
147
|
+
PrettyOutput.print(f"使用标签过滤: {', '.join(tags)}", OutputType.INFO)
|
148
|
+
|
149
|
+
# 格式化为Markdown输出
|
150
|
+
markdown_output = f"# 记忆检索结果\n\n"
|
151
|
+
markdown_output += f"**检索到 {len(all_memories)} 条记忆**\n\n"
|
152
|
+
|
153
|
+
if tags:
|
154
|
+
markdown_output += f"**使用标签过滤**: {', '.join(tags)}\n\n"
|
155
|
+
|
156
|
+
markdown_output += f"**记忆类型**: {', '.join(types_to_search)}\n\n"
|
157
|
+
|
158
|
+
markdown_output += "---\n\n"
|
159
|
+
|
160
|
+
# 输出所有记忆
|
161
|
+
for i, memory in enumerate(all_memories):
|
162
|
+
markdown_output += f"## {i+1}. {memory.get('id', '未知ID')}\n\n"
|
163
|
+
markdown_output += f"**类型**: {memory.get('type', '未知类型')}\n\n"
|
164
|
+
markdown_output += f"**标签**: {', '.join(memory.get('tags', []))}\n\n"
|
165
|
+
markdown_output += f"**创建时间**: {memory.get('created_at', '未知时间')}\n\n"
|
166
|
+
|
167
|
+
# 内容部分
|
168
|
+
content = memory.get('content', '')
|
169
|
+
if content:
|
170
|
+
markdown_output += f"**内容**:\n\n{content}\n\n"
|
171
|
+
|
172
|
+
# 如果有额外的元数据
|
173
|
+
metadata = {k: v for k, v in memory.items()
|
174
|
+
if k not in ['id', 'type', 'tags', 'created_at', 'content']}
|
175
|
+
if metadata:
|
176
|
+
markdown_output += f"**其他信息**:\n"
|
177
|
+
for key, value in metadata.items():
|
178
|
+
markdown_output += f"- {key}: {value}\n"
|
179
|
+
markdown_output += "\n"
|
180
|
+
|
181
|
+
markdown_output += "---\n\n"
|
182
|
+
|
183
|
+
# 如果记忆较多,在终端显示摘要
|
184
|
+
if len(all_memories) > 5:
|
185
|
+
PrettyOutput.print(f"记忆较多,仅显示前5条摘要:", OutputType.INFO)
|
186
|
+
for i, memory in enumerate(all_memories[:5]):
|
187
|
+
content_preview = memory.get("content", "")[:100]
|
188
|
+
if len(memory.get("content", "")) > 100:
|
189
|
+
content_preview += "..."
|
190
|
+
PrettyOutput.print(
|
191
|
+
f"{i+1}. [{memory.get('type')}] {memory.get('id')}\n"
|
192
|
+
f" 标签: {', '.join(memory.get('tags', []))}\n"
|
193
|
+
f" 内容: {content_preview}",
|
194
|
+
OutputType.INFO,
|
195
|
+
)
|
196
|
+
|
197
|
+
return {
|
198
|
+
"success": True,
|
199
|
+
"stdout": markdown_output,
|
200
|
+
"stderr": "",
|
201
|
+
}
|
202
|
+
|
203
|
+
except Exception as e:
|
204
|
+
error_msg = f"检索记忆失败: {str(e)}"
|
205
|
+
PrettyOutput.print(error_msg, OutputType.ERROR)
|
206
|
+
return {"success": False, "stdout": "", "stderr": error_msg}
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
import json
|
3
|
+
from datetime import datetime
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import Any, Dict, List
|
6
|
+
|
7
|
+
from jarvis.jarvis_utils.config import get_data_dir
|
8
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
9
|
+
from jarvis.jarvis_utils.globals import add_short_term_memory
|
10
|
+
|
11
|
+
|
12
|
+
class SaveMemoryTool:
|
13
|
+
"""保存记忆工具,用于将信息保存到长短期记忆系统"""
|
14
|
+
|
15
|
+
name = "save_memory"
|
16
|
+
description = """保存信息到长短期记忆系统。
|
17
|
+
|
18
|
+
支持的记忆类型:
|
19
|
+
- project_long_term: 项目长期记忆(与当前项目相关的信息)
|
20
|
+
- global_long_term: 全局长期记忆(通用的信息、用户喜好、知识、方法等)
|
21
|
+
- short_term: 短期记忆(当前任务相关的信息)
|
22
|
+
|
23
|
+
项目长期记忆存储在当前目录的 .jarvis/memory 下
|
24
|
+
全局长期记忆和短期记忆存储在数据目录的 memory 子目录下
|
25
|
+
"""
|
26
|
+
|
27
|
+
parameters = {
|
28
|
+
"type": "object",
|
29
|
+
"properties": {
|
30
|
+
"memory_type": {
|
31
|
+
"type": "string",
|
32
|
+
"enum": ["project_long_term", "global_long_term", "short_term"],
|
33
|
+
"description": "记忆类型",
|
34
|
+
},
|
35
|
+
"tags": {
|
36
|
+
"type": "array",
|
37
|
+
"items": {"type": "string"},
|
38
|
+
"description": "用于索引记忆的标签列表",
|
39
|
+
},
|
40
|
+
"content": {"type": "string", "description": "要保存的记忆内容"},
|
41
|
+
},
|
42
|
+
"required": ["memory_type", "tags", "content"],
|
43
|
+
}
|
44
|
+
|
45
|
+
def __init__(self):
|
46
|
+
"""初始化保存记忆工具"""
|
47
|
+
self.project_memory_dir = Path(".jarvis/memory")
|
48
|
+
self.global_memory_dir = Path(get_data_dir()) / "memory"
|
49
|
+
|
50
|
+
def _get_memory_dir(self, memory_type: str) -> Path:
|
51
|
+
"""根据记忆类型获取存储目录"""
|
52
|
+
if memory_type == "project_long_term":
|
53
|
+
return self.project_memory_dir
|
54
|
+
elif memory_type in ["global_long_term", "short_term"]:
|
55
|
+
return self.global_memory_dir / memory_type
|
56
|
+
else:
|
57
|
+
raise ValueError(f"未知的记忆类型: {memory_type}")
|
58
|
+
|
59
|
+
def _generate_memory_id(self) -> str:
|
60
|
+
"""生成唯一的记忆ID"""
|
61
|
+
return datetime.now().strftime("%Y%m%d_%H%M%S_%f")
|
62
|
+
|
63
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
64
|
+
"""执行保存记忆操作"""
|
65
|
+
try:
|
66
|
+
memory_type = args["memory_type"]
|
67
|
+
tags = args.get("tags", [])
|
68
|
+
content = args.get("content", "")
|
69
|
+
|
70
|
+
# 生成记忆ID
|
71
|
+
memory_id = self._generate_memory_id()
|
72
|
+
|
73
|
+
# 创建记忆对象
|
74
|
+
memory_data = {
|
75
|
+
"id": memory_id,
|
76
|
+
"type": memory_type,
|
77
|
+
"tags": tags,
|
78
|
+
"content": content,
|
79
|
+
"created_at": datetime.now().isoformat(),
|
80
|
+
"updated_at": datetime.now().isoformat(),
|
81
|
+
}
|
82
|
+
|
83
|
+
if memory_type == "short_term":
|
84
|
+
# 短期记忆保存到全局变量
|
85
|
+
add_short_term_memory(memory_data)
|
86
|
+
|
87
|
+
# 打印成功信息
|
88
|
+
PrettyOutput.print(
|
89
|
+
f"短期记忆已保存\n"
|
90
|
+
f"ID: {memory_id}\n"
|
91
|
+
f"类型: {memory_type}\n"
|
92
|
+
f"标签: {', '.join(tags)}\n"
|
93
|
+
f"存储位置: 内存(非持久化)",
|
94
|
+
OutputType.SUCCESS,
|
95
|
+
)
|
96
|
+
|
97
|
+
result = {
|
98
|
+
"memory_id": memory_id,
|
99
|
+
"memory_type": memory_type,
|
100
|
+
"tags": tags,
|
101
|
+
"storage": "memory",
|
102
|
+
"message": f"短期记忆已成功保存到内存,ID: {memory_id}",
|
103
|
+
}
|
104
|
+
else:
|
105
|
+
# 长期记忆保存到文件
|
106
|
+
# 获取存储目录并确保存在
|
107
|
+
memory_dir = self._get_memory_dir(memory_type)
|
108
|
+
memory_dir.mkdir(parents=True, exist_ok=True)
|
109
|
+
|
110
|
+
# 保存记忆文件
|
111
|
+
memory_file = memory_dir / f"{memory_id}.json"
|
112
|
+
with open(memory_file, "w", encoding="utf-8") as f:
|
113
|
+
json.dump(memory_data, f, ensure_ascii=False, indent=2)
|
114
|
+
|
115
|
+
# 打印成功信息
|
116
|
+
PrettyOutput.print(
|
117
|
+
f"记忆已保存\n"
|
118
|
+
f"ID: {memory_id}\n"
|
119
|
+
f"类型: {memory_type}\n"
|
120
|
+
f"标签: {', '.join(tags)}\n"
|
121
|
+
f"位置: {memory_file}",
|
122
|
+
OutputType.SUCCESS,
|
123
|
+
)
|
124
|
+
|
125
|
+
result = {
|
126
|
+
"memory_id": memory_id,
|
127
|
+
"memory_type": memory_type,
|
128
|
+
"tags": tags,
|
129
|
+
"file_path": str(memory_file),
|
130
|
+
"message": f"记忆已成功保存,ID: {memory_id}",
|
131
|
+
}
|
132
|
+
|
133
|
+
return {
|
134
|
+
"success": True,
|
135
|
+
"stdout": json.dumps(result, ensure_ascii=False, indent=2),
|
136
|
+
"stderr": "",
|
137
|
+
}
|
138
|
+
|
139
|
+
except Exception as e:
|
140
|
+
error_msg = f"保存记忆失败: {str(e)}"
|
141
|
+
PrettyOutput.print(error_msg, OutputType.ERROR)
|
142
|
+
return {"success": False, "stdout": "", "stderr": error_msg}
|
jarvis/jarvis_utils/globals.py
CHANGED
@@ -10,11 +10,16 @@
|
|
10
10
|
import os
|
11
11
|
|
12
12
|
# 全局变量:保存消息历史
|
13
|
-
from typing import Any, Dict, Set, List
|
13
|
+
from typing import Any, Dict, Set, List, Optional
|
14
|
+
from datetime import datetime
|
14
15
|
|
15
16
|
message_history: List[str] = []
|
16
17
|
MAX_HISTORY_SIZE = 50
|
17
18
|
|
19
|
+
# 短期记忆存储
|
20
|
+
short_term_memories: List[Dict[str, Any]] = []
|
21
|
+
MAX_SHORT_TERM_MEMORIES = 100
|
22
|
+
|
18
23
|
import colorama
|
19
24
|
from rich.console import Console
|
20
25
|
from rich.theme import Theme
|
@@ -207,3 +212,117 @@ def get_message_history() -> List[str]:
|
|
207
212
|
"""
|
208
213
|
global message_history
|
209
214
|
return message_history
|
215
|
+
|
216
|
+
|
217
|
+
def add_short_term_memory(memory_data: Dict[str, Any]) -> None:
|
218
|
+
"""
|
219
|
+
添加短期记忆到全局存储。
|
220
|
+
|
221
|
+
参数:
|
222
|
+
memory_data: 包含记忆信息的字典
|
223
|
+
"""
|
224
|
+
global short_term_memories
|
225
|
+
short_term_memories.append(memory_data)
|
226
|
+
# 如果超过最大数量,删除最旧的记忆
|
227
|
+
if len(short_term_memories) > MAX_SHORT_TERM_MEMORIES:
|
228
|
+
short_term_memories.pop(0)
|
229
|
+
|
230
|
+
|
231
|
+
def get_short_term_memories(tags: Optional[List[str]] = None) -> List[Dict[str, Any]]:
|
232
|
+
"""
|
233
|
+
获取短期记忆,可选择按标签过滤。
|
234
|
+
|
235
|
+
参数:
|
236
|
+
tags: 用于过滤的标签列表(可选)
|
237
|
+
|
238
|
+
返回:
|
239
|
+
List[Dict[str, Any]]: 符合条件的短期记忆列表
|
240
|
+
"""
|
241
|
+
global short_term_memories
|
242
|
+
if not tags:
|
243
|
+
return short_term_memories.copy()
|
244
|
+
|
245
|
+
# 按标签过滤
|
246
|
+
filtered_memories = []
|
247
|
+
for memory in short_term_memories:
|
248
|
+
memory_tags = memory.get("tags", [])
|
249
|
+
if any(tag in memory_tags for tag in tags):
|
250
|
+
filtered_memories.append(memory)
|
251
|
+
|
252
|
+
return filtered_memories
|
253
|
+
|
254
|
+
|
255
|
+
def clear_short_term_memories() -> None:
|
256
|
+
"""
|
257
|
+
清空所有短期记忆。
|
258
|
+
"""
|
259
|
+
global short_term_memories
|
260
|
+
short_term_memories.clear()
|
261
|
+
|
262
|
+
|
263
|
+
def get_all_memory_tags() -> Dict[str, List[str]]:
|
264
|
+
"""
|
265
|
+
获取所有记忆类型中的标签集合。
|
266
|
+
每个类型最多返回200个标签,超过时随机提取。
|
267
|
+
|
268
|
+
返回:
|
269
|
+
Dict[str, List[str]]: 按记忆类型分组的标签列表
|
270
|
+
"""
|
271
|
+
from pathlib import Path
|
272
|
+
import json
|
273
|
+
import random
|
274
|
+
from jarvis.jarvis_utils.config import get_data_dir
|
275
|
+
|
276
|
+
tags_by_type = {
|
277
|
+
"short_term": [],
|
278
|
+
"project_long_term": [],
|
279
|
+
"global_long_term": []
|
280
|
+
}
|
281
|
+
|
282
|
+
MAX_TAGS_PER_TYPE = 200
|
283
|
+
|
284
|
+
# 获取短期记忆标签
|
285
|
+
short_term_tags = set()
|
286
|
+
for memory in short_term_memories:
|
287
|
+
short_term_tags.update(memory.get("tags", []))
|
288
|
+
short_term_tags_list = sorted(list(short_term_tags))
|
289
|
+
if len(short_term_tags_list) > MAX_TAGS_PER_TYPE:
|
290
|
+
tags_by_type["short_term"] = sorted(random.sample(short_term_tags_list, MAX_TAGS_PER_TYPE))
|
291
|
+
else:
|
292
|
+
tags_by_type["short_term"] = short_term_tags_list
|
293
|
+
|
294
|
+
# 获取项目长期记忆标签
|
295
|
+
project_memory_dir = Path(".jarvis/memory")
|
296
|
+
if project_memory_dir.exists():
|
297
|
+
project_tags = set()
|
298
|
+
for memory_file in project_memory_dir.glob("*.json"):
|
299
|
+
try:
|
300
|
+
with open(memory_file, "r", encoding="utf-8") as f:
|
301
|
+
memory_data = json.load(f)
|
302
|
+
project_tags.update(memory_data.get("tags", []))
|
303
|
+
except Exception:
|
304
|
+
pass
|
305
|
+
project_tags_list = sorted(list(project_tags))
|
306
|
+
if len(project_tags_list) > MAX_TAGS_PER_TYPE:
|
307
|
+
tags_by_type["project_long_term"] = sorted(random.sample(project_tags_list, MAX_TAGS_PER_TYPE))
|
308
|
+
else:
|
309
|
+
tags_by_type["project_long_term"] = project_tags_list
|
310
|
+
|
311
|
+
# 获取全局长期记忆标签
|
312
|
+
global_memory_dir = Path(get_data_dir()) / "memory" / "global_long_term"
|
313
|
+
if global_memory_dir.exists():
|
314
|
+
global_tags = set()
|
315
|
+
for memory_file in global_memory_dir.glob("*.json"):
|
316
|
+
try:
|
317
|
+
with open(memory_file, "r", encoding="utf-8") as f:
|
318
|
+
memory_data = json.load(f)
|
319
|
+
global_tags.update(memory_data.get("tags", []))
|
320
|
+
except Exception:
|
321
|
+
pass
|
322
|
+
global_tags_list = sorted(list(global_tags))
|
323
|
+
if len(global_tags_list) > MAX_TAGS_PER_TYPE:
|
324
|
+
tags_by_type["global_long_term"] = sorted(random.sample(global_tags_list, MAX_TAGS_PER_TYPE))
|
325
|
+
else:
|
326
|
+
tags_by_type["global_long_term"] = global_tags_list
|
327
|
+
|
328
|
+
return tags_by_type
|
jarvis/jarvis_utils/utils.py
CHANGED
@@ -30,6 +30,35 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
30
30
|
|
31
31
|
g_config_file = None
|
32
32
|
|
33
|
+
COMMAND_MAPPING = {
|
34
|
+
# jarvis主命令
|
35
|
+
"jvs": "jarvis",
|
36
|
+
# 代码代理
|
37
|
+
"jca": "jarvis-code-agent",
|
38
|
+
# 智能shell
|
39
|
+
"jss": "jarvis-smart-shell",
|
40
|
+
# 平台管理
|
41
|
+
"jpm": "jarvis-platform-manager",
|
42
|
+
# Git提交
|
43
|
+
"jgc": "jarvis-git-commit",
|
44
|
+
# 代码审查
|
45
|
+
"jcr": "jarvis-code-review",
|
46
|
+
# Git压缩
|
47
|
+
"jgs": "jarvis-git-squash",
|
48
|
+
# 多代理
|
49
|
+
"jma": "jarvis-multi-agent",
|
50
|
+
# 代理
|
51
|
+
"ja": "jarvis-agent",
|
52
|
+
# 工具
|
53
|
+
"jt": "jarvis-tool",
|
54
|
+
# 方法论
|
55
|
+
"jm": "jarvis-methodology",
|
56
|
+
# RAG
|
57
|
+
"jrg": "jarvis-rag",
|
58
|
+
# 统计
|
59
|
+
"jst": "jarvis-stats",
|
60
|
+
}
|
61
|
+
|
33
62
|
|
34
63
|
def _setup_signal_handler() -> None:
|
35
64
|
"""设置SIGINT信号处理函数"""
|
@@ -149,6 +178,15 @@ def _show_usage_stats() -> None:
|
|
149
178
|
elif group == "command":
|
150
179
|
categorized_stats["command"]["metrics"][metric] = int(total)
|
151
180
|
|
181
|
+
# 合并长短命令的历史统计数据
|
182
|
+
command_stats = categorized_stats["command"]["metrics"]
|
183
|
+
if command_stats:
|
184
|
+
merged_stats: Dict[str, int] = {}
|
185
|
+
for metric, count in command_stats.items():
|
186
|
+
long_command = COMMAND_MAPPING.get(metric, metric)
|
187
|
+
merged_stats[long_command] = merged_stats.get(long_command, 0) + count
|
188
|
+
categorized_stats["command"]["metrics"] = merged_stats
|
189
|
+
|
152
190
|
# 计算采纳率并添加到统计中
|
153
191
|
commit_stats = categorized_stats["commit"]["metrics"]
|
154
192
|
# 尝试多种可能的指标名称
|
@@ -348,7 +386,7 @@ def _show_usage_stats() -> None:
|
|
348
386
|
remaining_days_after_months = remaining_days_after_years % 20
|
349
387
|
work_days = remaining_days_after_months
|
350
388
|
remaining_hours = int(hours % 8) # 剩余不足一个工作日的小时数
|
351
|
-
|
389
|
+
|
352
390
|
# 构建时间描述
|
353
391
|
time_parts = []
|
354
392
|
if work_years > 0:
|
@@ -359,17 +397,25 @@ def _show_usage_stats() -> None:
|
|
359
397
|
time_parts.append(f"{work_days} 个工作日")
|
360
398
|
if remaining_hours > 0:
|
361
399
|
time_parts.append(f"{remaining_hours} 小时")
|
362
|
-
|
400
|
+
|
363
401
|
if time_parts:
|
364
402
|
time_description = "、".join(time_parts)
|
365
403
|
if work_years >= 1:
|
366
|
-
encouragement =
|
404
|
+
encouragement = (
|
405
|
+
f"🎉 相当于节省了 {time_description} 的工作时间!"
|
406
|
+
)
|
367
407
|
elif work_months >= 1:
|
368
|
-
encouragement =
|
408
|
+
encouragement = (
|
409
|
+
f"🚀 相当于节省了 {time_description} 的工作时间!"
|
410
|
+
)
|
369
411
|
elif work_days >= 1:
|
370
|
-
encouragement =
|
412
|
+
encouragement = (
|
413
|
+
f"💪 相当于节省了 {time_description} 的工作时间!"
|
414
|
+
)
|
371
415
|
else:
|
372
|
-
encouragement =
|
416
|
+
encouragement = (
|
417
|
+
f"✨ 相当于节省了 {time_description} 的工作时间!"
|
418
|
+
)
|
373
419
|
elif hours >= 1:
|
374
420
|
encouragement = f"⭐ 相当于节省了 {int(hours)} 小时的工作时间,积少成多,继续保持!"
|
375
421
|
if encouragement:
|
@@ -459,7 +505,9 @@ def load_config():
|
|
459
505
|
if schema_path.exists():
|
460
506
|
try:
|
461
507
|
config_file_path.parent.mkdir(parents=True, exist_ok=True)
|
462
|
-
generate_default_config(
|
508
|
+
generate_default_config(
|
509
|
+
str(schema_path.absolute()), str(config_file_path)
|
510
|
+
)
|
463
511
|
PrettyOutput.print(
|
464
512
|
f"已生成默认配置文件: {config_file_path}", OutputType.INFO
|
465
513
|
)
|
@@ -576,7 +624,7 @@ def generate_default_config(schema_path: str, output_path: str) -> None:
|
|
576
624
|
|
577
625
|
default_config = _generate_from_schema(schema)
|
578
626
|
|
579
|
-
content = f"# yaml-language-server: $schema={
|
627
|
+
content = f"# yaml-language-server: $schema={schema_path}\n"
|
580
628
|
content += yaml.dump(default_config, allow_unicode=True, sort_keys=False)
|
581
629
|
|
582
630
|
with open(output_path, "w", encoding="utf-8") as f:
|
@@ -718,43 +766,13 @@ def count_cmd_usage() -> None:
|
|
718
766
|
import os
|
719
767
|
from jarvis.jarvis_stats.stats import StatsManager
|
720
768
|
|
721
|
-
# 命令映射关系:将短命令映射到长命令
|
722
|
-
command_mapping = {
|
723
|
-
# jarvis主命令
|
724
|
-
"jvs": "jarvis",
|
725
|
-
# 代码代理
|
726
|
-
"jca": "jarvis-code-agent",
|
727
|
-
# 智能shell
|
728
|
-
"jss": "jarvis-smart-shell",
|
729
|
-
# 平台管理
|
730
|
-
"jpm": "jarvis-platform-manager",
|
731
|
-
# Git提交
|
732
|
-
"jgc": "jarvis-git-commit",
|
733
|
-
# 代码审查
|
734
|
-
"jcr": "jarvis-code-review",
|
735
|
-
# Git压缩
|
736
|
-
"jgs": "jarvis-git-squash",
|
737
|
-
# 多代理
|
738
|
-
"jma": "jarvis-multi-agent",
|
739
|
-
# 代理
|
740
|
-
"ja": "jarvis-agent",
|
741
|
-
# 工具
|
742
|
-
"jt": "jarvis-tool",
|
743
|
-
# 方法论
|
744
|
-
"jm": "jarvis-methodology",
|
745
|
-
# RAG
|
746
|
-
"jrg": "jarvis-rag",
|
747
|
-
# 统计
|
748
|
-
"jst": "jarvis-stats",
|
749
|
-
}
|
750
|
-
|
751
769
|
# 从完整路径中提取命令名称
|
752
770
|
cmd_path = sys.argv[0]
|
753
771
|
cmd_name = os.path.basename(cmd_path)
|
754
|
-
|
772
|
+
|
755
773
|
# 如果是短命令,映射到长命令
|
756
|
-
if cmd_name in
|
757
|
-
metric_name =
|
774
|
+
if cmd_name in COMMAND_MAPPING:
|
775
|
+
metric_name = COMMAND_MAPPING[cmd_name]
|
758
776
|
else:
|
759
777
|
metric_name = cmd_name
|
760
778
|
|
@@ -1,7 +1,7 @@
|
|
1
|
-
jarvis/__init__.py,sha256=
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=
|
1
|
+
jarvis/__init__.py,sha256=LeVLn20oHpcp1TpDsXJ8P6m_z_MKXTzTQvPUv3CRNK4,73
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=nhJ9QOdFQJHpdLsFO0_JNH0XJHvXxMDHDTP4b7-OSnA,26370
|
3
3
|
jarvis/jarvis_agent/builtin_input_handler.py,sha256=Qs4LAr4xdKLBJpQE81YP4CkucAop86ms0iVoKa1nnso,2468
|
4
|
-
jarvis/jarvis_agent/edit_file_handler.py,sha256=
|
4
|
+
jarvis/jarvis_agent/edit_file_handler.py,sha256=w-byNJ4TN_SlV3djjfFC7OksySOFGrM8ku49w662dzc,11854
|
5
5
|
jarvis/jarvis_agent/jarvis.py,sha256=L2sI-Y7gxqH6M4E4F2GlNoZcxxvz_f72rxvjh7bxuZE,8443
|
6
6
|
jarvis/jarvis_agent/main.py,sha256=56pLVy6v-3ZdyPCcWXdRkgbjmYsoIfC7zrA6B7sYivU,3334
|
7
7
|
jarvis/jarvis_agent/output_handler.py,sha256=P7oWpXBGFfOsWq7cIhS_z9crkQ19ES7qU5pM92KKjAs,1172
|
@@ -12,7 +12,7 @@ jarvis/jarvis_agent/session_manager.py,sha256=DnvI9rWkVmkyO1XfKZyo9lTn4ajg4ccwzE
|
|
12
12
|
jarvis/jarvis_agent/shell_input_handler.py,sha256=1IboqdxcJuoIqRpmDU10GugR9fWXUHyCEbVF4nIWbyo,1328
|
13
13
|
jarvis/jarvis_agent/tool_executor.py,sha256=nIq-sPNgrtimtM-IHpN09cWmId8jDzWRdCFoRzXnnoo,1721
|
14
14
|
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
-
jarvis/jarvis_code_agent/code_agent.py,sha256=
|
15
|
+
jarvis/jarvis_code_agent/code_agent.py,sha256=C761NUsz3W_SLJLEj6Y_HB9ox-joOlnJQ9CsfE88IFk,29100
|
16
16
|
jarvis/jarvis_code_agent/lint.py,sha256=LZPsfyZPMo7Wm7LN4osZocuNJwZx1ojacO3MlF870x8,4009
|
17
17
|
jarvis/jarvis_code_analysis/code_review.py,sha256=TMov1pqDe1bg0vM1ndnYeW9ejHrRN_jMroo3T4L9yag,32368
|
18
18
|
jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=LIXAYa1sW3l7foP6kohLWnE98I_EQ0T7z5bYKHq6rJA,78
|
@@ -46,7 +46,7 @@ jarvis/jarvis_mcp/stdio_mcp_client.py,sha256=APYUksYKlMx7AVNODKOLrTkKZPnp4kqTQIY
|
|
46
46
|
jarvis/jarvis_mcp/streamable_mcp_client.py,sha256=sP0KEsxVcXGht0eA7a_m-ECtZAk39s4PL9OUdm35x2Y,14467
|
47
47
|
jarvis/jarvis_methodology/main.py,sha256=6QF8hH3vB6rfxim0fPR34uVPf41zVpb4ZLqrFN2qONg,10983
|
48
48
|
jarvis/jarvis_multi_agent/__init__.py,sha256=kCgtAX7VvliyEOQxIj2DvNjRAuh6bpNaOtDn60nzph4,6089
|
49
|
-
jarvis/jarvis_multi_agent/main.py,sha256=
|
49
|
+
jarvis/jarvis_multi_agent/main.py,sha256=Wbarez48QxXexlKEOcRsoMbcQEOP5rv_DzGkNk0SfpY,1779
|
50
50
|
jarvis/jarvis_platform/__init__.py,sha256=WLQHSiE87PPket2M50_hHzjdMIgPIBx2VF8JfB_NNRk,105
|
51
51
|
jarvis/jarvis_platform/ai8.py,sha256=uiL1BkONteUB2aXg6kMGSXLLOhzGDl5_SNQYyQzmFNk,11412
|
52
52
|
jarvis/jarvis_platform/base.py,sha256=cfeYB6ldfQH1tz1rroQpmJTLAw8KByKS74qun0pqE1c,9498
|
@@ -86,7 +86,9 @@ jarvis/jarvis_tools/methodology.py,sha256=_K4GIDUodGEma3SvNRo7Qs5rliijgNespVLyAP
|
|
86
86
|
jarvis/jarvis_tools/read_code.py,sha256=EnI-R-5HyIQYhMD391nZWXHIuHHBF-OJIRE0QpLcPX4,6417
|
87
87
|
jarvis/jarvis_tools/read_webpage.py,sha256=NmDUboVZd4CGHBPRFK6dp3uqVhuGopW1bOi3TcaLDF4,2092
|
88
88
|
jarvis/jarvis_tools/registry.py,sha256=8qhZgmmGIXJsYwtpsp_Ls8woT0qmBrthF8lIuQqOu7c,28614
|
89
|
+
jarvis/jarvis_tools/retrieve_memory.py,sha256=CKmNym5FxHjgdc0my4IlsJ3TB3E2m0aCNFSRWjH6fKs,8221
|
89
90
|
jarvis/jarvis_tools/rewrite_file.py,sha256=eG_WKg6cVAXmuGwUqlWkcuyay5S8DOzEi8vZCmX3O8w,7255
|
91
|
+
jarvis/jarvis_tools/save_memory.py,sha256=4KRJWiyeyaIfdjeCAflPrxJ5ZXA4gUL3tv9h6d6sFKc,5309
|
90
92
|
jarvis/jarvis_tools/search_web.py,sha256=zh6EYLQPIQneoz27Hheh-fifMeMNhrTVldXKMSsMz2Y,5801
|
91
93
|
jarvis/jarvis_tools/virtual_tty.py,sha256=LTsg1PlsPvgaLShUaxpAKwTpyjXRr0l0qSREI7Q-fBc,26349
|
92
94
|
jarvis/jarvis_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -97,16 +99,16 @@ jarvis/jarvis_utils/config.py,sha256=-ZgqIkzsp8VP5qsXke9XAGuwtAB9XlOAo_k4L6jhcrE
|
|
97
99
|
jarvis/jarvis_utils/embedding.py,sha256=oEOEM2qf16DMYwPsQe6srET9BknyjOdY2ef0jsp3Or8,2714
|
98
100
|
jarvis/jarvis_utils/file_processors.py,sha256=XiM248SHS7lLgQDCbORVFWqinbVDUawYxWDOsLXDxP8,3043
|
99
101
|
jarvis/jarvis_utils/git_utils.py,sha256=dkC0HcUdm_rF5vXNoLByne3mGykZEviD3Lo_SYbwROU,21667
|
100
|
-
jarvis/jarvis_utils/globals.py,sha256=
|
102
|
+
jarvis/jarvis_utils/globals.py,sha256=lpS1lmWRnLgqOeoyhZlktdZK9SK8YMekc6XWamho0Jw,8561
|
101
103
|
jarvis/jarvis_utils/http.py,sha256=eRhV3-GYuWmQ0ogq9di9WMlQkFcVb1zGCrySnOgT1x0,4392
|
102
104
|
jarvis/jarvis_utils/input.py,sha256=g0Xa1TNZHxLaYduREV_Wc55iqHD6djN73YFJbR83gUg,9488
|
103
105
|
jarvis/jarvis_utils/methodology.py,sha256=EqS9feS3HHgNcKYoGs-Dkhp4pGwylwXt96r2J61cxUo,9223
|
104
106
|
jarvis/jarvis_utils/output.py,sha256=E_J_RYXtkOgRiDSHCRE9QPHY8WQmmhIotQtIQru8GZA,10888
|
105
107
|
jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
|
106
|
-
jarvis/jarvis_utils/utils.py,sha256=
|
107
|
-
jarvis_ai_assistant-0.2.
|
108
|
-
jarvis_ai_assistant-0.2.
|
109
|
-
jarvis_ai_assistant-0.2.
|
110
|
-
jarvis_ai_assistant-0.2.
|
111
|
-
jarvis_ai_assistant-0.2.
|
112
|
-
jarvis_ai_assistant-0.2.
|
108
|
+
jarvis/jarvis_utils/utils.py,sha256=b7t2BsoPEU_3ZhippcQW9qwQD0PO-sGkjjtZ4DvwI2s,37056
|
109
|
+
jarvis_ai_assistant-0.2.6.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
110
|
+
jarvis_ai_assistant-0.2.6.dist-info/METADATA,sha256=4XIqrWX0_tWmBC88XLFVlZGa2nzIbijiUxVW4g0y20I,16807
|
111
|
+
jarvis_ai_assistant-0.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
112
|
+
jarvis_ai_assistant-0.2.6.dist-info/entry_points.txt,sha256=8cwi1VxZGU5UeSZMFiH-jG6NK95Asjukj5SBLBrGiGo,1257
|
113
|
+
jarvis_ai_assistant-0.2.6.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
114
|
+
jarvis_ai_assistant-0.2.6.dist-info/RECORD,,
|
File without changes
|
{jarvis_ai_assistant-0.2.5.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/entry_points.txt
RENAMED
File without changes
|
{jarvis_ai_assistant-0.2.5.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
File without changes
|