jarvis-ai-assistant 0.1.192__py3-none-any.whl → 0.1.194__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 +69 -37
- jarvis/jarvis_agent/builtin_input_handler.py +26 -4
- jarvis/jarvis_agent/jarvis.py +38 -22
- jarvis/jarvis_agent/main.py +20 -12
- jarvis/jarvis_agent/output_handler.py +7 -7
- jarvis/jarvis_agent/shell_input_handler.py +14 -11
- jarvis/jarvis_code_agent/code_agent.py +93 -90
- jarvis/jarvis_code_agent/lint.py +92 -105
- jarvis/jarvis_code_analysis/checklists/__init__.py +1 -1
- jarvis/jarvis_code_analysis/checklists/c_cpp.py +1 -1
- jarvis/jarvis_code_analysis/checklists/csharp.py +1 -1
- jarvis/jarvis_code_analysis/checklists/data_format.py +1 -1
- jarvis/jarvis_code_analysis/checklists/devops.py +1 -1
- jarvis/jarvis_code_analysis/checklists/docs.py +1 -1
- jarvis/jarvis_code_analysis/checklists/go.py +1 -1
- jarvis/jarvis_code_analysis/checklists/infrastructure.py +1 -1
- jarvis/jarvis_code_analysis/checklists/java.py +1 -1
- jarvis/jarvis_code_analysis/checklists/javascript.py +1 -1
- jarvis/jarvis_code_analysis/checklists/kotlin.py +1 -1
- jarvis/jarvis_code_analysis/checklists/loader.py +51 -35
- jarvis/jarvis_code_analysis/checklists/php.py +1 -1
- jarvis/jarvis_code_analysis/checklists/python.py +1 -1
- jarvis/jarvis_code_analysis/checklists/ruby.py +1 -1
- jarvis/jarvis_code_analysis/checklists/rust.py +1 -1
- jarvis/jarvis_code_analysis/checklists/shell.py +1 -1
- jarvis/jarvis_code_analysis/checklists/sql.py +1 -1
- jarvis/jarvis_code_analysis/checklists/swift.py +1 -1
- jarvis/jarvis_code_analysis/checklists/web.py +1 -1
- jarvis/jarvis_code_analysis/code_review.py +293 -192
- jarvis/jarvis_dev/main.py +73 -56
- jarvis/jarvis_git_details/main.py +29 -33
- jarvis/jarvis_git_squash/main.py +13 -11
- jarvis/jarvis_git_utils/git_commiter.py +12 -3
- jarvis/jarvis_mcp/__init__.py +8 -10
- jarvis/jarvis_mcp/sse_mcp_client.py +182 -205
- jarvis/jarvis_mcp/stdio_mcp_client.py +93 -120
- jarvis/jarvis_mcp/streamable_mcp_client.py +117 -142
- jarvis/jarvis_methodology/main.py +81 -47
- jarvis/jarvis_multi_agent/__init__.py +24 -16
- jarvis/jarvis_multi_agent/main.py +10 -4
- jarvis/jarvis_platform/__init__.py +1 -1
- jarvis/jarvis_platform/base.py +49 -21
- jarvis/jarvis_platform/human.py +5 -3
- jarvis/jarvis_platform/kimi.py +96 -72
- jarvis/jarvis_platform/openai.py +23 -28
- jarvis/jarvis_platform/registry.py +50 -33
- jarvis/jarvis_platform/tongyi.py +16 -10
- jarvis/jarvis_platform/yuanbao.py +205 -147
- jarvis/jarvis_platform_manager/main.py +4 -2
- jarvis/jarvis_smart_shell/main.py +35 -29
- jarvis/jarvis_tools/ask_user.py +8 -16
- jarvis/jarvis_tools/base.py +3 -2
- jarvis/jarvis_tools/chdir.py +7 -19
- jarvis/jarvis_tools/cli/main.py +14 -10
- jarvis/jarvis_tools/code_plan.py +10 -31
- jarvis/jarvis_tools/create_code_agent.py +10 -13
- jarvis/jarvis_tools/create_sub_agent.py +10 -22
- jarvis/jarvis_tools/edit_file.py +98 -76
- jarvis/jarvis_tools/execute_script.py +46 -46
- jarvis/jarvis_tools/file_analyzer.py +22 -34
- jarvis/jarvis_tools/file_operation.py +69 -62
- jarvis/jarvis_tools/generate_new_tool.py +0 -2
- jarvis/jarvis_tools/methodology.py +19 -23
- jarvis/jarvis_tools/read_code.py +42 -33
- jarvis/jarvis_tools/read_webpage.py +7 -16
- jarvis/jarvis_tools/registry.py +65 -32
- jarvis/jarvis_tools/rewrite_file.py +26 -29
- jarvis/jarvis_tools/search_web.py +5 -8
- jarvis/jarvis_tools/virtual_tty.py +133 -122
- jarvis/jarvis_utils/__init__.py +0 -1
- jarvis/jarvis_utils/builtin_replace_map.py +96 -8
- jarvis/jarvis_utils/config.py +59 -32
- jarvis/jarvis_utils/embedding.py +17 -14
- jarvis/jarvis_utils/file_processors.py +16 -9
- jarvis/jarvis_utils/git_utils.py +140 -99
- jarvis/jarvis_utils/globals.py +1 -1
- jarvis/jarvis_utils/input.py +84 -52
- jarvis/jarvis_utils/methodology.py +28 -21
- jarvis/jarvis_utils/output.py +159 -78
- jarvis/jarvis_utils/tag.py +2 -1
- jarvis/jarvis_utils/utils.py +85 -51
- {jarvis_ai_assistant-0.1.192.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/METADATA +337 -204
- jarvis_ai_assistant-0.1.194.dist-info/RECORD +97 -0
- jarvis/jarvis_agent/file_input_handler.py +0 -112
- jarvis/jarvis_event/__init__.py +0 -0
- jarvis_ai_assistant-0.1.192.dist-info/RECORD +0 -99
- {jarvis_ai_assistant-0.1.192.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.192.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.192.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.192.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/top_level.txt +0 -0
jarvis/jarvis_utils/input.py
CHANGED
@@ -12,7 +12,7 @@ from colorama import Fore
|
|
12
12
|
from colorama import Style as ColoramaStyle
|
13
13
|
from fuzzywuzzy import process
|
14
14
|
from prompt_toolkit import PromptSession
|
15
|
-
from prompt_toolkit.completion import Completer, Completion, PathCompleter
|
15
|
+
from prompt_toolkit.completion import Completer, Completion, PathCompleter, CompleteEvent
|
16
16
|
from prompt_toolkit.document import Document
|
17
17
|
from prompt_toolkit.formatted_text import FormattedText
|
18
18
|
from prompt_toolkit.key_binding import KeyBindings
|
@@ -34,10 +34,14 @@ def get_single_line_input(tip: str) -> str:
|
|
34
34
|
str: 用户的输入
|
35
35
|
"""
|
36
36
|
session = PromptSession(history=None)
|
37
|
-
style = PromptStyle.from_dict(
|
38
|
-
|
39
|
-
|
37
|
+
style = PromptStyle.from_dict(
|
38
|
+
{
|
39
|
+
"prompt": "ansicyan",
|
40
|
+
}
|
41
|
+
)
|
40
42
|
return session.prompt(f"{tip}", style=style)
|
43
|
+
|
44
|
+
|
41
45
|
class FileCompleter(Completer):
|
42
46
|
"""
|
43
47
|
带有模糊匹配的文件路径自定义补全器。
|
@@ -47,13 +51,15 @@ class FileCompleter(Completer):
|
|
47
51
|
max_suggestions: 显示的最大建议数量
|
48
52
|
min_score: 建议的最小匹配分数
|
49
53
|
"""
|
54
|
+
|
50
55
|
def __init__(self):
|
51
56
|
"""使用默认设置初始化文件补全器。"""
|
52
57
|
self.path_completer = PathCompleter()
|
53
58
|
self.max_suggestions = 10
|
54
59
|
self.min_score = 10
|
55
60
|
self.replace_map = get_replace_map()
|
56
|
-
|
61
|
+
|
62
|
+
def get_completions(self, document: Document, _: CompleteEvent) -> Completion: # type: ignore
|
57
63
|
"""
|
58
64
|
生成带有模糊匹配的文件路径补全建议。
|
59
65
|
|
@@ -67,7 +73,7 @@ class FileCompleter(Completer):
|
|
67
73
|
text = document.text_before_cursor
|
68
74
|
cursor_pos = document.cursor_position
|
69
75
|
# 查找文本中的所有@位置
|
70
|
-
at_positions = [i for i, char in enumerate(text) if char ==
|
76
|
+
at_positions = [i for i, char in enumerate(text) if char == "@"]
|
71
77
|
if not at_positions:
|
72
78
|
return
|
73
79
|
# 获取最后一个@位置
|
@@ -76,12 +82,10 @@ class FileCompleter(Completer):
|
|
76
82
|
if cursor_pos <= current_at_pos:
|
77
83
|
return
|
78
84
|
# 检查@之后是否有空格
|
79
|
-
text_after_at = text[current_at_pos + 1:cursor_pos]
|
80
|
-
if
|
85
|
+
text_after_at = text[current_at_pos + 1 : cursor_pos]
|
86
|
+
if " " in text_after_at:
|
81
87
|
return
|
82
|
-
|
83
88
|
|
84
|
-
|
85
89
|
# 获取当前@之后的文本
|
86
90
|
file_path = text_after_at.strip()
|
87
91
|
# 计算替换长度
|
@@ -89,38 +93,52 @@ class FileCompleter(Completer):
|
|
89
93
|
|
90
94
|
# 获取所有可能的补全项
|
91
95
|
all_completions = []
|
92
|
-
|
96
|
+
|
93
97
|
# 1. 添加特殊标记
|
94
|
-
all_completions.extend(
|
95
|
-
(ot(tag), self._get_description(tag))
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
all_completions.extend(
|
99
|
+
[(ot(tag), self._get_description(tag)) for tag in self.replace_map.keys()]
|
100
|
+
)
|
101
|
+
all_completions.extend(
|
102
|
+
[
|
103
|
+
(ot("Summary"), "总结"),
|
104
|
+
(ot("Clear"), "清除历史"),
|
105
|
+
(ot("ToolUsage"), "工具使用说明"),
|
106
|
+
(ot("ReloadConfig"), "重新加载配置"),
|
107
|
+
]
|
108
|
+
)
|
109
|
+
|
103
110
|
# 2. 添加文件列表
|
104
111
|
try:
|
105
112
|
import subprocess
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
113
|
+
|
114
|
+
result = subprocess.run(
|
115
|
+
["git", "ls-files"],
|
116
|
+
stdout=subprocess.PIPE,
|
117
|
+
stderr=subprocess.PIPE,
|
118
|
+
text=True,
|
119
|
+
)
|
110
120
|
if result.returncode == 0:
|
111
|
-
all_completions.extend(
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
121
|
+
all_completions.extend(
|
122
|
+
[
|
123
|
+
(path, "File")
|
124
|
+
for path in result.stdout.splitlines()
|
125
|
+
if path.strip()
|
126
|
+
]
|
127
|
+
)
|
116
128
|
except Exception:
|
117
129
|
pass
|
118
|
-
|
130
|
+
|
119
131
|
# 统一过滤和排序
|
120
132
|
if file_path:
|
121
133
|
# 使用模糊匹配过滤
|
122
|
-
scored_items = process.extract(
|
123
|
-
|
134
|
+
scored_items = process.extract(
|
135
|
+
file_path,
|
136
|
+
[item[0] for item in all_completions],
|
137
|
+
limit=self.max_suggestions,
|
138
|
+
)
|
139
|
+
scored_items = [
|
140
|
+
(item[0], item[1]) for item in scored_items if item[1] > self.min_score
|
141
|
+
]
|
124
142
|
# 创建映射以便查找描述
|
125
143
|
completion_map = {item[0]: item[1] for item in all_completions}
|
126
144
|
# 生成补全项
|
@@ -132,23 +150,29 @@ class FileCompleter(Completer):
|
|
132
150
|
text=f"'{text}'",
|
133
151
|
start_position=-replace_length,
|
134
152
|
display=display_text,
|
135
|
-
display_meta=completion_map.get(text, "")
|
136
|
-
)
|
153
|
+
display_meta=completion_map.get(text, ""),
|
154
|
+
) # type: ignore
|
137
155
|
else:
|
138
156
|
# 没有输入时返回前max_suggestions个建议
|
139
|
-
for text, desc in all_completions[:self.max_suggestions]:
|
157
|
+
for text, desc in all_completions[: self.max_suggestions]:
|
140
158
|
yield Completion(
|
141
159
|
text=f"'{text}'",
|
142
160
|
start_position=-replace_length,
|
143
161
|
display=text,
|
144
|
-
display_meta=desc
|
145
|
-
)
|
146
|
-
|
162
|
+
display_meta=desc,
|
163
|
+
) # type: ignore
|
164
|
+
|
147
165
|
def _get_description(self, tag: str) -> str:
|
148
166
|
"""获取标记的描述信息"""
|
149
167
|
if tag in self.replace_map:
|
150
|
-
return
|
168
|
+
return (
|
169
|
+
self.replace_map[tag].get("description", tag) + "(Append)"
|
170
|
+
if "append" in self.replace_map[tag] and self.replace_map[tag]["append"]
|
171
|
+
else "(Replace)"
|
172
|
+
)
|
151
173
|
return tag
|
174
|
+
|
175
|
+
|
152
176
|
def get_multiline_input(tip: str) -> str:
|
153
177
|
"""
|
154
178
|
获取带有增强补全和确认功能的多行输入。
|
@@ -160,25 +184,35 @@ def get_multiline_input(tip: str) -> str:
|
|
160
184
|
str: 用户的输入,如果取消则返回空字符串
|
161
185
|
"""
|
162
186
|
# 显示输入说明
|
163
|
-
PrettyOutput.section(
|
187
|
+
PrettyOutput.section(
|
188
|
+
"用户输入 - 使用 @ 触发文件补全,Tab 选择补全项,Ctrl+J 提交,按 Ctrl+C 取消输入",
|
189
|
+
OutputType.USER,
|
190
|
+
)
|
164
191
|
print(f"{Fore.GREEN}{tip}{ColoramaStyle.RESET_ALL}")
|
165
192
|
# 配置键绑定
|
166
193
|
bindings = KeyBindings()
|
167
|
-
|
194
|
+
|
195
|
+
@bindings.add("enter")
|
168
196
|
def _(event):
|
169
197
|
"""处理回车键以进行补全或换行。"""
|
170
198
|
if event.current_buffer.complete_state:
|
171
|
-
event.current_buffer.apply_completion(
|
199
|
+
event.current_buffer.apply_completion(
|
200
|
+
event.current_buffer.complete_state.current_completion
|
201
|
+
)
|
172
202
|
else:
|
173
|
-
event.current_buffer.insert_text(
|
174
|
-
|
203
|
+
event.current_buffer.insert_text("\n")
|
204
|
+
|
205
|
+
@bindings.add("c-j")
|
175
206
|
def _(event):
|
176
207
|
"""处理Ctrl+J以提交输入。"""
|
177
208
|
event.current_buffer.validate_and_handle()
|
209
|
+
|
178
210
|
# 配置提示会话
|
179
|
-
style = PromptStyle.from_dict(
|
180
|
-
|
181
|
-
|
211
|
+
style = PromptStyle.from_dict(
|
212
|
+
{
|
213
|
+
"prompt": "ansicyan",
|
214
|
+
}
|
215
|
+
)
|
182
216
|
try:
|
183
217
|
import os
|
184
218
|
|
@@ -190,17 +224,15 @@ def get_multiline_input(tip: str) -> str:
|
|
190
224
|
history_dir = get_data_dir()
|
191
225
|
# 初始化带历史记录的会话
|
192
226
|
session = PromptSession(
|
193
|
-
history=FileHistory(os.path.join(history_dir,
|
227
|
+
history=FileHistory(os.path.join(history_dir, "multiline_input_history")),
|
194
228
|
completer=FileCompleter(),
|
195
229
|
key_bindings=bindings,
|
196
230
|
complete_while_typing=True,
|
197
231
|
multiline=True,
|
198
232
|
vi_mode=False,
|
199
|
-
mouse_support=False
|
233
|
+
mouse_support=False,
|
200
234
|
)
|
201
|
-
prompt = FormattedText([
|
202
|
-
('class:prompt', '>>> ')
|
203
|
-
])
|
235
|
+
prompt = FormattedText([("class:prompt", ">>> ")])
|
204
236
|
# 获取输入
|
205
237
|
text = session.prompt(
|
206
238
|
prompt,
|
@@ -34,6 +34,7 @@ def _get_methodology_directory() -> str:
|
|
34
34
|
PrettyOutput.print(f"创建方法论目录失败: {str(e)}", OutputType.ERROR)
|
35
35
|
return methodology_dir
|
36
36
|
|
37
|
+
|
37
38
|
def _load_all_methodologies() -> Dict[str, str]:
|
38
39
|
"""
|
39
40
|
加载所有方法论文件
|
@@ -48,6 +49,7 @@ def _load_all_methodologies() -> Dict[str, str]:
|
|
48
49
|
return all_methodologies
|
49
50
|
|
50
51
|
import glob
|
52
|
+
|
51
53
|
for filepath in glob.glob(os.path.join(methodology_dir, "*.json")):
|
52
54
|
try:
|
53
55
|
with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
|
@@ -58,10 +60,13 @@ def _load_all_methodologies() -> Dict[str, str]:
|
|
58
60
|
all_methodologies[problem_type] = content
|
59
61
|
except Exception as e:
|
60
62
|
filename = os.path.basename(filepath)
|
61
|
-
PrettyOutput.print(
|
63
|
+
PrettyOutput.print(
|
64
|
+
f"加载方法论文件 {filename} 失败: {str(e)}", OutputType.WARNING
|
65
|
+
)
|
62
66
|
|
63
67
|
return all_methodologies
|
64
68
|
|
69
|
+
|
65
70
|
def _create_methodology_temp_file(methodologies: Dict[str, str]) -> Optional[str]:
|
66
71
|
"""
|
67
72
|
创建包含所有方法论的临时文件
|
@@ -74,33 +79,34 @@ def _create_methodology_temp_file(methodologies: Dict[str, str]) -> Optional[str
|
|
74
79
|
"""
|
75
80
|
if not methodologies:
|
76
81
|
return None
|
77
|
-
|
82
|
+
|
78
83
|
try:
|
79
84
|
# 创建临时文件
|
80
|
-
fd, temp_path = tempfile.mkstemp(suffix=
|
85
|
+
fd, temp_path = tempfile.mkstemp(suffix=".md", prefix="methodologies_")
|
81
86
|
os.close(fd)
|
82
|
-
|
87
|
+
|
83
88
|
# 写入方法论内容
|
84
|
-
with open(temp_path,
|
89
|
+
with open(temp_path, "w", encoding="utf-8") as f:
|
85
90
|
f.write("# 方法论集合\n\n")
|
86
91
|
for problem_type, content in methodologies.items():
|
87
92
|
f.write(f"## {problem_type}\n\n")
|
88
93
|
f.write(f"{content}\n\n")
|
89
94
|
f.write("---\n\n")
|
90
95
|
f.flush()
|
91
|
-
|
96
|
+
|
92
97
|
return temp_path
|
93
98
|
except Exception as e:
|
94
99
|
PrettyOutput.print(f"创建方法论临时文件失败: {str(e)}", OutputType.ERROR)
|
95
100
|
return None
|
96
101
|
|
102
|
+
|
97
103
|
def upload_methodology(platform: BasePlatform) -> bool:
|
98
104
|
"""
|
99
105
|
上传方法论文件到指定平台
|
100
|
-
|
106
|
+
|
101
107
|
参数:
|
102
108
|
platform: 平台实例,需实现upload_files方法
|
103
|
-
|
109
|
+
|
104
110
|
返回:
|
105
111
|
bool: 上传是否成功
|
106
112
|
"""
|
@@ -108,19 +114,19 @@ def upload_methodology(platform: BasePlatform) -> bool:
|
|
108
114
|
if not os.path.exists(methodology_dir):
|
109
115
|
PrettyOutput.print("方法论文档不存在", OutputType.WARNING)
|
110
116
|
return False
|
111
|
-
|
117
|
+
|
112
118
|
methodologies = _load_all_methodologies()
|
113
119
|
if not methodologies:
|
114
120
|
PrettyOutput.print("没有可用的方法论文档", OutputType.WARNING)
|
115
121
|
return False
|
116
|
-
|
122
|
+
|
117
123
|
temp_file_path = _create_methodology_temp_file(methodologies)
|
118
124
|
if not temp_file_path:
|
119
125
|
return False
|
120
|
-
|
126
|
+
|
121
127
|
try:
|
122
128
|
return platform.upload_files([temp_file_path])
|
123
|
-
|
129
|
+
|
124
130
|
finally:
|
125
131
|
if temp_file_path and os.path.exists(temp_file_path):
|
126
132
|
try:
|
@@ -141,8 +147,6 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
141
147
|
"""
|
142
148
|
from yaspin import yaspin # type: ignore
|
143
149
|
|
144
|
-
from jarvis.jarvis_tools.registry import ToolRegistry
|
145
|
-
|
146
150
|
prompt = tool_registery.prompt() if tool_registery else ""
|
147
151
|
|
148
152
|
# 获取方法论目录
|
@@ -178,7 +182,7 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
178
182
|
|
179
183
|
full_content += f"以下是所有可用的工具内容:\n\n"
|
180
184
|
full_content += prompt
|
181
|
-
|
185
|
+
|
182
186
|
# 添加用户输入和输出要求
|
183
187
|
full_content += f"""
|
184
188
|
请根据以上方法论和可调用的工具内容,规划/总结出以下用户需求的执行步骤: {user_input}
|
@@ -199,7 +203,7 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
199
203
|
# 检查内容是否过大
|
200
204
|
is_large_content = is_context_overflow(full_content)
|
201
205
|
temp_file_path = None
|
202
|
-
|
206
|
+
|
203
207
|
try:
|
204
208
|
if is_large_content:
|
205
209
|
# 创建临时文件
|
@@ -214,10 +218,12 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
214
218
|
|
215
219
|
# 尝试上传文件
|
216
220
|
upload_success = platform.upload_files([temp_file_path])
|
217
|
-
|
221
|
+
|
218
222
|
if upload_success:
|
219
223
|
# 使用上传的文件生成摘要
|
220
|
-
return platform.chat_until_success(
|
224
|
+
return platform.chat_until_success(
|
225
|
+
base_prompt
|
226
|
+
+ f"""
|
221
227
|
请根据已上传的方法论和可调用的工具文件内容,规划/总结出以下用户需求的执行步骤: {user_input}
|
222
228
|
|
223
229
|
请按以下格式回复:
|
@@ -231,12 +237,13 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
231
237
|
|
232
238
|
如果没有匹配的方法论,请输出:没有历史方法论可参考
|
233
239
|
除以上要求外,不要输出任何内容
|
234
|
-
"""
|
240
|
+
"""
|
241
|
+
)
|
235
242
|
else:
|
236
243
|
return "没有历史方法论可参考"
|
237
244
|
# 如果内容不大或上传失败,直接使用chat_until_success
|
238
245
|
return platform.chat_until_success(full_content)
|
239
|
-
|
246
|
+
|
240
247
|
finally:
|
241
248
|
# 清理临时文件
|
242
249
|
if temp_file_path and os.path.exists(temp_file_path):
|
@@ -244,7 +251,7 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
244
251
|
os.remove(temp_file_path)
|
245
252
|
except Exception:
|
246
253
|
pass
|
247
|
-
|
254
|
+
|
248
255
|
except Exception as e:
|
249
256
|
PrettyOutput.print(f"加载方法论失败: {str(e)}", OutputType.ERROR)
|
250
257
|
return ""
|