jarvis-ai-assistant 0.3.14__tar.gz → 0.3.16__tar.gz
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_ai_assistant-0.3.14/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.3.16}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/pyproject.toml +1 -1
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/setup.py +1 -1
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/__init__.py +1 -1
- jarvis_ai_assistant-0.3.16/src/jarvis/jarvis_agent/jarvis.py +286 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/main.py +18 -10
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_agent/code_agent.py +38 -12
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +20 -7
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_multi_agent/main.py +8 -4
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform_manager/service.py +106 -76
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/base.py +10 -1
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/registry.py +40 -12
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
- jarvis_ai_assistant-0.3.14/src/jarvis/jarvis_agent/jarvis.py +0 -94
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/README.md +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/agent_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/config_editor.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/edit_file_handler.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/file_methodology_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/memory_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/methodology_share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/prompt_builder.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/prompts.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/protocols.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/session_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/task_analyzer.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/task_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/tool_executor.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/tool_share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_agent/lint.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_data/config_schema.json +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_git_squash/main.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_git_utils/git_commiter.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_mcp/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_memory_organizer/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_memory_organizer/memory_organizer.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_methodology/main.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/ai8.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/base.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/human.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/kimi.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/tongyi.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform_manager/main.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/cache.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/cli.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/embedding_manager.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/llm_interface.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/query_rewriter.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/rag_pipeline.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/reranker.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/retriever.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_smart_shell/main.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/cli.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/stats.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/storage.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/visualizer.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/clear_memory.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/cli/main.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/edit_file.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/execute_script.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/read_code.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/retrieve_memory.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/save_memory.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/search_web.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/clipboard.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/config.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/embedding.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/file_processors.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/git_utils.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/globals.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/http.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/input.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/methodology.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/output.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/tag.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/utils.py +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
- {jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "jarvis-ai-assistant"
|
7
|
-
version = "0.3.
|
7
|
+
version = "0.3.16"
|
8
8
|
description = "Jarvis: An AI assistant that uses tools to interact with the system"
|
9
9
|
readme = "README.md"
|
10
10
|
authors = [{ name = "skyfire", email = "skyfireitdiy@hotmail.com" }]
|
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages # type: ignore
|
|
3
3
|
|
4
4
|
setup(
|
5
5
|
name="jarvis-ai-assistant",
|
6
|
-
version="0.3.
|
6
|
+
version="0.3.16",
|
7
7
|
author="skyfire",
|
8
8
|
author_email="skyfireitdiy@hotmail.com",
|
9
9
|
description="An AI assistant that uses various tools to interact with the system",
|
@@ -0,0 +1,286 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""Jarvis AI 助手主入口模块"""
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
import typer
|
6
|
+
|
7
|
+
from jarvis.jarvis_agent import OutputType, PrettyOutput
|
8
|
+
from jarvis.jarvis_agent.agent_manager import AgentManager
|
9
|
+
from jarvis.jarvis_agent.config_editor import ConfigEditor
|
10
|
+
from jarvis.jarvis_agent.methodology_share_manager import MethodologyShareManager
|
11
|
+
from jarvis.jarvis_agent.tool_share_manager import ToolShareManager
|
12
|
+
from jarvis.jarvis_utils.utils import init_env
|
13
|
+
from jarvis.jarvis_utils.input import user_confirm, get_single_line_input
|
14
|
+
import os
|
15
|
+
import sys
|
16
|
+
import subprocess
|
17
|
+
from pathlib import Path
|
18
|
+
import yaml # type: ignore
|
19
|
+
from rich.table import Table
|
20
|
+
from rich.console import Console
|
21
|
+
|
22
|
+
app = typer.Typer(help="Jarvis AI 助手")
|
23
|
+
|
24
|
+
|
25
|
+
@app.callback(invoke_without_command=True)
|
26
|
+
def run_cli(
|
27
|
+
ctx: typer.Context,
|
28
|
+
llm_type: str = typer.Option(
|
29
|
+
"normal",
|
30
|
+
"-t",
|
31
|
+
"--llm-type",
|
32
|
+
help="使用的LLM类型,可选值:'normal'(普通)或 'thinking'(思考模式)",
|
33
|
+
),
|
34
|
+
task: Optional[str] = typer.Option(
|
35
|
+
None, "-T", "--task", help="从命令行直接输入任务内容"
|
36
|
+
),
|
37
|
+
model_group: Optional[str] = typer.Option(
|
38
|
+
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
39
|
+
),
|
40
|
+
tool_group: Optional[str] = typer.Option(
|
41
|
+
None, "-G", "--tool-group", help="使用的工具组,覆盖配置文件中的设置"
|
42
|
+
),
|
43
|
+
config_file: Optional[str] = typer.Option(
|
44
|
+
None, "-f", "--config", help="自定义配置文件路径"
|
45
|
+
),
|
46
|
+
restore_session: bool = typer.Option(
|
47
|
+
False,
|
48
|
+
"--restore-session",
|
49
|
+
help="从 .jarvis/saved_session.json 恢复会话",
|
50
|
+
),
|
51
|
+
edit: bool = typer.Option(False, "-e", "--edit", help="编辑配置文件"),
|
52
|
+
share_methodology: bool = typer.Option(
|
53
|
+
False, "--share-methodology", help="分享本地方法论到中心方法论仓库"
|
54
|
+
),
|
55
|
+
share_tool: bool = typer.Option(
|
56
|
+
False, "--share-tool", help="分享本地工具到中心工具仓库"
|
57
|
+
),
|
58
|
+
) -> None:
|
59
|
+
"""Jarvis AI assistant command-line interface."""
|
60
|
+
if ctx.invoked_subcommand is not None:
|
61
|
+
return
|
62
|
+
|
63
|
+
# 处理配置文件编辑
|
64
|
+
if edit:
|
65
|
+
ConfigEditor.edit_config(config_file)
|
66
|
+
return
|
67
|
+
|
68
|
+
# 处理方法论分享
|
69
|
+
if share_methodology:
|
70
|
+
init_env("", config_file=config_file) # 初始化配置但不显示欢迎信息
|
71
|
+
methodology_manager = MethodologyShareManager()
|
72
|
+
methodology_manager.run()
|
73
|
+
return
|
74
|
+
|
75
|
+
# 处理工具分享
|
76
|
+
if share_tool:
|
77
|
+
init_env("", config_file=config_file) # 初始化配置但不显示欢迎信息
|
78
|
+
tool_manager = ToolShareManager()
|
79
|
+
tool_manager.run()
|
80
|
+
return
|
81
|
+
|
82
|
+
# 在初始化环境前检测Git仓库,并可选择自动切换到代码开发模式(jca)
|
83
|
+
try:
|
84
|
+
res = subprocess.run(
|
85
|
+
["git", "rev-parse", "--show-toplevel"],
|
86
|
+
capture_output=True,
|
87
|
+
text=True,
|
88
|
+
)
|
89
|
+
if res.returncode == 0:
|
90
|
+
git_root = res.stdout.strip()
|
91
|
+
if git_root and os.path.isdir(git_root):
|
92
|
+
PrettyOutput.print(
|
93
|
+
f"检测到当前位于 Git 仓库: {git_root}", OutputType.INFO
|
94
|
+
)
|
95
|
+
if user_confirm(
|
96
|
+
"检测到Git仓库,是否切换到代码开发模式(jca)?", default=False
|
97
|
+
):
|
98
|
+
# 构建并切换到 jarvis-code-agent 命令,传递兼容参数
|
99
|
+
args = ["jarvis-code-agent"]
|
100
|
+
if llm_type:
|
101
|
+
args += ["-t", llm_type]
|
102
|
+
if model_group:
|
103
|
+
args += ["-g", model_group]
|
104
|
+
if tool_group:
|
105
|
+
args += ["-G", tool_group]
|
106
|
+
if config_file:
|
107
|
+
args += ["-f", config_file]
|
108
|
+
if restore_session:
|
109
|
+
args += ["--restore-session"]
|
110
|
+
if task:
|
111
|
+
args += ["-r", task]
|
112
|
+
PrettyOutput.print(
|
113
|
+
"正在切换到 'jca'(jarvis-code-agent)以进入代码开发模式...",
|
114
|
+
OutputType.INFO,
|
115
|
+
)
|
116
|
+
os.execvp(args[0], args)
|
117
|
+
except Exception:
|
118
|
+
# 静默忽略检测异常,不影响主流程
|
119
|
+
pass
|
120
|
+
|
121
|
+
# 在进入默认通用代理前,列出内置配置供选择(agent/multi_agent/roles)
|
122
|
+
try:
|
123
|
+
# 优先使用项目内置目录,若不存在则回退到指定的绝对路径
|
124
|
+
builtin_root = Path(__file__).resolve().parents[3] / "builtin"
|
125
|
+
if not builtin_root.exists():
|
126
|
+
builtin_root = Path("/home/skyfire/code/Jarvis/builtin")
|
127
|
+
|
128
|
+
categories = [
|
129
|
+
("agent", "jarvis-agent", "*.yaml"),
|
130
|
+
("multi_agent", "jarvis-multi-agent", "*.yaml"),
|
131
|
+
("roles", "jarvis-platform-manager", "*.yaml"),
|
132
|
+
]
|
133
|
+
|
134
|
+
options = []
|
135
|
+
for cat, cmd, pattern in categories:
|
136
|
+
dir_path = builtin_root / cat
|
137
|
+
if not dir_path.exists():
|
138
|
+
continue
|
139
|
+
for fpath in sorted(dir_path.glob(pattern)):
|
140
|
+
# 解析YAML以获取可读名称/描述(失败时静默降级为文件名)
|
141
|
+
name = fpath.stem
|
142
|
+
desc = ""
|
143
|
+
try:
|
144
|
+
with open(fpath, "r", encoding="utf-8", errors="ignore") as fh:
|
145
|
+
data = yaml.safe_load(fh) or {}
|
146
|
+
if isinstance(data, dict):
|
147
|
+
name = data.get("name") or data.get("title") or name
|
148
|
+
desc = data.get("description") or data.get("desc") or ""
|
149
|
+
if cat == "roles" and isinstance(data.get("roles"), list):
|
150
|
+
if not desc:
|
151
|
+
desc = f"{len(data['roles'])} 个角色"
|
152
|
+
except Exception:
|
153
|
+
# 忽略解析错误,使用默认显示
|
154
|
+
pass
|
155
|
+
|
156
|
+
# 为 roles 构建详细信息(每个角色的名称与描述)
|
157
|
+
details = ""
|
158
|
+
if cat == "roles":
|
159
|
+
roles = (data or {}).get("roles", [])
|
160
|
+
if isinstance(roles, list):
|
161
|
+
lines = []
|
162
|
+
for role in roles:
|
163
|
+
if isinstance(role, dict):
|
164
|
+
rname = str(role.get("name", "") or "")
|
165
|
+
rdesc = str(role.get("description", "") or "")
|
166
|
+
lines.append(f"{rname} - {rdesc}" if rdesc else rname)
|
167
|
+
details = "\n".join([ln for ln in lines if ln])
|
168
|
+
# 如果没有角色详情,退回到统计信息
|
169
|
+
if not details and isinstance((data or {}).get("roles"), list):
|
170
|
+
details = f"{len(data['roles'])} 个角色"
|
171
|
+
|
172
|
+
options.append(
|
173
|
+
{
|
174
|
+
"category": cat,
|
175
|
+
"cmd": cmd,
|
176
|
+
"file": str(fpath),
|
177
|
+
"name": str(name),
|
178
|
+
"desc": str(desc),
|
179
|
+
"details": str(details),
|
180
|
+
}
|
181
|
+
)
|
182
|
+
|
183
|
+
if options:
|
184
|
+
PrettyOutput.section("可用的内置配置", OutputType.SUCCESS)
|
185
|
+
# 使用 rich Table 呈现
|
186
|
+
table = Table(show_header=True, header_style="bold magenta")
|
187
|
+
table.add_column("No.", style="cyan", no_wrap=True)
|
188
|
+
table.add_column("类型", style="green", no_wrap=True)
|
189
|
+
table.add_column("名称", style="bold")
|
190
|
+
table.add_column("文件", style="dim")
|
191
|
+
table.add_column("描述/详情", style="white")
|
192
|
+
|
193
|
+
for idx, opt in enumerate(options, 1):
|
194
|
+
category = opt.get("category", "")
|
195
|
+
name = opt.get("name", "")
|
196
|
+
file_path = opt.get("file", "")
|
197
|
+
# multi_agent: 优先显示顶层描述
|
198
|
+
# roles: 显示每个角色名称与描述(多行)
|
199
|
+
# 其他:显示 desc
|
200
|
+
if category == "roles" and opt.get("details"):
|
201
|
+
detail = opt["details"]
|
202
|
+
else:
|
203
|
+
detail = opt.get("desc", "")
|
204
|
+
|
205
|
+
table.add_row(str(idx), category, name, file_path, detail)
|
206
|
+
|
207
|
+
Console().print(table)
|
208
|
+
|
209
|
+
choice = get_single_line_input(
|
210
|
+
"选择要启动的配置编号,直接回车使用默认通用代理(jvs): ", default=""
|
211
|
+
)
|
212
|
+
|
213
|
+
if choice.strip():
|
214
|
+
try:
|
215
|
+
index = int(choice.strip())
|
216
|
+
if 1 <= index <= len(options):
|
217
|
+
sel = options[index - 1]
|
218
|
+
args = []
|
219
|
+
|
220
|
+
if sel["category"] == "agent":
|
221
|
+
# jarvis-agent 支持 -f/--config(全局配置)与 -c/--agent-definition
|
222
|
+
args = [sel["cmd"], "-c", sel["file"]]
|
223
|
+
if llm_type:
|
224
|
+
args += ["--llm-type", llm_type]
|
225
|
+
if model_group:
|
226
|
+
args += ["-g", model_group]
|
227
|
+
if config_file:
|
228
|
+
args += ["-f", config_file]
|
229
|
+
if task:
|
230
|
+
args += ["--task", task]
|
231
|
+
|
232
|
+
elif sel["category"] == "multi_agent":
|
233
|
+
# jarvis-multi-agent 需要 -c/--config,用户输入通过 -i/--input 传递
|
234
|
+
args = [sel["cmd"], "-c", sel["file"]]
|
235
|
+
if task:
|
236
|
+
args += ["-i", task]
|
237
|
+
|
238
|
+
elif sel["category"] == "roles":
|
239
|
+
# jarvis-platform-manager role 子命令,支持 -c/-t/-g
|
240
|
+
args = [sel["cmd"], "role", "-c", sel["file"]]
|
241
|
+
if llm_type:
|
242
|
+
args += ["-t", llm_type]
|
243
|
+
if model_group:
|
244
|
+
args += ["-g", model_group]
|
245
|
+
|
246
|
+
if args:
|
247
|
+
PrettyOutput.print(
|
248
|
+
f"正在启动: {' '.join(args)}", OutputType.INFO
|
249
|
+
)
|
250
|
+
os.execvp(args[0], args)
|
251
|
+
except Exception:
|
252
|
+
# 任何异常都不影响默认流程
|
253
|
+
pass
|
254
|
+
except Exception:
|
255
|
+
# 静默忽略内置配置扫描错误,不影响主流程
|
256
|
+
pass
|
257
|
+
|
258
|
+
# 初始化环境
|
259
|
+
init_env(
|
260
|
+
"欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=config_file
|
261
|
+
)
|
262
|
+
|
263
|
+
# 运行主流程
|
264
|
+
try:
|
265
|
+
agent_manager = AgentManager(
|
266
|
+
llm_type=llm_type,
|
267
|
+
model_group=model_group,
|
268
|
+
tool_group=tool_group,
|
269
|
+
restore_session=restore_session,
|
270
|
+
)
|
271
|
+
agent_manager.initialize()
|
272
|
+
agent_manager.run_task(task)
|
273
|
+
except typer.Exit:
|
274
|
+
raise
|
275
|
+
except Exception as err: # pylint: disable=broad-except
|
276
|
+
PrettyOutput.print(f"初始化错误: {str(err)}", OutputType.ERROR)
|
277
|
+
raise typer.Exit(code=1)
|
278
|
+
|
279
|
+
|
280
|
+
def main() -> None:
|
281
|
+
"""Application entry point."""
|
282
|
+
app()
|
283
|
+
|
284
|
+
|
285
|
+
if __name__ == "__main__":
|
286
|
+
main()
|
@@ -3,7 +3,7 @@ import os
|
|
3
3
|
from typing import Optional
|
4
4
|
|
5
5
|
import typer
|
6
|
-
import yaml
|
6
|
+
import yaml # type: ignore[import-untyped]
|
7
7
|
|
8
8
|
from jarvis.jarvis_agent import Agent
|
9
9
|
from jarvis.jarvis_utils.input import get_multiline_input
|
@@ -45,20 +45,22 @@ def cli(
|
|
45
45
|
agent_definition: Optional[str] = typer.Option(
|
46
46
|
None, "-c", "--agent-definition", help="代理定义文件路径"
|
47
47
|
),
|
48
|
-
task: Optional[str] = typer.Option(
|
49
|
-
None, "-t", "--task", help="初始任务内容"
|
50
|
-
),
|
48
|
+
task: Optional[str] = typer.Option(None, "-T", "--task", help="初始任务内容"),
|
51
49
|
llm_type: str = typer.Option(
|
52
50
|
"normal",
|
53
|
-
"-t",
|
51
|
+
"-t",
|
52
|
+
"--llm-type",
|
54
53
|
help="使用的LLM类型,覆盖配置文件中的设置",
|
55
54
|
),
|
56
55
|
model_group: Optional[str] = typer.Option(
|
57
56
|
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
58
|
-
),
|
57
|
+
),
|
58
|
+
):
|
59
59
|
"""Main entry point for Jarvis agent"""
|
60
60
|
# Initialize environment
|
61
|
-
init_env(
|
61
|
+
init_env(
|
62
|
+
"欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=config_file
|
63
|
+
)
|
62
64
|
|
63
65
|
# Load configuration
|
64
66
|
config = load_config(agent_definition) if agent_definition else {}
|
@@ -77,21 +79,27 @@ def cli(
|
|
77
79
|
if task:
|
78
80
|
PrettyOutput.print(f"执行初始任务: {task}", OutputType.INFO)
|
79
81
|
agent.run(task)
|
80
|
-
|
82
|
+
return
|
81
83
|
|
82
84
|
try:
|
83
85
|
user_input = get_multiline_input("请输入你的任务(输入空行退出):")
|
84
86
|
if not user_input:
|
85
|
-
|
87
|
+
return
|
86
88
|
agent.set_addon_prompt(
|
87
89
|
"如果有必要,请先指定出行动计划,然后根据计划一步步执行,如果任务过于复杂,可以拆分子Agent进行执行,拆的子Agent需要掌握所有必要的任务信息,否则无法执行"
|
88
90
|
)
|
89
91
|
agent.run(user_input)
|
92
|
+
except KeyboardInterrupt:
|
93
|
+
# 用户主动取消输入,正常退出
|
94
|
+
return
|
95
|
+
except typer.Exit:
|
96
|
+
# 来自输入流程的正常退出
|
97
|
+
return
|
90
98
|
except Exception as e:
|
91
99
|
PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
|
92
100
|
|
93
101
|
except typer.Exit:
|
94
|
-
|
102
|
+
return
|
95
103
|
except Exception as e:
|
96
104
|
PrettyOutput.print(f"初始化错误: {str(e)}", OutputType.ERROR)
|
97
105
|
raise typer.Exit(code=1)
|
{jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_agent/code_agent.py
RENAMED
@@ -52,8 +52,10 @@ class CodeAgent:
|
|
52
52
|
model_group: Optional[str] = None,
|
53
53
|
need_summary: bool = True,
|
54
54
|
append_tools: Optional[str] = None,
|
55
|
+
tool_group: Optional[str] = None,
|
55
56
|
):
|
56
57
|
self.root_dir = os.getcwd()
|
58
|
+
self.tool_group = tool_group
|
57
59
|
|
58
60
|
# 检测 git username 和 email 是否已设置
|
59
61
|
self._check_git_config()
|
@@ -233,18 +235,18 @@ class CodeAgent:
|
|
233
235
|
else:
|
234
236
|
print("ℹ️ .jarvis已在.gitignore中")
|
235
237
|
|
236
|
-
def _handle_git_changes(self) -> None:
|
238
|
+
def _handle_git_changes(self, prefix: str, suffix: str) -> None:
|
237
239
|
"""处理git仓库中的未提交修改"""
|
238
240
|
print("🔄 正在检查未提交的修改...")
|
239
241
|
if has_uncommitted_changes():
|
240
242
|
print("⏳ 发现未提交修改,正在处理...")
|
241
243
|
git_commiter = GitCommitTool()
|
242
|
-
git_commiter.execute({})
|
244
|
+
git_commiter.execute({"prefix": prefix, "suffix": suffix})
|
243
245
|
print("✅ 未提交修改已处理完成")
|
244
246
|
else:
|
245
247
|
print("✅ 没有未提交的修改")
|
246
248
|
|
247
|
-
def _init_env(self) -> None:
|
249
|
+
def _init_env(self, prefix: str, suffix: str) -> None:
|
248
250
|
"""初始化环境,组合以下功能:
|
249
251
|
1. 查找git根目录
|
250
252
|
2. 检查并更新.gitignore文件
|
@@ -254,7 +256,7 @@ class CodeAgent:
|
|
254
256
|
print("🚀 正在初始化环境...")
|
255
257
|
git_dir = self._find_git_root()
|
256
258
|
self._update_gitignore(git_dir)
|
257
|
-
self._handle_git_changes()
|
259
|
+
self._handle_git_changes(prefix, suffix)
|
258
260
|
# 配置git对换行符变化不敏感
|
259
261
|
self._configure_line_ending_settings()
|
260
262
|
print("✅ 环境初始化完成")
|
@@ -473,7 +475,11 @@ class CodeAgent:
|
|
473
475
|
return commits
|
474
476
|
|
475
477
|
def _handle_commit_confirmation(
|
476
|
-
self,
|
478
|
+
self,
|
479
|
+
commits: List[Tuple[str, str]],
|
480
|
+
start_commit: Optional[str],
|
481
|
+
prefix: str,
|
482
|
+
suffix: str,
|
477
483
|
) -> None:
|
478
484
|
"""处理提交确认和可能的重置"""
|
479
485
|
if commits and user_confirm("是否接受以上提交记录?", True):
|
@@ -489,7 +495,7 @@ class CodeAgent:
|
|
489
495
|
check=True,
|
490
496
|
)
|
491
497
|
git_commiter = GitCommitTool()
|
492
|
-
git_commiter.execute({})
|
498
|
+
git_commiter.execute({"prefix": prefix, "suffix": suffix})
|
493
499
|
|
494
500
|
# 在用户接受commit后,根据配置决定是否保存记忆
|
495
501
|
if self.agent.force_save_memory:
|
@@ -498,7 +504,7 @@ class CodeAgent:
|
|
498
504
|
os.system(f"git reset --hard {str(start_commit)}") # 确保转换为字符串
|
499
505
|
PrettyOutput.print("已重置到初始提交", OutputType.INFO)
|
500
506
|
|
501
|
-
def run(self, user_input: str) -> Optional[str]:
|
507
|
+
def run(self, user_input: str, prefix: str = "", suffix: str = "") -> Optional[str]:
|
502
508
|
"""使用给定的用户输入运行代码代理。
|
503
509
|
|
504
510
|
参数:
|
@@ -508,7 +514,7 @@ class CodeAgent:
|
|
508
514
|
str: 描述执行结果的输出,成功时返回None
|
509
515
|
"""
|
510
516
|
try:
|
511
|
-
self._init_env()
|
517
|
+
self._init_env(prefix, suffix)
|
512
518
|
start_commit = get_latest_commit_hash()
|
513
519
|
|
514
520
|
# 获取项目统计信息并附加到用户输入
|
@@ -557,7 +563,7 @@ class CodeAgent:
|
|
557
563
|
self._handle_uncommitted_changes()
|
558
564
|
end_commit = get_latest_commit_hash()
|
559
565
|
commits = self._show_commit_history(start_commit, end_commit)
|
560
|
-
self._handle_commit_confirmation(commits, start_commit)
|
566
|
+
self._handle_commit_confirmation(commits, start_commit, prefix, suffix)
|
561
567
|
return None
|
562
568
|
|
563
569
|
except RuntimeError as e:
|
@@ -660,6 +666,12 @@ def cli(
|
|
660
666
|
model_group: Optional[str] = typer.Option(
|
661
667
|
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
662
668
|
),
|
669
|
+
tool_group: Optional[str] = typer.Option(
|
670
|
+
None, "-G", "--tool-group", help="使用的工具组,覆盖配置文件中的设置"
|
671
|
+
),
|
672
|
+
config_file: Optional[str] = typer.Option(
|
673
|
+
None, "-f", "--config", help="配置文件路径"
|
674
|
+
),
|
663
675
|
requirement: Optional[str] = typer.Option(
|
664
676
|
None, "-r", "--requirement", help="要处理的需求描述"
|
665
677
|
),
|
@@ -671,9 +683,22 @@ def cli(
|
|
671
683
|
"--restore-session",
|
672
684
|
help="从 .jarvis/saved_session.json 恢复会话状态",
|
673
685
|
),
|
686
|
+
prefix: str = typer.Option(
|
687
|
+
"",
|
688
|
+
"--prefix",
|
689
|
+
help="提交信息前缀(用空格分隔)",
|
690
|
+
),
|
691
|
+
suffix: str = typer.Option(
|
692
|
+
"",
|
693
|
+
"--suffix",
|
694
|
+
help="提交信息后缀(用换行分隔)",
|
695
|
+
),
|
674
696
|
) -> None:
|
675
697
|
"""Jarvis主入口点。"""
|
676
|
-
init_env(
|
698
|
+
init_env(
|
699
|
+
"欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!",
|
700
|
+
config_file=config_file,
|
701
|
+
)
|
677
702
|
|
678
703
|
try:
|
679
704
|
subprocess.run(
|
@@ -717,6 +742,7 @@ def cli(
|
|
717
742
|
model_group=model_group,
|
718
743
|
need_summary=False,
|
719
744
|
append_tools=append_tools,
|
745
|
+
tool_group=tool_group,
|
720
746
|
)
|
721
747
|
|
722
748
|
# 尝试恢复会话
|
@@ -731,13 +757,13 @@ def cli(
|
|
731
757
|
)
|
732
758
|
|
733
759
|
if requirement:
|
734
|
-
agent.run(requirement)
|
760
|
+
agent.run(requirement, prefix=prefix, suffix=suffix)
|
735
761
|
else:
|
736
762
|
while True:
|
737
763
|
user_input = get_multiline_input("请输入你的需求(输入空行退出):")
|
738
764
|
if not user_input:
|
739
765
|
raise typer.Exit(code=0)
|
740
|
-
agent.run(user_input)
|
766
|
+
agent.run(user_input, prefix=prefix, suffix=suffix)
|
741
767
|
|
742
768
|
except typer.Exit:
|
743
769
|
raise
|
@@ -4,7 +4,7 @@ import threading
|
|
4
4
|
from typing import Any, Callable, Dict, List
|
5
5
|
from urllib.parse import urljoin
|
6
6
|
|
7
|
-
import requests
|
7
|
+
import requests # type: ignore[import-untyped]
|
8
8
|
|
9
9
|
from jarvis.jarvis_mcp import McpClient
|
10
10
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
@@ -25,6 +25,8 @@ class StreamableMcpClient(McpClient):
|
|
25
25
|
self.base_url = config.get("base_url", "")
|
26
26
|
if not self.base_url:
|
27
27
|
raise ValueError("No base_url specified in config")
|
28
|
+
# Normalize base_url to ensure trailing slash for urljoin correctness
|
29
|
+
self.base_url = self.base_url.rstrip("/") + "/"
|
28
30
|
|
29
31
|
# 设置HTTP客户端
|
30
32
|
self.session = requests.Session()
|
@@ -43,6 +45,8 @@ class StreamableMcpClient(McpClient):
|
|
43
45
|
# 添加额外的HTTP头
|
44
46
|
extra_headers = config.get("headers", {})
|
45
47
|
self.session.headers.update(extra_headers)
|
48
|
+
# Request timeouts (connect, read) in seconds; can be overridden via config["timeout"]
|
49
|
+
self.timeout = config.get("timeout", (10, 300))
|
46
50
|
|
47
51
|
# 请求相关属性
|
48
52
|
self.pending_requests: Dict[str, threading.Event] = {} # 存储等待响应的请求 {id: Event}
|
@@ -141,7 +145,9 @@ class StreamableMcpClient(McpClient):
|
|
141
145
|
|
142
146
|
# 发送请求到Streamable HTTP端点
|
143
147
|
mcp_url = urljoin(self.base_url, "mcp")
|
144
|
-
response = self.session.post(
|
148
|
+
response = self.session.post(
|
149
|
+
mcp_url, json=request, stream=True, timeout=self.timeout
|
150
|
+
) # 启用流式传输
|
145
151
|
response.raise_for_status()
|
146
152
|
|
147
153
|
# 处理流式响应
|
@@ -149,17 +155,21 @@ class StreamableMcpClient(McpClient):
|
|
149
155
|
for line in response.iter_lines(decode_unicode=True):
|
150
156
|
if line:
|
151
157
|
try:
|
152
|
-
|
158
|
+
line_data = line
|
159
|
+
if isinstance(line_data, str) and line_data.startswith("data:"):
|
160
|
+
# Handle SSE-formatted lines like "data: {...}"
|
161
|
+
line_data = line_data.split(":", 1)[1].strip()
|
162
|
+
data = json.loads(line_data)
|
153
163
|
if "id" in data and data["id"] == req_id:
|
154
164
|
# 这是我们的请求响应
|
155
165
|
result = data
|
156
166
|
break
|
157
167
|
elif "method" in data:
|
158
168
|
# 这是一个通知
|
159
|
-
|
169
|
+
notify_method = data.get("method", "")
|
160
170
|
params = data.get("params", {})
|
161
|
-
if
|
162
|
-
for handler in self.notification_handlers[
|
171
|
+
if notify_method in self.notification_handlers:
|
172
|
+
for handler in self.notification_handlers[notify_method]:
|
163
173
|
try:
|
164
174
|
handler(params)
|
165
175
|
except Exception as e:
|
@@ -171,6 +181,8 @@ class StreamableMcpClient(McpClient):
|
|
171
181
|
PrettyOutput.print(f"无法解析响应: {line}", OutputType.WARNING)
|
172
182
|
continue
|
173
183
|
|
184
|
+
# Ensure response is closed after streaming
|
185
|
+
response.close()
|
174
186
|
if result is None:
|
175
187
|
raise RuntimeError(f"未收到响应: {method}")
|
176
188
|
|
@@ -198,8 +210,9 @@ class StreamableMcpClient(McpClient):
|
|
198
210
|
|
199
211
|
# 发送通知到Streamable HTTP端点
|
200
212
|
mcp_url = urljoin(self.base_url, "mcp")
|
201
|
-
response = self.session.post(mcp_url, json=notification)
|
213
|
+
response = self.session.post(mcp_url, json=notification, timeout=self.timeout)
|
202
214
|
response.raise_for_status()
|
215
|
+
response.close()
|
203
216
|
|
204
217
|
except Exception as e:
|
205
218
|
PrettyOutput.print(f"发送通知失败: {str(e)}", OutputType.ERROR)
|
{jarvis_ai_assistant-0.3.14 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_multi_agent/main.py
RENAMED
@@ -2,7 +2,7 @@
|
|
2
2
|
from typing import Optional
|
3
3
|
|
4
4
|
import typer
|
5
|
-
import yaml
|
5
|
+
import yaml # type: ignore[import-untyped]
|
6
6
|
|
7
7
|
from jarvis.jarvis_multi_agent import MultiAgent
|
8
8
|
from jarvis.jarvis_utils.input import get_multiline_input
|
@@ -15,7 +15,9 @@ app = typer.Typer(help="多智能体系统启动器")
|
|
15
15
|
@app.command()
|
16
16
|
def cli(
|
17
17
|
config: str = typer.Option(..., "--config", "-c", help="YAML配置文件路径"),
|
18
|
-
user_input: Optional[str] = typer.Option(
|
18
|
+
user_input: Optional[str] = typer.Option(
|
19
|
+
None, "--input", "-i", help="用户输入(可选)"
|
20
|
+
),
|
19
21
|
):
|
20
22
|
"""从YAML配置文件初始化并运行多智能体系统"""
|
21
23
|
init_env("欢迎使用 Jarvis-MultiAgent,您的多智能体系统已准备就绪!")
|
@@ -39,11 +41,13 @@ def cli(
|
|
39
41
|
else get_multiline_input("请输入内容(输入空行结束):")
|
40
42
|
)
|
41
43
|
if not final_input:
|
42
|
-
|
44
|
+
return
|
43
45
|
multi_agent.run(final_input)
|
44
46
|
|
47
|
+
except KeyboardInterrupt:
|
48
|
+
return
|
45
49
|
except typer.Exit:
|
46
|
-
|
50
|
+
return
|
47
51
|
except (ValueError, RuntimeError, yaml.YAMLError) as e:
|
48
52
|
PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
|
49
53
|
raise typer.Exit(code=1)
|