jarvis-ai-assistant 0.2.4__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 +80 -16
- jarvis/jarvis_agent/edit_file_handler.py +5 -6
- jarvis/jarvis_code_agent/code_agent.py +17 -24
- jarvis/jarvis_data/config_schema.json +2 -19
- jarvis/jarvis_multi_agent/main.py +1 -0
- jarvis/jarvis_stats/cli.py +72 -5
- jarvis/jarvis_stats/stats.py +175 -70
- jarvis/jarvis_stats/storage.py +53 -1
- jarvis/jarvis_stats/visualizer.py +63 -224
- jarvis/jarvis_tools/cli/main.py +7 -9
- jarvis/jarvis_tools/registry.py +2 -5
- jarvis/jarvis_tools/retrieve_memory.py +206 -0
- jarvis/jarvis_tools/save_memory.py +142 -0
- jarvis/jarvis_utils/config.py +6 -8
- jarvis/jarvis_utils/globals.py +120 -1
- jarvis/jarvis_utils/methodology.py +74 -67
- jarvis/jarvis_utils/utils.py +362 -121
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/METADATA +11 -2
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/RECORD +24 -22
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.6.dist-info}/top_level.txt +0 -0
@@ -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/config.py
CHANGED
@@ -81,10 +81,10 @@ def get_max_token_count(model_group_override: Optional[str] = None) -> int:
|
|
81
81
|
获取模型允许的最大token数量。
|
82
82
|
|
83
83
|
返回:
|
84
|
-
int: 模型能处理的最大token
|
84
|
+
int: 模型能处理的最大token数量,为最大输入token数量的100倍。
|
85
85
|
"""
|
86
|
-
|
87
|
-
return
|
86
|
+
max_input_tokens = get_max_input_token_count(model_group_override)
|
87
|
+
return max_input_tokens * 100
|
88
88
|
|
89
89
|
|
90
90
|
def get_max_input_token_count(model_group_override: Optional[str] = None) -> int:
|
@@ -151,9 +151,7 @@ def _get_resolved_model_config(
|
|
151
151
|
"JARVIS_MODEL",
|
152
152
|
"JARVIS_THINKING_PLATFORM",
|
153
153
|
"JARVIS_THINKING_MODEL",
|
154
|
-
"JARVIS_MAX_TOKEN_COUNT",
|
155
154
|
"JARVIS_MAX_INPUT_TOKEN_COUNT",
|
156
|
-
"JARVIS_MAX_BIG_CONTENT_SIZE",
|
157
155
|
]:
|
158
156
|
if key in GLOBAL_CONFIG_DATA:
|
159
157
|
resolved_config[key] = GLOBAL_CONFIG_DATA[key]
|
@@ -249,10 +247,10 @@ def get_max_big_content_size(model_group_override: Optional[str] = None) -> int:
|
|
249
247
|
获取最大大内容大小。
|
250
248
|
|
251
249
|
返回:
|
252
|
-
int:
|
250
|
+
int: 最大大内容大小,为最大输入token数量的5倍
|
253
251
|
"""
|
254
|
-
|
255
|
-
return
|
252
|
+
max_input_tokens = get_max_input_token_count(model_group_override)
|
253
|
+
return max_input_tokens * 5
|
256
254
|
|
257
255
|
|
258
256
|
def get_pretty_output() -> bool:
|
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
|
@@ -149,6 +149,7 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
149
149
|
|
150
150
|
参数:
|
151
151
|
user_input: 用户输入文本,用于提示大模型
|
152
|
+
tool_registery: 工具注册表,用于获取工具列表
|
152
153
|
|
153
154
|
返回:
|
154
155
|
str: 相关的方法论提示,如果未找到方法论则返回空字符串
|
@@ -170,70 +171,87 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
170
171
|
return ""
|
171
172
|
print(f"✅ 加载方法论文件完成 (共 {len(methodologies)} 个)")
|
172
173
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
else:
|
179
|
-
platform = PlatformRegistry().get_normal_platform()
|
180
|
-
model_group = None
|
181
|
-
platform.set_suppress_output(False)
|
182
|
-
if not platform:
|
183
|
-
return ""
|
174
|
+
platform = PlatformRegistry().get_normal_platform()
|
175
|
+
platform.set_suppress_output(True)
|
176
|
+
|
177
|
+
# 步骤1:获取所有方法论的标题
|
178
|
+
methodology_titles = list(methodologies.keys())
|
184
179
|
|
185
|
-
#
|
186
|
-
|
180
|
+
# 步骤2:让大模型选择相关性高的方法论
|
181
|
+
selection_prompt = f"""以下是所有可用的方法论标题:
|
187
182
|
|
188
183
|
"""
|
189
|
-
|
190
|
-
|
191
|
-
for problem_type, content in methodologies.items():
|
192
|
-
full_content += f"## {problem_type}\n\n{content}\n\n---\n\n"
|
184
|
+
for i, title in enumerate(methodology_titles, 1):
|
185
|
+
selection_prompt += f"{i}. {title}\n"
|
193
186
|
|
194
|
-
|
195
|
-
|
187
|
+
selection_prompt += f"""
|
188
|
+
以下是可用的工具列表:
|
189
|
+
{prompt}
|
196
190
|
|
197
|
-
|
198
|
-
full_content += f"""
|
199
|
-
请根据以上方法论和可调用的工具内容,规划/总结出以下用户需求的执行步骤: {user_input}
|
191
|
+
用户需求:{user_input}
|
200
192
|
|
201
|
-
|
202
|
-
### 与该任务/需求相关的方法论
|
203
|
-
1. [方法论名字]
|
204
|
-
2. [方法论名字]
|
205
|
-
### 根据以上方法论,规划/总结出执行步骤
|
206
|
-
1. [步骤1]
|
207
|
-
2. [步骤2]
|
208
|
-
3. [步骤3]
|
193
|
+
请分析用户需求,从上述方法论中选择出与需求相关性较高的方法论(可以选择多个)。
|
209
194
|
|
210
|
-
|
211
|
-
|
195
|
+
请严格按照以下格式返回序号:
|
196
|
+
<NUM>序号1,序号2,序号3</NUM>
|
197
|
+
|
198
|
+
例如:<NUM>1,3,5</NUM>
|
199
|
+
|
200
|
+
如果没有相关的方法论,请返回:<NUM>none</NUM>
|
201
|
+
|
202
|
+
注意:只返回<NUM>标签内的内容,不要有其他任何输出。
|
212
203
|
"""
|
213
204
|
|
214
|
-
#
|
215
|
-
|
216
|
-
|
205
|
+
# 获取大模型选择的方法论序号
|
206
|
+
response = platform.chat_until_success(selection_prompt).strip()
|
207
|
+
|
208
|
+
# 重置平台,恢复输出
|
209
|
+
platform.reset()
|
210
|
+
platform.set_suppress_output(False)
|
211
|
+
|
212
|
+
# 从响应中提取<NUM>标签内的内容
|
213
|
+
import re
|
214
|
+
num_match = re.search(r'<NUM>(.*?)</NUM>', response, re.DOTALL)
|
215
|
+
|
216
|
+
if not num_match:
|
217
|
+
# 如果没有找到<NUM>标签,尝试直接解析响应
|
218
|
+
selected_indices_str = response
|
219
|
+
else:
|
220
|
+
selected_indices_str = num_match.group(1).strip()
|
221
|
+
|
222
|
+
if selected_indices_str.lower() == "none":
|
223
|
+
return "没有历史方法论可参考"
|
217
224
|
|
225
|
+
# 解析选择的序号
|
226
|
+
selected_methodologies = {}
|
218
227
|
try:
|
219
|
-
if
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
228
|
+
if selected_indices_str:
|
229
|
+
indices = [int(idx.strip()) for idx in selected_indices_str.split(",") if idx.strip().isdigit()]
|
230
|
+
for idx in indices:
|
231
|
+
if 1 <= idx <= len(methodology_titles):
|
232
|
+
title = methodology_titles[idx - 1]
|
233
|
+
selected_methodologies[title] = methodologies[title]
|
234
|
+
except Exception:
|
235
|
+
# 如果解析失败,返回空结果
|
236
|
+
return "没有历史方法论可参考"
|
237
|
+
|
238
|
+
if not selected_methodologies:
|
239
|
+
return "没有历史方法论可参考"
|
240
|
+
|
241
|
+
# 步骤3:将选择出来的方法论内容提供给大模型生成步骤
|
242
|
+
final_prompt = f"""以下是与用户需求相关的方法论内容:
|
243
|
+
|
244
|
+
"""
|
245
|
+
for problem_type, content in selected_methodologies.items():
|
246
|
+
final_prompt += f"## {problem_type}\n\n{content}\n\n---\n\n"
|
247
|
+
|
248
|
+
final_prompt += f"""以下是所有可用的工具内容:
|
249
|
+
|
250
|
+
{prompt}
|
251
|
+
|
252
|
+
用户需求:{user_input}
|
253
|
+
|
254
|
+
请根据以上方法论和可调用的工具内容,规划/总结出执行步骤。
|
237
255
|
|
238
256
|
请按以下格式回复:
|
239
257
|
### 与该任务/需求相关的方法论
|
@@ -244,22 +262,11 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
244
262
|
2. [步骤2]
|
245
263
|
3. [步骤3]
|
246
264
|
|
247
|
-
如果没有匹配的方法论,请输出:没有历史方法论可参考
|
248
265
|
除以上要求外,不要输出任何内容
|
249
266
|
"""
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
# 如果内容不大或上传失败,直接使用chat_until_success
|
254
|
-
return platform.chat_until_success(full_content)
|
255
|
-
|
256
|
-
finally:
|
257
|
-
# 清理临时文件
|
258
|
-
if temp_file_path and os.path.exists(temp_file_path):
|
259
|
-
try:
|
260
|
-
os.remove(temp_file_path)
|
261
|
-
except Exception:
|
262
|
-
pass
|
267
|
+
|
268
|
+
# 如果内容不大,直接使用chat_until_success
|
269
|
+
return platform.chat_until_success(final_prompt)
|
263
270
|
|
264
271
|
except Exception as e:
|
265
272
|
PrettyOutput.print(f"加载方法论失败: {str(e)}", OutputType.ERROR)
|