jarvis-ai-assistant 0.2.5__py3-none-any.whl → 0.2.7__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.
@@ -0,0 +1,252 @@
1
+ # -*- coding: utf-8 -*-
2
+ import json
3
+ import shutil
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 (
10
+ clear_short_term_memories,
11
+ get_short_term_memories,
12
+ short_term_memories,
13
+ )
14
+
15
+
16
+ class ClearMemoryTool:
17
+ """清除记忆工具,用于批量清除指定的记忆"""
18
+
19
+ name = "clear_memory"
20
+ description = """批量清除指定的记忆。
21
+
22
+ 支持的清除方式:
23
+ 1. 按记忆类型清除所有记忆
24
+ 2. 按标签清除特定记忆
25
+ 3. 按记忆ID清除单个记忆
26
+
27
+ 支持的记忆类型:
28
+ - project_long_term: 项目长期记忆
29
+ - global_long_term: 全局长期记忆
30
+ - short_term: 短期记忆
31
+ - all: 所有类型的记忆
32
+
33
+ 注意:清除操作不可恢复,请谨慎使用
34
+ """
35
+
36
+ parameters = {
37
+ "type": "object",
38
+ "properties": {
39
+ "memory_types": {
40
+ "type": "array",
41
+ "items": {
42
+ "type": "string",
43
+ "enum": [
44
+ "project_long_term",
45
+ "global_long_term",
46
+ "short_term",
47
+ "all",
48
+ ],
49
+ },
50
+ "description": "要清除的记忆类型列表",
51
+ },
52
+ "tags": {
53
+ "type": "array",
54
+ "items": {"type": "string"},
55
+ "description": "要清除的记忆标签列表(可选,如果指定则只清除带有这些标签的记忆)",
56
+ },
57
+ "memory_ids": {
58
+ "type": "array",
59
+ "items": {"type": "string"},
60
+ "description": "要清除的具体记忆ID列表(可选)",
61
+ },
62
+ "confirm": {
63
+ "type": "boolean",
64
+ "description": "确认清除操作(必须为true才会执行清除)",
65
+ "default": False,
66
+ },
67
+ },
68
+ "required": ["memory_types", "confirm"],
69
+ }
70
+
71
+ def __init__(self):
72
+ """初始化清除记忆工具"""
73
+ self.project_memory_dir = Path(".jarvis/memory")
74
+ self.global_memory_dir = Path(get_data_dir()) / "memory"
75
+
76
+ def _get_memory_dir(self, memory_type: str) -> Path:
77
+ """根据记忆类型获取存储目录"""
78
+ if memory_type == "project_long_term":
79
+ return self.project_memory_dir
80
+ elif memory_type in ["global_long_term", "short_term"]:
81
+ return self.global_memory_dir / memory_type
82
+ else:
83
+ raise ValueError(f"未知的记忆类型: {memory_type}")
84
+
85
+ def _clear_short_term_memories(
86
+ self, tags: Optional[List[str]] = None, memory_ids: Optional[List[str]] = None
87
+ ) -> Dict[str, int]:
88
+ """清除短期记忆"""
89
+ global short_term_memories
90
+
91
+ initial_count = len(short_term_memories)
92
+ removed_count = 0
93
+
94
+ if memory_ids:
95
+ # 按ID清除
96
+ new_memories = []
97
+ for memory in short_term_memories:
98
+ if memory.get("id") not in memory_ids:
99
+ new_memories.append(memory)
100
+ else:
101
+ removed_count += 1
102
+ short_term_memories[:] = new_memories
103
+ elif tags:
104
+ # 按标签清除
105
+ new_memories = []
106
+ for memory in short_term_memories:
107
+ memory_tags = memory.get("tags", [])
108
+ if not any(tag in memory_tags for tag in tags):
109
+ new_memories.append(memory)
110
+ else:
111
+ removed_count += 1
112
+ short_term_memories[:] = new_memories
113
+ else:
114
+ # 清除所有
115
+ clear_short_term_memories()
116
+ removed_count = initial_count
117
+
118
+ return {"total": initial_count, "removed": removed_count}
119
+
120
+ def _clear_long_term_memories(
121
+ self,
122
+ memory_type: str,
123
+ tags: Optional[List[str]] = None,
124
+ memory_ids: Optional[List[str]] = None,
125
+ ) -> Dict[str, int]:
126
+ """清除长期记忆"""
127
+ memory_dir = self._get_memory_dir(memory_type)
128
+
129
+ if not memory_dir.exists():
130
+ return {"total": 0, "removed": 0}
131
+
132
+ total_count = 0
133
+ removed_count = 0
134
+
135
+ # 获取所有记忆文件
136
+ memory_files = list(memory_dir.glob("*.json"))
137
+ total_count = len(memory_files)
138
+
139
+ for memory_file in memory_files:
140
+ try:
141
+ # 读取记忆内容
142
+ with open(memory_file, "r", encoding="utf-8") as f:
143
+ memory_data = json.load(f)
144
+
145
+ should_remove = False
146
+
147
+ if memory_ids:
148
+ # 按ID判断
149
+ if memory_data.get("id") in memory_ids:
150
+ should_remove = True
151
+ elif tags:
152
+ # 按标签判断
153
+ memory_tags = memory_data.get("tags", [])
154
+ if any(tag in memory_tags for tag in tags):
155
+ should_remove = True
156
+ else:
157
+ # 清除所有
158
+ should_remove = True
159
+
160
+ if should_remove:
161
+ memory_file.unlink()
162
+ removed_count += 1
163
+
164
+ except Exception as e:
165
+ PrettyOutput.print(
166
+ f"处理记忆文件 {memory_file} 时出错: {str(e)}", OutputType.WARNING
167
+ )
168
+
169
+ # 如果目录为空,可以删除目录
170
+ if not any(memory_dir.iterdir()) and memory_dir != self.project_memory_dir:
171
+ memory_dir.rmdir()
172
+
173
+ return {"total": total_count, "removed": removed_count}
174
+
175
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
176
+ """执行清除记忆操作"""
177
+ try:
178
+ memory_types = args.get("memory_types", [])
179
+ tags = args.get("tags", [])
180
+ memory_ids = args.get("memory_ids", [])
181
+ confirm = args.get("confirm", False)
182
+
183
+ if not confirm:
184
+ return {
185
+ "success": False,
186
+ "stdout": "",
187
+ "stderr": "必须设置 confirm=true 才能执行清除操作",
188
+ }
189
+
190
+ # 确定要清除的记忆类型
191
+ if "all" in memory_types:
192
+ types_to_clear = ["project_long_term", "global_long_term", "short_term"]
193
+ else:
194
+ types_to_clear = memory_types
195
+
196
+ # 统计结果
197
+ results = {}
198
+ total_removed = 0
199
+
200
+ # 清除各类型的记忆
201
+ for memory_type in types_to_clear:
202
+ if memory_type == "short_term":
203
+ result = self._clear_short_term_memories(tags, memory_ids)
204
+ else:
205
+ result = self._clear_long_term_memories(
206
+ memory_type, tags, memory_ids
207
+ )
208
+
209
+ results[memory_type] = result
210
+ total_removed += result["removed"]
211
+
212
+ # 生成结果报告
213
+ PrettyOutput.print(
214
+ f"记忆清除完成,共清除 {total_removed} 条记忆", OutputType.SUCCESS
215
+ )
216
+
217
+ # 详细报告
218
+ report = f"# 记忆清除报告\n\n"
219
+ report += f"**总计清除**: {total_removed} 条记忆\n\n"
220
+
221
+ if tags:
222
+ report += f"**使用标签过滤**: {', '.join(tags)}\n\n"
223
+
224
+ if memory_ids:
225
+ report += f"**指定记忆ID**: {', '.join(memory_ids)}\n\n"
226
+
227
+ report += "## 详细结果\n\n"
228
+
229
+ for memory_type, result in results.items():
230
+ report += f"### {memory_type}\n"
231
+ report += f"- 原有记忆: {result['total']} 条\n"
232
+ report += f"- 已清除: {result['removed']} 条\n"
233
+ report += f"- 剩余: {result['total'] - result['removed']} 条\n\n"
234
+
235
+ # 在终端显示摘要
236
+ for memory_type, result in results.items():
237
+ if result["removed"] > 0:
238
+ PrettyOutput.print(
239
+ f"{memory_type}: 清除了 {result['removed']}/{result['total']} 条记忆",
240
+ OutputType.INFO,
241
+ )
242
+
243
+ return {
244
+ "success": True,
245
+ "stdout": report,
246
+ "stderr": "",
247
+ }
248
+
249
+ except Exception as e:
250
+ error_msg = f"清除记忆失败: {str(e)}"
251
+ PrettyOutput.print(error_msg, OutputType.ERROR)
252
+ return {"success": False, "stdout": "", "stderr": error_msg}
@@ -0,0 +1,212 @@
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
+ 注意:标签数量建议不要超过10个,以保证检索效率
26
+ """
27
+
28
+ parameters = {
29
+ "type": "object",
30
+ "properties": {
31
+ "memory_types": {
32
+ "type": "array",
33
+ "items": {
34
+ "type": "string",
35
+ "enum": [
36
+ "project_long_term",
37
+ "global_long_term",
38
+ "short_term",
39
+ "all",
40
+ ],
41
+ },
42
+ "description": "要检索的记忆类型列表,如果包含'all'则检索所有类型",
43
+ },
44
+ "tags": {
45
+ "type": "array",
46
+ "items": {"type": "string"},
47
+ "description": "用于过滤的标签列表(可选)",
48
+ },
49
+ "limit": {
50
+ "type": "integer",
51
+ "description": "返回结果的最大数量(可选,默认返回所有)",
52
+ "minimum": 1,
53
+ },
54
+ },
55
+ "required": ["memory_types"],
56
+ }
57
+
58
+ def __init__(self):
59
+ """初始化检索记忆工具"""
60
+ self.project_memory_dir = Path(".jarvis/memory")
61
+ self.global_memory_dir = Path(get_data_dir()) / "memory"
62
+
63
+ def _get_memory_dir(self, memory_type: str) -> Path:
64
+ """根据记忆类型获取存储目录"""
65
+ if memory_type == "project_long_term":
66
+ return self.project_memory_dir
67
+ elif memory_type in ["global_long_term", "short_term"]:
68
+ return self.global_memory_dir / memory_type
69
+ else:
70
+ raise ValueError(f"未知的记忆类型: {memory_type}")
71
+
72
+ def _retrieve_from_type(
73
+ self, memory_type: str, tags: Optional[List[str]] = None
74
+ ) -> List[Dict[str, Any]]:
75
+ """从指定类型中检索记忆"""
76
+ memories: List[Dict[str, Any]] = []
77
+
78
+ if memory_type == "short_term":
79
+ # 从全局变量获取短期记忆
80
+ memories = get_short_term_memories(tags)
81
+ else:
82
+ # 从文件系统获取长期记忆
83
+ memory_dir = self._get_memory_dir(memory_type)
84
+
85
+ if not memory_dir.exists():
86
+ return memories
87
+
88
+ # 遍历记忆文件
89
+ for memory_file in memory_dir.glob("*.json"):
90
+ try:
91
+ with open(memory_file, "r", encoding="utf-8") as f:
92
+ memory_data = json.load(f)
93
+
94
+ # 如果指定了标签,检查是否匹配
95
+ if tags:
96
+ memory_tags = memory_data.get("tags", [])
97
+ if not any(tag in memory_tags for tag in tags):
98
+ continue
99
+
100
+ memories.append(memory_data)
101
+ except Exception as e:
102
+ PrettyOutput.print(
103
+ f"读取记忆文件 {memory_file} 失败: {str(e)}", OutputType.WARNING
104
+ )
105
+
106
+ return memories
107
+
108
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
109
+ """执行检索记忆操作"""
110
+ try:
111
+ memory_types = args.get("memory_types", [])
112
+ tags = args.get("tags", [])
113
+ limit = args.get("limit", None)
114
+
115
+ # 确定要检索的记忆类型
116
+ if "all" in memory_types:
117
+ types_to_search = [
118
+ "project_long_term",
119
+ "global_long_term",
120
+ "short_term",
121
+ ]
122
+ else:
123
+ types_to_search = memory_types
124
+
125
+ # 从各个类型中检索记忆
126
+ all_memories = []
127
+ for memory_type in types_to_search:
128
+ memories = self._retrieve_from_type(memory_type, tags)
129
+ all_memories.extend(memories)
130
+
131
+ # 按创建时间排序(最新的在前)
132
+ all_memories.sort(key=lambda x: x.get("created_at", ""), reverse=True)
133
+
134
+ # 限制最多返回50条记忆,随机选取
135
+ if len(all_memories) > 50:
136
+ all_memories = random.sample(all_memories, 50)
137
+ # 重新排序,保持时间顺序
138
+ all_memories.sort(key=lambda x: x.get("created_at", ""), reverse=True)
139
+
140
+ # 如果指定了限制,只返回前N个
141
+ if limit:
142
+ all_memories = all_memories[:limit]
143
+
144
+ # 打印结果摘要
145
+ PrettyOutput.print(f"检索到 {len(all_memories)} 条记忆", OutputType.INFO)
146
+
147
+ if tags:
148
+ PrettyOutput.print(f"使用标签过滤: {', '.join(tags)}", OutputType.INFO)
149
+
150
+ # 格式化为Markdown输出
151
+ markdown_output = f"# 记忆检索结果\n\n"
152
+ markdown_output += f"**检索到 {len(all_memories)} 条记忆**\n\n"
153
+
154
+ if tags:
155
+ markdown_output += f"**使用标签过滤**: {', '.join(tags)}\n\n"
156
+
157
+ markdown_output += f"**记忆类型**: {', '.join(types_to_search)}\n\n"
158
+
159
+ markdown_output += "---\n\n"
160
+
161
+ # 输出所有记忆
162
+ for i, memory in enumerate(all_memories):
163
+ markdown_output += f"## {i+1}. {memory.get('id', '未知ID')}\n\n"
164
+ markdown_output += f"**类型**: {memory.get('type', '未知类型')}\n\n"
165
+ markdown_output += f"**标签**: {', '.join(memory.get('tags', []))}\n\n"
166
+ markdown_output += (
167
+ f"**创建时间**: {memory.get('created_at', '未知时间')}\n\n"
168
+ )
169
+
170
+ # 内容部分
171
+ content = memory.get("content", "")
172
+ if content:
173
+ markdown_output += f"**内容**:\n\n{content}\n\n"
174
+
175
+ # 如果有额外的元数据
176
+ metadata = {
177
+ k: v
178
+ for k, v in memory.items()
179
+ if k not in ["id", "type", "tags", "created_at", "content"]
180
+ }
181
+ if metadata:
182
+ markdown_output += f"**其他信息**:\n"
183
+ for key, value in metadata.items():
184
+ markdown_output += f"- {key}: {value}\n"
185
+ markdown_output += "\n"
186
+
187
+ markdown_output += "---\n\n"
188
+
189
+ # 如果记忆较多,在终端显示摘要
190
+ if len(all_memories) > 5:
191
+ PrettyOutput.print(f"记忆较多,仅显示前5条摘要:", OutputType.INFO)
192
+ for i, memory in enumerate(all_memories[:5]):
193
+ content_preview = memory.get("content", "")[:100]
194
+ if len(memory.get("content", "")) > 100:
195
+ content_preview += "..."
196
+ PrettyOutput.print(
197
+ f"{i+1}. [{memory.get('type')}] {memory.get('id')}\n"
198
+ f" 标签: {', '.join(memory.get('tags', []))}\n"
199
+ f" 内容: {content_preview}",
200
+ OutputType.INFO,
201
+ )
202
+
203
+ return {
204
+ "success": True,
205
+ "stdout": markdown_output,
206
+ "stderr": "",
207
+ }
208
+
209
+ except Exception as e:
210
+ error_msg = f"检索记忆失败: {str(e)}"
211
+ PrettyOutput.print(error_msg, OutputType.ERROR)
212
+ return {"success": False, "stdout": "", "stderr": error_msg}
@@ -0,0 +1,203 @@
1
+ # -*- coding: utf-8 -*-
2
+ import json
3
+ import time
4
+ from datetime import datetime
5
+ from pathlib import Path
6
+ from typing import Any, Dict, List
7
+
8
+ from jarvis.jarvis_utils.config import get_data_dir
9
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
10
+ from jarvis.jarvis_utils.globals import add_short_term_memory
11
+
12
+
13
+ class SaveMemoryTool:
14
+ """保存记忆工具,用于将信息保存到长短期记忆系统"""
15
+
16
+ name = "save_memory"
17
+ description = """保存信息到长短期记忆系统。
18
+
19
+ 支持批量保存多条记忆,可以同时保存不同类型的记忆。
20
+
21
+ 支持的记忆类型:
22
+ - project_long_term: 项目长期记忆(与当前项目相关的信息)
23
+ - global_long_term: 全局长期记忆(通用的信息、用户喜好、知识、方法等)
24
+ - short_term: 短期记忆(当前任务相关的信息)
25
+
26
+ 项目长期记忆存储在当前目录的 .jarvis/memory 下
27
+ 全局长期记忆和短期记忆存储在数据目录的 memory 子目录下
28
+ """
29
+
30
+ parameters = {
31
+ "type": "object",
32
+ "properties": {
33
+ "memories": {
34
+ "type": "array",
35
+ "items": {
36
+ "type": "object",
37
+ "properties": {
38
+ "memory_type": {
39
+ "type": "string",
40
+ "enum": [
41
+ "project_long_term",
42
+ "global_long_term",
43
+ "short_term",
44
+ ],
45
+ "description": "记忆类型",
46
+ },
47
+ "tags": {
48
+ "type": "array",
49
+ "items": {"type": "string"},
50
+ "description": "用于索引记忆的标签列表",
51
+ },
52
+ "content": {
53
+ "type": "string",
54
+ "description": "要保存的记忆内容",
55
+ },
56
+ },
57
+ "required": ["memory_type", "tags", "content"],
58
+ },
59
+ "description": "要保存的记忆列表",
60
+ }
61
+ },
62
+ "required": ["memories"],
63
+ }
64
+
65
+ def __init__(self):
66
+ """初始化保存记忆工具"""
67
+ self.project_memory_dir = Path(".jarvis/memory")
68
+ self.global_memory_dir = Path(get_data_dir()) / "memory"
69
+
70
+ def _get_memory_dir(self, memory_type: str) -> Path:
71
+ """根据记忆类型获取存储目录"""
72
+ if memory_type == "project_long_term":
73
+ return self.project_memory_dir
74
+ elif memory_type in ["global_long_term", "short_term"]:
75
+ return self.global_memory_dir / memory_type
76
+ else:
77
+ raise ValueError(f"未知的记忆类型: {memory_type}")
78
+
79
+ def _generate_memory_id(self) -> str:
80
+ """生成唯一的记忆ID"""
81
+ # 添加微秒级时间戳确保唯一性
82
+ time.sleep(0.001) # 确保不同记忆有不同的时间戳
83
+ return datetime.now().strftime("%Y%m%d_%H%M%S_%f")
84
+
85
+ def _save_single_memory(self, memory_data: Dict[str, Any]) -> Dict[str, Any]:
86
+ """保存单条记忆"""
87
+ memory_type = memory_data["memory_type"]
88
+ tags = memory_data.get("tags", [])
89
+ content = memory_data.get("content", "")
90
+
91
+ # 生成记忆ID
92
+ memory_id = self._generate_memory_id()
93
+
94
+ # 创建记忆对象
95
+ memory_obj = {
96
+ "id": memory_id,
97
+ "type": memory_type,
98
+ "tags": tags,
99
+ "content": content,
100
+ "created_at": datetime.now().isoformat(),
101
+ "updated_at": datetime.now().isoformat(),
102
+ }
103
+
104
+ if memory_type == "short_term":
105
+ # 短期记忆保存到全局变量
106
+ add_short_term_memory(memory_obj)
107
+
108
+ result = {
109
+ "memory_id": memory_id,
110
+ "memory_type": memory_type,
111
+ "tags": tags,
112
+ "storage": "memory",
113
+ "message": f"短期记忆已成功保存到内存,ID: {memory_id}",
114
+ }
115
+ else:
116
+ # 长期记忆保存到文件
117
+ # 获取存储目录并确保存在
118
+ memory_dir = self._get_memory_dir(memory_type)
119
+ memory_dir.mkdir(parents=True, exist_ok=True)
120
+
121
+ # 保存记忆文件
122
+ memory_file = memory_dir / f"{memory_id}.json"
123
+ with open(memory_file, "w", encoding="utf-8") as f:
124
+ json.dump(memory_obj, f, ensure_ascii=False, indent=2)
125
+
126
+ result = {
127
+ "memory_id": memory_id,
128
+ "memory_type": memory_type,
129
+ "tags": tags,
130
+ "file_path": str(memory_file),
131
+ "message": f"记忆已成功保存,ID: {memory_id}",
132
+ }
133
+
134
+ return result
135
+
136
+ def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
137
+ """执行保存记忆操作"""
138
+ try:
139
+ memories = args.get("memories", [])
140
+
141
+ if not memories:
142
+ return {
143
+ "success": False,
144
+ "stdout": "",
145
+ "stderr": "没有提供要保存的记忆",
146
+ }
147
+
148
+ results = []
149
+ success_count = 0
150
+ failed_count = 0
151
+
152
+ # 保存每条记忆
153
+ for i, memory_data in enumerate(memories):
154
+ try:
155
+ result = self._save_single_memory(memory_data)
156
+ results.append(result)
157
+ success_count += 1
158
+
159
+ # 打印单条记忆保存信息
160
+ memory_type = memory_data["memory_type"]
161
+ tags = memory_data.get("tags", [])
162
+ PrettyOutput.print(
163
+ f"[{i+1}/{len(memories)}] {memory_type} 记忆已保存\n"
164
+ f"ID: {result['memory_id']}\n"
165
+ f"标签: {', '.join(tags)}",
166
+ OutputType.SUCCESS,
167
+ )
168
+ except Exception as e:
169
+ failed_count += 1
170
+ error_msg = f"保存第 {i+1} 条记忆失败: {str(e)}"
171
+ PrettyOutput.print(error_msg, OutputType.ERROR)
172
+ results.append(
173
+ {
174
+ "error": error_msg,
175
+ "memory_type": memory_data.get("memory_type", "unknown"),
176
+ "tags": memory_data.get("tags", []),
177
+ }
178
+ )
179
+
180
+ # 生成总结报告
181
+ PrettyOutput.print(
182
+ f"\n批量保存完成:成功 {success_count} 条,失败 {failed_count} 条",
183
+ OutputType.INFO,
184
+ )
185
+
186
+ # 构建返回结果
187
+ output = {
188
+ "total": len(memories),
189
+ "success": success_count,
190
+ "failed": failed_count,
191
+ "results": results,
192
+ }
193
+
194
+ return {
195
+ "success": True,
196
+ "stdout": json.dumps(output, ensure_ascii=False, indent=2),
197
+ "stderr": "",
198
+ }
199
+
200
+ except Exception as e:
201
+ error_msg = f"保存记忆失败: {str(e)}"
202
+ PrettyOutput.print(error_msg, OutputType.ERROR)
203
+ return {"success": False, "stdout": "", "stderr": error_msg}
@@ -309,6 +309,16 @@ def get_methodology_dirs() -> List[str]:
309
309
  return GLOBAL_CONFIG_DATA.get("JARVIS_METHODOLOGY_DIRS", [])
310
310
 
311
311
 
312
+ def get_central_methodology_repo() -> str:
313
+ """
314
+ 获取中心方法论Git仓库地址。
315
+
316
+ 返回:
317
+ str: 中心方法论Git仓库地址,如果未配置则返回空字符串
318
+ """
319
+ return GLOBAL_CONFIG_DATA.get("JARVIS_CENTRAL_METHODOLOGY_REPO", "")
320
+
321
+
312
322
  def is_print_prompt() -> bool:
313
323
  """
314
324
  获取是否打印提示。