jarvis-ai-assistant 0.7.0__py3-none-any.whl → 0.7.8__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 +243 -139
- jarvis/jarvis_agent/agent_manager.py +5 -10
- jarvis/jarvis_agent/builtin_input_handler.py +2 -6
- jarvis/jarvis_agent/config_editor.py +2 -7
- jarvis/jarvis_agent/event_bus.py +82 -12
- jarvis/jarvis_agent/file_context_handler.py +265 -15
- jarvis/jarvis_agent/file_methodology_manager.py +3 -4
- jarvis/jarvis_agent/jarvis.py +113 -98
- jarvis/jarvis_agent/language_extractors/__init__.py +57 -0
- jarvis/jarvis_agent/language_extractors/c_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/cpp_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/go_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/java_extractor.py +84 -0
- jarvis/jarvis_agent/language_extractors/javascript_extractor.py +79 -0
- jarvis/jarvis_agent/language_extractors/python_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/rust_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/typescript_extractor.py +84 -0
- jarvis/jarvis_agent/language_support_info.py +486 -0
- jarvis/jarvis_agent/main.py +6 -12
- jarvis/jarvis_agent/memory_manager.py +7 -16
- jarvis/jarvis_agent/methodology_share_manager.py +10 -16
- jarvis/jarvis_agent/prompt_manager.py +1 -1
- jarvis/jarvis_agent/prompts.py +193 -171
- jarvis/jarvis_agent/protocols.py +8 -12
- jarvis/jarvis_agent/run_loop.py +77 -14
- jarvis/jarvis_agent/session_manager.py +2 -3
- jarvis/jarvis_agent/share_manager.py +12 -21
- jarvis/jarvis_agent/shell_input_handler.py +1 -2
- jarvis/jarvis_agent/task_analyzer.py +26 -4
- jarvis/jarvis_agent/task_manager.py +11 -27
- jarvis/jarvis_agent/tool_executor.py +2 -3
- jarvis/jarvis_agent/tool_share_manager.py +12 -24
- jarvis/jarvis_agent/web_server.py +55 -20
- jarvis/jarvis_c2rust/__init__.py +5 -5
- jarvis/jarvis_c2rust/cli.py +461 -499
- jarvis/jarvis_c2rust/collector.py +45 -53
- jarvis/jarvis_c2rust/constants.py +26 -0
- jarvis/jarvis_c2rust/library_replacer.py +264 -132
- jarvis/jarvis_c2rust/llm_module_agent.py +162 -190
- jarvis/jarvis_c2rust/loaders.py +207 -0
- jarvis/jarvis_c2rust/models.py +28 -0
- jarvis/jarvis_c2rust/optimizer.py +1592 -395
- jarvis/jarvis_c2rust/transpiler.py +1722 -1064
- jarvis/jarvis_c2rust/utils.py +385 -0
- jarvis/jarvis_code_agent/build_validation_config.py +2 -3
- jarvis/jarvis_code_agent/code_agent.py +394 -320
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +3 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +4 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +17 -2
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +3 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +36 -4
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +9 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +9 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +12 -1
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +22 -5
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +57 -32
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +62 -6
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +8 -9
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +290 -5
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +21 -3
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +72 -4
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +35 -3
- jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +212 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +254 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +52 -2
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +73 -1
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +280 -0
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +306 -152
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +556 -0
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +193 -18
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +18 -8
- jarvis/jarvis_code_agent/lint.py +258 -27
- jarvis/jarvis_code_agent/utils.py +0 -1
- jarvis/jarvis_code_analysis/code_review.py +19 -24
- jarvis/jarvis_data/config_schema.json +53 -26
- jarvis/jarvis_git_squash/main.py +4 -5
- jarvis/jarvis_git_utils/git_commiter.py +44 -49
- jarvis/jarvis_mcp/sse_mcp_client.py +20 -27
- jarvis/jarvis_mcp/stdio_mcp_client.py +11 -12
- jarvis/jarvis_mcp/streamable_mcp_client.py +15 -14
- jarvis/jarvis_memory_organizer/memory_organizer.py +55 -74
- jarvis/jarvis_methodology/main.py +32 -48
- jarvis/jarvis_multi_agent/__init__.py +79 -61
- jarvis/jarvis_multi_agent/main.py +3 -7
- jarvis/jarvis_platform/base.py +469 -199
- jarvis/jarvis_platform/human.py +7 -8
- jarvis/jarvis_platform/kimi.py +30 -36
- jarvis/jarvis_platform/openai.py +65 -27
- jarvis/jarvis_platform/registry.py +26 -10
- jarvis/jarvis_platform/tongyi.py +24 -25
- jarvis/jarvis_platform/yuanbao.py +31 -42
- jarvis/jarvis_platform_manager/main.py +66 -77
- jarvis/jarvis_platform_manager/service.py +8 -13
- jarvis/jarvis_rag/cli.py +49 -51
- jarvis/jarvis_rag/embedding_manager.py +13 -18
- jarvis/jarvis_rag/llm_interface.py +8 -9
- jarvis/jarvis_rag/query_rewriter.py +10 -21
- jarvis/jarvis_rag/rag_pipeline.py +24 -27
- jarvis/jarvis_rag/reranker.py +4 -5
- jarvis/jarvis_rag/retriever.py +28 -30
- jarvis/jarvis_sec/__init__.py +220 -3520
- jarvis/jarvis_sec/agents.py +143 -0
- jarvis/jarvis_sec/analysis.py +276 -0
- jarvis/jarvis_sec/cli.py +29 -6
- jarvis/jarvis_sec/clustering.py +1439 -0
- jarvis/jarvis_sec/file_manager.py +427 -0
- jarvis/jarvis_sec/parsers.py +73 -0
- jarvis/jarvis_sec/prompts.py +268 -0
- jarvis/jarvis_sec/report.py +83 -4
- jarvis/jarvis_sec/review.py +453 -0
- jarvis/jarvis_sec/utils.py +499 -0
- jarvis/jarvis_sec/verification.py +848 -0
- jarvis/jarvis_sec/workflow.py +7 -0
- jarvis/jarvis_smart_shell/main.py +38 -87
- jarvis/jarvis_stats/cli.py +1 -1
- jarvis/jarvis_stats/stats.py +7 -7
- jarvis/jarvis_stats/storage.py +15 -21
- jarvis/jarvis_tools/clear_memory.py +3 -20
- jarvis/jarvis_tools/cli/main.py +20 -23
- jarvis/jarvis_tools/edit_file.py +1066 -0
- jarvis/jarvis_tools/execute_script.py +42 -21
- jarvis/jarvis_tools/file_analyzer.py +6 -9
- jarvis/jarvis_tools/generate_new_tool.py +11 -20
- jarvis/jarvis_tools/lsp_client.py +1552 -0
- jarvis/jarvis_tools/methodology.py +2 -3
- jarvis/jarvis_tools/read_code.py +1525 -87
- jarvis/jarvis_tools/read_symbols.py +2 -3
- jarvis/jarvis_tools/read_webpage.py +7 -10
- jarvis/jarvis_tools/registry.py +370 -181
- jarvis/jarvis_tools/retrieve_memory.py +20 -19
- jarvis/jarvis_tools/rewrite_file.py +105 -0
- jarvis/jarvis_tools/save_memory.py +3 -15
- jarvis/jarvis_tools/search_web.py +3 -7
- jarvis/jarvis_tools/sub_agent.py +17 -6
- jarvis/jarvis_tools/sub_code_agent.py +14 -16
- jarvis/jarvis_tools/virtual_tty.py +54 -32
- jarvis/jarvis_utils/clipboard.py +7 -10
- jarvis/jarvis_utils/config.py +98 -63
- jarvis/jarvis_utils/embedding.py +5 -5
- jarvis/jarvis_utils/fzf.py +8 -8
- jarvis/jarvis_utils/git_utils.py +81 -67
- jarvis/jarvis_utils/input.py +24 -49
- jarvis/jarvis_utils/jsonnet_compat.py +465 -0
- jarvis/jarvis_utils/methodology.py +33 -35
- jarvis/jarvis_utils/utils.py +245 -202
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/METADATA +205 -70
- jarvis_ai_assistant-0.7.8.dist-info/RECORD +218 -0
- jarvis/jarvis_agent/edit_file_handler.py +0 -584
- jarvis/jarvis_agent/rewrite_file_handler.py +0 -141
- jarvis/jarvis_agent/task_planner.py +0 -496
- jarvis/jarvis_platform/ai8.py +0 -332
- jarvis/jarvis_tools/ask_user.py +0 -54
- jarvis_ai_assistant-0.7.0.dist-info/RECORD +0 -192
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/top_level.txt +0 -0
jarvis/jarvis_git_squash/main.py
CHANGED
|
@@ -5,7 +5,6 @@ from typing import Dict
|
|
|
5
5
|
import typer
|
|
6
6
|
|
|
7
7
|
from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
|
|
8
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
9
8
|
from jarvis.jarvis_utils.utils import init_env
|
|
10
9
|
from jarvis.jarvis_utils.input import user_confirm
|
|
11
10
|
from jarvis.jarvis_utils.globals import get_agent, current_agent_name
|
|
@@ -38,11 +37,11 @@ class GitSquashTool:
|
|
|
38
37
|
"""Execute the squash operation"""
|
|
39
38
|
try:
|
|
40
39
|
if not self._confirm_squash():
|
|
41
|
-
|
|
40
|
+
print("⚠️ 操作已取消")
|
|
42
41
|
return
|
|
43
42
|
|
|
44
43
|
if not self._reset_to_commit(args["commit_hash"]):
|
|
45
|
-
|
|
44
|
+
print("⚠️ 重置到指定提交失败")
|
|
46
45
|
return
|
|
47
46
|
|
|
48
47
|
# Use existing GitCommitTool for new commit
|
|
@@ -53,7 +52,7 @@ class GitSquashTool:
|
|
|
53
52
|
exec_args["agent"] = agent
|
|
54
53
|
commit_tool.execute(exec_args)
|
|
55
54
|
except Exception as e:
|
|
56
|
-
|
|
55
|
+
print(f"⚠️ 压缩提交失败: {str(e)}")
|
|
57
56
|
|
|
58
57
|
|
|
59
58
|
@app.command()
|
|
@@ -61,7 +60,7 @@ def cli(
|
|
|
61
60
|
commit_hash: str = typer.Argument(..., help="要压缩的基础提交哈希"),
|
|
62
61
|
lang: str = typer.Option("Chinese", "--lang", help="提交信息的语言"),
|
|
63
62
|
):
|
|
64
|
-
init_env(
|
|
63
|
+
init_env()
|
|
65
64
|
tool = GitSquashTool()
|
|
66
65
|
tool.execute({"commit_hash": commit_hash, "lang": lang})
|
|
67
66
|
|
|
@@ -75,7 +75,7 @@ class GitCommitTool:
|
|
|
75
75
|
os.chdir(root_dir)
|
|
76
76
|
find_git_root_and_cd()
|
|
77
77
|
if not has_uncommitted_changes():
|
|
78
|
-
|
|
78
|
+
print("✅ 没有未提交的更改")
|
|
79
79
|
return None
|
|
80
80
|
return original_dir
|
|
81
81
|
|
|
@@ -129,42 +129,7 @@ class GitCommitTool:
|
|
|
129
129
|
|
|
130
130
|
try:
|
|
131
131
|
temp_diff_file_path = None
|
|
132
|
-
|
|
133
|
-
PrettyOutput.print("正在生成提交消息...", OutputType.INFO)
|
|
134
|
-
|
|
135
|
-
# 准备提示信息
|
|
136
|
-
custom_prompt = get_git_commit_prompt()
|
|
137
|
-
base_prompt = (
|
|
138
|
-
custom_prompt
|
|
139
|
-
if custom_prompt
|
|
140
|
-
else """根据代码差异生成提交信息:
|
|
141
|
-
提交信息应使用中文书写
|
|
142
|
-
# 格式模板
|
|
143
|
-
必须使用以下格式:
|
|
144
|
-
|
|
145
|
-
<类型>(<范围>): <主题>
|
|
146
|
-
|
|
147
|
-
[可选] 详细描述变更内容和原因
|
|
148
|
-
|
|
149
|
-
# 格式规则
|
|
150
|
-
1. 类型: fix(修复bug), feat(新功能), docs(文档), style(格式), refactor(重构), test(测试), chore(其他)
|
|
151
|
-
2. 范围表示变更的模块或组件 (例如: auth, database, ui)
|
|
152
|
-
3. 主题行不超过72个字符,不以句号结尾,使用祈使语气
|
|
153
|
-
4. 如有详细描述,使用空行分隔主题和详细描述
|
|
154
|
-
5. 详细描述部分应解释"是什么"和"为什么",而非"如何"
|
|
155
|
-
6. 仅输出提交信息,不要输出其他内容
|
|
156
|
-
"""
|
|
157
|
-
)
|
|
158
|
-
base_prompt += f"""
|
|
159
|
-
# 输出格式
|
|
160
|
-
{ot("COMMIT_MESSAGE")}
|
|
161
|
-
commit信息
|
|
162
|
-
{ct("COMMIT_MESSAGE")}
|
|
163
|
-
"""
|
|
164
|
-
|
|
165
|
-
# 优先从调用方传入的 agent 获取平台与模型
|
|
166
|
-
agent_from_args = args.get("agent")
|
|
167
|
-
|
|
132
|
+
|
|
168
133
|
# Get model_group from args
|
|
169
134
|
model_group = args.get("model_group")
|
|
170
135
|
|
|
@@ -184,6 +149,7 @@ commit信息
|
|
|
184
149
|
model_name = get_normal_model_name(model_group)
|
|
185
150
|
else:
|
|
186
151
|
# 如果没有提供 model_group,尝试从传入的 agent 获取
|
|
152
|
+
agent_from_args = args.get("agent")
|
|
187
153
|
if (
|
|
188
154
|
agent_from_args
|
|
189
155
|
and hasattr(agent_from_args, "model")
|
|
@@ -239,6 +205,40 @@ commit信息
|
|
|
239
205
|
else:
|
|
240
206
|
platform = PlatformRegistry().get_normal_platform()
|
|
241
207
|
|
|
208
|
+
# 生成提交信息
|
|
209
|
+
model_display_name = model_name or (platform.name() if platform else "AI")
|
|
210
|
+
print(f"ℹ️ 正在使用{model_display_name}生成提交消息...")
|
|
211
|
+
|
|
212
|
+
# 准备提示信息
|
|
213
|
+
custom_prompt = get_git_commit_prompt()
|
|
214
|
+
base_prompt = (
|
|
215
|
+
custom_prompt
|
|
216
|
+
if custom_prompt
|
|
217
|
+
else """根据代码差异生成提交信息:
|
|
218
|
+
提交信息应使用中文书写
|
|
219
|
+
# 格式模板
|
|
220
|
+
必须使用以下格式:
|
|
221
|
+
|
|
222
|
+
<类型>(<范围>): <主题>
|
|
223
|
+
|
|
224
|
+
[可选] 详细描述变更内容和原因
|
|
225
|
+
|
|
226
|
+
# 格式规则
|
|
227
|
+
1. 类型: fix(修复bug), feat(新功能), docs(文档), style(格式), refactor(重构), test(测试), chore(其他)
|
|
228
|
+
2. 范围表示变更的模块或组件 (例如: auth, database, ui)
|
|
229
|
+
3. 主题行不超过72个字符,不以句号结尾,使用祈使语气
|
|
230
|
+
4. 如有详细描述,使用空行分隔主题和详细描述
|
|
231
|
+
5. 详细描述部分应解释"是什么"和"为什么",而非"如何"
|
|
232
|
+
6. 仅输出提交信息,不要输出其他内容
|
|
233
|
+
"""
|
|
234
|
+
)
|
|
235
|
+
base_prompt += f"""
|
|
236
|
+
# 输出格式
|
|
237
|
+
{ot("COMMIT_MESSAGE")}
|
|
238
|
+
commit信息
|
|
239
|
+
{ct("COMMIT_MESSAGE")}
|
|
240
|
+
"""
|
|
241
|
+
|
|
242
242
|
# 跳过模型可用性校验:
|
|
243
243
|
# 为避免某些平台/代理不支持 get_model_list 接口导致的噪音日志(如 404),
|
|
244
244
|
# 这里默认不调用 platform.get_model_list() 进行模型可用性校验。
|
|
@@ -256,11 +256,11 @@ commit信息
|
|
|
256
256
|
upload_success = False
|
|
257
257
|
|
|
258
258
|
# Check if content is too large
|
|
259
|
-
is_large_content = is_context_overflow(diff, model_group)
|
|
259
|
+
is_large_content = is_context_overflow(diff, model_group, platform)
|
|
260
260
|
|
|
261
261
|
if is_large_content:
|
|
262
262
|
if not platform.support_upload_files():
|
|
263
|
-
|
|
263
|
+
print("❌ 差异文件太大,无法处理")
|
|
264
264
|
return {
|
|
265
265
|
"success": False,
|
|
266
266
|
"stdout": "",
|
|
@@ -279,7 +279,7 @@ commit信息
|
|
|
279
279
|
if upload_success:
|
|
280
280
|
pass
|
|
281
281
|
else:
|
|
282
|
-
|
|
282
|
+
print("❌ 上传代码差异文件失败")
|
|
283
283
|
return {
|
|
284
284
|
"success": False,
|
|
285
285
|
"stdout": "",
|
|
@@ -378,14 +378,9 @@ commit信息
|
|
|
378
378
|
try:
|
|
379
379
|
os.unlink(temp_diff_file_path)
|
|
380
380
|
except Exception as e:
|
|
381
|
-
|
|
382
|
-
f"无法删除临时文件: {str(e)}", OutputType.WARNING
|
|
383
|
-
)
|
|
381
|
+
print(f"⚠️ 无法删除临时文件: {str(e)}")
|
|
384
382
|
|
|
385
|
-
PrettyOutput.print(
|
|
386
|
-
f"提交哈希: {commit_hash}\n提交消息: {commit_message}",
|
|
387
|
-
OutputType.SUCCESS,
|
|
388
|
-
)
|
|
383
|
+
PrettyOutput.print(f"提交哈希: {commit_hash}\n提交消息: {commit_message}", OutputType.SUCCESS)
|
|
389
384
|
|
|
390
385
|
return {
|
|
391
386
|
"success": True,
|
|
@@ -396,7 +391,7 @@ commit信息
|
|
|
396
391
|
"stderr": "",
|
|
397
392
|
}
|
|
398
393
|
except Exception as e:
|
|
399
|
-
|
|
394
|
+
print(f"❌ 提交失败: {str(e)}")
|
|
400
395
|
return {
|
|
401
396
|
"success": False,
|
|
402
397
|
"stdout": "",
|
|
@@ -425,7 +420,7 @@ def cli(
|
|
|
425
420
|
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
|
426
421
|
),
|
|
427
422
|
):
|
|
428
|
-
init_env(
|
|
423
|
+
init_env()
|
|
429
424
|
tool = GitCommitTool()
|
|
430
425
|
tool.execute(
|
|
431
426
|
{
|
|
@@ -8,7 +8,6 @@ from urllib.parse import parse_qs, urlencode, urljoin
|
|
|
8
8
|
import requests # type: ignore[import-untyped]
|
|
9
9
|
|
|
10
10
|
from jarvis.jarvis_mcp import McpClient
|
|
11
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class SSEMcpClient(McpClient):
|
|
@@ -78,13 +77,10 @@ class SSEMcpClient(McpClient):
|
|
|
78
77
|
|
|
79
78
|
if not self.messages_endpoint:
|
|
80
79
|
self.messages_endpoint = "/messages" # 默认端点
|
|
81
|
-
|
|
82
|
-
f"未获取到消息端点,使用默认值: {self.messages_endpoint}",
|
|
83
|
-
OutputType.WARNING,
|
|
84
|
-
)
|
|
80
|
+
print(f"⚠️ 未获取到消息端点,使用默认值: {self.messages_endpoint}")
|
|
85
81
|
|
|
86
82
|
if not self.session_id:
|
|
87
|
-
|
|
83
|
+
print("⚠️ 未获取到会话ID")
|
|
88
84
|
|
|
89
85
|
# 发送初始化请求
|
|
90
86
|
response = self._send_request(
|
|
@@ -107,7 +103,7 @@ class SSEMcpClient(McpClient):
|
|
|
107
103
|
self._send_notification("notifications/initialized", {})
|
|
108
104
|
|
|
109
105
|
except Exception as e:
|
|
110
|
-
|
|
106
|
+
print(f"❌ MCP初始化失败: {str(e)}")
|
|
111
107
|
raise
|
|
112
108
|
|
|
113
109
|
def _start_sse_connection(self) -> None:
|
|
@@ -138,7 +134,7 @@ class SSEMcpClient(McpClient):
|
|
|
138
134
|
self.sse_thread.start()
|
|
139
135
|
|
|
140
136
|
except Exception as e:
|
|
141
|
-
|
|
137
|
+
print(f"❌ SSE连接失败: {str(e)}")
|
|
142
138
|
raise
|
|
143
139
|
|
|
144
140
|
def _process_sse_events(self) -> None:
|
|
@@ -166,9 +162,7 @@ class SSEMcpClient(McpClient):
|
|
|
166
162
|
if "session_id" in query_params:
|
|
167
163
|
self.session_id = query_params["session_id"][0]
|
|
168
164
|
except Exception as e:
|
|
169
|
-
|
|
170
|
-
f"解析消息端点或会话ID失败: {e}", OutputType.WARNING
|
|
171
|
-
)
|
|
165
|
+
print(f"⚠️ 解析消息端点或会话ID失败: {e}")
|
|
172
166
|
else:
|
|
173
167
|
buffer += data
|
|
174
168
|
elif line.startswith(":"): # 忽略注释行
|
|
@@ -184,10 +178,10 @@ class SSEMcpClient(McpClient):
|
|
|
184
178
|
try:
|
|
185
179
|
self._handle_sse_event(buffer)
|
|
186
180
|
except Exception as e:
|
|
187
|
-
|
|
181
|
+
print(f"❌ 处理SSE事件出错: {e}")
|
|
188
182
|
buffer = ""
|
|
189
183
|
|
|
190
|
-
|
|
184
|
+
print("⚠️ SSE连接已关闭")
|
|
191
185
|
|
|
192
186
|
def _handle_sse_event(self, data: str) -> None:
|
|
193
187
|
"""处理单个SSE事件数据"""
|
|
@@ -217,11 +211,10 @@ class SSEMcpClient(McpClient):
|
|
|
217
211
|
except Exception as e:
|
|
218
212
|
error_lines.append(f"处理通知时出错 ({method}): {e}")
|
|
219
213
|
if error_lines:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
PrettyOutput.print(f"处理SSE事件时出错: {e}", OutputType.ERROR)
|
|
214
|
+
joined_errors = '\n'.join(error_lines)
|
|
215
|
+
print(f"❌ {joined_errors}")
|
|
216
|
+
except Exception:
|
|
217
|
+
print(f"⚠️ 无法解析SSE事件: {data}")
|
|
225
218
|
|
|
226
219
|
def register_notification_handler(self, method: str, handler: Callable) -> None:
|
|
227
220
|
"""注册通知处理器
|
|
@@ -341,7 +334,7 @@ class SSEMcpClient(McpClient):
|
|
|
341
334
|
self.pending_requests.pop(req_id, None)
|
|
342
335
|
self.request_results.pop(req_id, None)
|
|
343
336
|
|
|
344
|
-
|
|
337
|
+
print(f"❌ 发送请求失败: {str(e)}")
|
|
345
338
|
raise
|
|
346
339
|
|
|
347
340
|
def _send_notification(self, method: str, params: Dict[str, Any]) -> None:
|
|
@@ -396,7 +389,7 @@ class SSEMcpClient(McpClient):
|
|
|
396
389
|
post_response.raise_for_status()
|
|
397
390
|
|
|
398
391
|
except Exception as e:
|
|
399
|
-
|
|
392
|
+
print(f"❌ 发送通知失败: {str(e)}")
|
|
400
393
|
raise
|
|
401
394
|
|
|
402
395
|
def get_tool_list(self) -> List[Dict[str, Any]]:
|
|
@@ -439,10 +432,10 @@ class SSEMcpClient(McpClient):
|
|
|
439
432
|
else:
|
|
440
433
|
error_msg += ": 未知错误"
|
|
441
434
|
|
|
442
|
-
|
|
435
|
+
print(f"❌ {error_msg}")
|
|
443
436
|
return []
|
|
444
437
|
except Exception as e:
|
|
445
|
-
|
|
438
|
+
print(f"❌ 获取工具列表失败: {str(e)}")
|
|
446
439
|
return []
|
|
447
440
|
|
|
448
441
|
def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
|
@@ -481,7 +474,7 @@ class SSEMcpClient(McpClient):
|
|
|
481
474
|
"stderr": response.get("error", "Unknown error"),
|
|
482
475
|
}
|
|
483
476
|
except Exception as e:
|
|
484
|
-
|
|
477
|
+
print(f"❌ 执行工具失败: {str(e)}")
|
|
485
478
|
return {"success": False, "stdout": "", "stderr": str(e)}
|
|
486
479
|
|
|
487
480
|
def get_resource_list(self) -> List[Dict[str, Any]]:
|
|
@@ -504,10 +497,10 @@ class SSEMcpClient(McpClient):
|
|
|
504
497
|
error_msg += f": {response['error']}"
|
|
505
498
|
else:
|
|
506
499
|
error_msg += ": 未知错误"
|
|
507
|
-
|
|
500
|
+
print(f"❌ {error_msg}")
|
|
508
501
|
return []
|
|
509
502
|
except Exception as e:
|
|
510
|
-
|
|
503
|
+
print(f"❌ 获取资源列表失败: {str(e)}")
|
|
511
504
|
return []
|
|
512
505
|
|
|
513
506
|
def get_resource(self, uri: str) -> Dict[str, Any]:
|
|
@@ -548,11 +541,11 @@ class SSEMcpClient(McpClient):
|
|
|
548
541
|
error_msg += f": {response['error']}"
|
|
549
542
|
else:
|
|
550
543
|
error_msg += ": 未知错误"
|
|
551
|
-
|
|
544
|
+
print(f"❌ {error_msg}")
|
|
552
545
|
return {"success": False, "stdout": "", "stderr": error_msg}
|
|
553
546
|
except Exception as e:
|
|
554
547
|
error_msg = f"获取资源内容失败: {str(e)}"
|
|
555
|
-
|
|
548
|
+
print(f"❌ {error_msg}")
|
|
556
549
|
return {"success": False, "stdout": "", "stderr": error_msg}
|
|
557
550
|
|
|
558
551
|
def __del__(self):
|
|
@@ -5,7 +5,6 @@ import subprocess
|
|
|
5
5
|
from typing import Any, Dict, List, Optional
|
|
6
6
|
|
|
7
7
|
from jarvis.jarvis_mcp import McpClient
|
|
8
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
class StdioMcpClient(McpClient):
|
|
@@ -50,7 +49,7 @@ class StdioMcpClient(McpClient):
|
|
|
50
49
|
)
|
|
51
50
|
|
|
52
51
|
except Exception as e:
|
|
53
|
-
|
|
52
|
+
print(f"❌ 启动MCP进程失败: {str(e)}")
|
|
54
53
|
raise
|
|
55
54
|
|
|
56
55
|
def _initialize(self) -> None:
|
|
@@ -79,7 +78,7 @@ class StdioMcpClient(McpClient):
|
|
|
79
78
|
self._send_notification("notifications/initialized", {})
|
|
80
79
|
|
|
81
80
|
except Exception as e:
|
|
82
|
-
|
|
81
|
+
print(f"❌ MCP初始化失败: {str(e)}")
|
|
83
82
|
raise
|
|
84
83
|
|
|
85
84
|
def _send_request(self, method: str, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
@@ -108,7 +107,7 @@ class StdioMcpClient(McpClient):
|
|
|
108
107
|
return json.loads(response)
|
|
109
108
|
|
|
110
109
|
except Exception as e:
|
|
111
|
-
|
|
110
|
+
print(f"❌ 发送请求失败: {str(e)}")
|
|
112
111
|
raise
|
|
113
112
|
|
|
114
113
|
def _send_notification(self, method: str, params: Dict[str, Any]) -> None:
|
|
@@ -129,7 +128,7 @@ class StdioMcpClient(McpClient):
|
|
|
129
128
|
self.process.stdin.flush() # type: ignore
|
|
130
129
|
|
|
131
130
|
except Exception as e:
|
|
132
|
-
|
|
131
|
+
print(f"❌ 发送通知失败: {str(e)}")
|
|
133
132
|
raise
|
|
134
133
|
|
|
135
134
|
def get_tool_list(self) -> List[Dict[str, Any]]:
|
|
@@ -172,10 +171,10 @@ class StdioMcpClient(McpClient):
|
|
|
172
171
|
else:
|
|
173
172
|
error_msg += ": 未知错误"
|
|
174
173
|
|
|
175
|
-
|
|
174
|
+
print(f"❌ {error_msg}")
|
|
176
175
|
return []
|
|
177
176
|
except Exception as e:
|
|
178
|
-
|
|
177
|
+
print(f"❌ 获取工具列表失败: {str(e)}")
|
|
179
178
|
return []
|
|
180
179
|
|
|
181
180
|
def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
|
@@ -214,7 +213,7 @@ class StdioMcpClient(McpClient):
|
|
|
214
213
|
"stderr": response.get("error", "Unknown error"),
|
|
215
214
|
}
|
|
216
215
|
except Exception as e:
|
|
217
|
-
|
|
216
|
+
print(f"❌ 执行工具失败: {str(e)}")
|
|
218
217
|
return {"success": False, "stdout": "", "stderr": str(e)}
|
|
219
218
|
|
|
220
219
|
def get_resource_list(self) -> List[Dict[str, Any]]:
|
|
@@ -237,10 +236,10 @@ class StdioMcpClient(McpClient):
|
|
|
237
236
|
error_msg += f": {response['error']}"
|
|
238
237
|
else:
|
|
239
238
|
error_msg += ": 未知错误"
|
|
240
|
-
|
|
239
|
+
print(f"❌ {error_msg}")
|
|
241
240
|
return []
|
|
242
241
|
except Exception as e:
|
|
243
|
-
|
|
242
|
+
print(f"❌ 获取资源列表失败: {str(e)}")
|
|
244
243
|
return []
|
|
245
244
|
|
|
246
245
|
def get_resource(self, uri: str) -> Dict[str, Any]:
|
|
@@ -281,11 +280,11 @@ class StdioMcpClient(McpClient):
|
|
|
281
280
|
error_msg += f": {response['error']}"
|
|
282
281
|
else:
|
|
283
282
|
error_msg += ": 未知错误"
|
|
284
|
-
|
|
283
|
+
print(f"❌ {error_msg}")
|
|
285
284
|
return {"success": False, "stdout": "", "stderr": error_msg}
|
|
286
285
|
except Exception as e:
|
|
287
286
|
error_msg = f"获取资源内容失败: {str(e)}"
|
|
288
|
-
|
|
287
|
+
print(f"❌ {error_msg}")
|
|
289
288
|
return {"success": False, "stdout": "", "stderr": error_msg}
|
|
290
289
|
|
|
291
290
|
def __del__(self):
|
|
@@ -7,7 +7,6 @@ from urllib.parse import urljoin
|
|
|
7
7
|
import requests # type: ignore[import-untyped]
|
|
8
8
|
|
|
9
9
|
from jarvis.jarvis_mcp import McpClient
|
|
10
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
class StreamableMcpClient(McpClient):
|
|
@@ -86,7 +85,7 @@ class StreamableMcpClient(McpClient):
|
|
|
86
85
|
self._send_notification("notifications/initialized", {})
|
|
87
86
|
|
|
88
87
|
except Exception as e:
|
|
89
|
-
|
|
88
|
+
print(f"❌ MCP初始化失败: {str(e)}")
|
|
90
89
|
raise
|
|
91
90
|
|
|
92
91
|
def register_notification_handler(self, method: str, handler: Callable) -> None:
|
|
@@ -182,14 +181,16 @@ class StreamableMcpClient(McpClient):
|
|
|
182
181
|
handler(params)
|
|
183
182
|
except Exception as e:
|
|
184
183
|
error_lines.append(f"处理通知时出错 ({notify_method}): {e}")
|
|
185
|
-
except
|
|
184
|
+
except Exception:
|
|
186
185
|
warning_lines.append(f"无法解析响应: {line}")
|
|
187
186
|
continue
|
|
188
187
|
|
|
189
188
|
if warning_lines:
|
|
190
|
-
|
|
189
|
+
joined_warnings = '\n'.join(warning_lines)
|
|
190
|
+
print(f"⚠️ {joined_warnings}")
|
|
191
191
|
if error_lines:
|
|
192
|
-
|
|
192
|
+
joined_errors = '\n'.join(error_lines)
|
|
193
|
+
print(f"❌ {joined_errors}")
|
|
193
194
|
# Ensure response is closed after streaming
|
|
194
195
|
response.close()
|
|
195
196
|
if result is None:
|
|
@@ -198,7 +199,7 @@ class StreamableMcpClient(McpClient):
|
|
|
198
199
|
return result
|
|
199
200
|
|
|
200
201
|
except Exception as e:
|
|
201
|
-
|
|
202
|
+
print(f"❌ 发送请求失败: {str(e)}")
|
|
202
203
|
raise
|
|
203
204
|
finally:
|
|
204
205
|
# 清理请求状态
|
|
@@ -226,7 +227,7 @@ class StreamableMcpClient(McpClient):
|
|
|
226
227
|
response.close()
|
|
227
228
|
|
|
228
229
|
except Exception as e:
|
|
229
|
-
|
|
230
|
+
print(f"❌ 发送通知失败: {str(e)}")
|
|
230
231
|
raise
|
|
231
232
|
|
|
232
233
|
def get_tool_list(self) -> List[Dict[str, Any]]:
|
|
@@ -269,10 +270,10 @@ class StreamableMcpClient(McpClient):
|
|
|
269
270
|
else:
|
|
270
271
|
error_msg += ": 未知错误"
|
|
271
272
|
|
|
272
|
-
|
|
273
|
+
print(f"❌ {error_msg}")
|
|
273
274
|
return []
|
|
274
275
|
except Exception as e:
|
|
275
|
-
|
|
276
|
+
print(f"❌ 获取工具列表失败: {str(e)}")
|
|
276
277
|
return []
|
|
277
278
|
|
|
278
279
|
def execute(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
|
@@ -311,7 +312,7 @@ class StreamableMcpClient(McpClient):
|
|
|
311
312
|
"stderr": response.get("error", "Unknown error"),
|
|
312
313
|
}
|
|
313
314
|
except Exception as e:
|
|
314
|
-
|
|
315
|
+
print(f"❌ 执行工具失败: {str(e)}")
|
|
315
316
|
return {"success": False, "stdout": "", "stderr": str(e)}
|
|
316
317
|
|
|
317
318
|
def get_resource_list(self) -> List[Dict[str, Any]]:
|
|
@@ -334,10 +335,10 @@ class StreamableMcpClient(McpClient):
|
|
|
334
335
|
error_msg += f": {response['error']}"
|
|
335
336
|
else:
|
|
336
337
|
error_msg += ": 未知错误"
|
|
337
|
-
|
|
338
|
+
print(f"❌ {error_msg}")
|
|
338
339
|
return []
|
|
339
340
|
except Exception as e:
|
|
340
|
-
|
|
341
|
+
print(f"❌ 获取资源列表失败: {str(e)}")
|
|
341
342
|
return []
|
|
342
343
|
|
|
343
344
|
def get_resource(self, uri: str) -> Dict[str, Any]:
|
|
@@ -378,11 +379,11 @@ class StreamableMcpClient(McpClient):
|
|
|
378
379
|
error_msg += f": {response['error']}"
|
|
379
380
|
else:
|
|
380
381
|
error_msg += ": 未知错误"
|
|
381
|
-
|
|
382
|
+
print(f"❌ {error_msg}")
|
|
382
383
|
return {"success": False, "stdout": "", "stderr": error_msg}
|
|
383
384
|
except Exception as e:
|
|
384
385
|
error_msg = f"获取资源内容失败: {str(e)}"
|
|
385
|
-
|
|
386
|
+
print(f"❌ {error_msg}")
|
|
386
387
|
return {"success": False, "stdout": "", "stderr": error_msg}
|
|
387
388
|
|
|
388
389
|
def __del__(self):
|