jarvis-ai-assistant 0.3.15__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.15/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.3.16}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/pyproject.toml +1 -1
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/setup.py +1 -1
- {jarvis_ai_assistant-0.3.15 → 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.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/main.py +18 -10
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_agent/code_agent.py +15 -9
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_multi_agent/main.py +8 -4
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/base.py +10 -1
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/registry.py +37 -11
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
- jarvis_ai_assistant-0.3.15/src/jarvis/jarvis_agent/jarvis.py +0 -94
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/README.md +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/agent_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/config_editor.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/edit_file_handler.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/file_methodology_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/memory_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/methodology_share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/prompt_builder.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/prompts.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/protocols.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/session_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/task_analyzer.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/task_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/tool_executor.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_agent/tool_share_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_agent/lint.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_data/config_schema.json +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_git_squash/main.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_git_utils/git_commiter.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_mcp/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_memory_organizer/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_memory_organizer/memory_organizer.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_methodology/main.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/ai8.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/base.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/human.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/kimi.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/tongyi.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform_manager/main.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_platform_manager/service.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/cache.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/cli.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/embedding_manager.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/llm_interface.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/query_rewriter.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/rag_pipeline.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/reranker.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_rag/retriever.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_smart_shell/main.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/cli.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/stats.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/storage.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_stats/visualizer.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/clear_memory.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/cli/main.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/edit_file.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/execute_script.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/read_code.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/retrieve_memory.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/save_memory.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/search_web.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/__init__.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/clipboard.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/config.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/embedding.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/file_processors.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/git_utils.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/globals.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/http.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/input.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/methodology.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/output.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/tag.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_utils/utils.py +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
- {jarvis_ai_assistant-0.3.15 → 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.15 → 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()
|
@@ -239,10 +241,7 @@ class CodeAgent:
|
|
239
241
|
if has_uncommitted_changes():
|
240
242
|
print("⏳ 发现未提交修改,正在处理...")
|
241
243
|
git_commiter = GitCommitTool()
|
242
|
-
git_commiter.execute({
|
243
|
-
"prefix": prefix,
|
244
|
-
"suffix": suffix
|
245
|
-
})
|
244
|
+
git_commiter.execute({"prefix": prefix, "suffix": suffix})
|
246
245
|
print("✅ 未提交修改已处理完成")
|
247
246
|
else:
|
248
247
|
print("✅ 没有未提交的修改")
|
@@ -496,10 +495,7 @@ class CodeAgent:
|
|
496
495
|
check=True,
|
497
496
|
)
|
498
497
|
git_commiter = GitCommitTool()
|
499
|
-
git_commiter.execute({
|
500
|
-
"prefix": prefix,
|
501
|
-
"suffix": suffix
|
502
|
-
})
|
498
|
+
git_commiter.execute({"prefix": prefix, "suffix": suffix})
|
503
499
|
|
504
500
|
# 在用户接受commit后,根据配置决定是否保存记忆
|
505
501
|
if self.agent.force_save_memory:
|
@@ -670,6 +666,12 @@ def cli(
|
|
670
666
|
model_group: Optional[str] = typer.Option(
|
671
667
|
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
672
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
|
+
),
|
673
675
|
requirement: Optional[str] = typer.Option(
|
674
676
|
None, "-r", "--requirement", help="要处理的需求描述"
|
675
677
|
),
|
@@ -693,7 +695,10 @@ def cli(
|
|
693
695
|
),
|
694
696
|
) -> None:
|
695
697
|
"""Jarvis主入口点。"""
|
696
|
-
init_env(
|
698
|
+
init_env(
|
699
|
+
"欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!",
|
700
|
+
config_file=config_file,
|
701
|
+
)
|
697
702
|
|
698
703
|
try:
|
699
704
|
subprocess.run(
|
@@ -737,6 +742,7 @@ def cli(
|
|
737
742
|
model_group=model_group,
|
738
743
|
need_summary=False,
|
739
744
|
append_tools=append_tools,
|
745
|
+
tool_group=tool_group,
|
740
746
|
)
|
741
747
|
|
742
748
|
# 尝试恢复会话
|
{jarvis_ai_assistant-0.3.15 → 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)
|
@@ -6,7 +6,14 @@ from typing import Any, Callable, Dict
|
|
6
6
|
class Tool:
|
7
7
|
"""工具类,用于封装工具的基本信息和执行方法"""
|
8
8
|
|
9
|
-
def __init__(
|
9
|
+
def __init__(
|
10
|
+
self,
|
11
|
+
name: str,
|
12
|
+
description: str,
|
13
|
+
parameters: Dict,
|
14
|
+
func: Callable,
|
15
|
+
protocol_version: str = "1.0",
|
16
|
+
):
|
10
17
|
"""
|
11
18
|
初始化工具对象
|
12
19
|
|
@@ -15,11 +22,13 @@ class Tool:
|
|
15
22
|
description (str): 工具描述
|
16
23
|
parameters (Dict): 工具参数定义
|
17
24
|
func (Callable): 工具执行函数
|
25
|
+
protocol_version (str): 工具协议版本,默认"1.0";支持"1.0"或"2.0"
|
18
26
|
"""
|
19
27
|
self.name = name
|
20
28
|
self.description = description
|
21
29
|
self.parameters = parameters
|
22
30
|
self.func = func
|
31
|
+
self.protocol_version = protocol_version
|
23
32
|
|
24
33
|
def to_dict(self) -> Dict:
|
25
34
|
"""将工具对象转换为字典格式,主要用于序列化"""
|
{jarvis_ai_assistant-0.3.15 → jarvis_ai_assistant-0.3.16}/src/jarvis/jarvis_tools/registry.py
RENAMED
@@ -7,7 +7,7 @@ import tempfile
|
|
7
7
|
from pathlib import Path
|
8
8
|
from typing import Any, Callable, Dict, List, Optional, Protocol, Tuple
|
9
9
|
|
10
|
-
import yaml
|
10
|
+
import yaml # type: ignore[import-untyped]
|
11
11
|
|
12
12
|
from jarvis.jarvis_mcp import McpClient
|
13
13
|
from jarvis.jarvis_mcp.sse_mcp_client import SSEMcpClient
|
@@ -32,6 +32,7 @@ tool_call_help = f"""
|
|
32
32
|
{ot("TOOL_CALL")}
|
33
33
|
want: 想要从执行结果中获取到的信息,如果工具输出内容过长,会根据此字段尝试提取有效信息
|
34
34
|
name: 工具名称
|
35
|
+
|
35
36
|
arguments:
|
36
37
|
param1: 值1
|
37
38
|
param2: 值2
|
@@ -77,6 +78,7 @@ arguments:
|
|
77
78
|
{ot("TOOL_CALL")}
|
78
79
|
want: 当前的git状态,期望获取xxx的提交记录
|
79
80
|
name: execute_script
|
81
|
+
|
80
82
|
arguments:
|
81
83
|
interpreter: bash
|
82
84
|
script_content: |2
|
@@ -595,6 +597,9 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
595
597
|
description=tool_instance.description,
|
596
598
|
parameters=tool_instance.parameters,
|
597
599
|
func=tool_instance.execute,
|
600
|
+
protocol_version=getattr(
|
601
|
+
tool_instance, "protocol_version", "1.0"
|
602
|
+
),
|
598
603
|
)
|
599
604
|
tool_found = True
|
600
605
|
break
|
@@ -630,7 +635,7 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
630
635
|
content: 包含工具调用的内容
|
631
636
|
|
632
637
|
返回:
|
633
|
-
Tuple[Dict[str, Dict[str, Any]], str]:
|
638
|
+
Tuple[Dict[str, Dict[str, Any]], str]:
|
634
639
|
- 第一个元素是提取的工具调用字典
|
635
640
|
- 第二个元素是错误消息字符串(成功时为"")
|
636
641
|
|
@@ -708,6 +713,7 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
708
713
|
description: str,
|
709
714
|
parameters: Any,
|
710
715
|
func: Callable[..., Dict[str, Any]],
|
716
|
+
protocol_version: str = "1.0",
|
711
717
|
) -> None:
|
712
718
|
"""注册新工具
|
713
719
|
|
@@ -721,7 +727,7 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
721
727
|
PrettyOutput.print(
|
722
728
|
f"警告: 工具 '{name}' 已存在,将被覆盖", OutputType.WARNING
|
723
729
|
)
|
724
|
-
self.tools[name] = Tool(name, description, parameters, func)
|
730
|
+
self.tools[name] = Tool(name, description, parameters, func, protocol_version)
|
725
731
|
|
726
732
|
def get_tool(self, name: str) -> Optional[Tool]:
|
727
733
|
"""获取工具
|
@@ -742,12 +748,15 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
742
748
|
"""
|
743
749
|
return [tool.to_dict() for tool in self.tools.values()]
|
744
750
|
|
745
|
-
def execute_tool(
|
751
|
+
def execute_tool(
|
752
|
+
self, name: str, arguments: Dict[str, Any], agent: Optional[Any] = None
|
753
|
+
) -> Dict[str, Any]:
|
746
754
|
"""执行指定工具
|
747
755
|
|
748
756
|
参数:
|
749
757
|
name: 工具名称
|
750
758
|
arguments: 工具参数
|
759
|
+
agent: 智能体实例(由系统内部传递,用于v2.0分离agent与参数)
|
751
760
|
|
752
761
|
返回:
|
753
762
|
Dict[str, Any]: 包含执行结果的字典,包含success、stdout和stderr字段
|
@@ -763,7 +772,23 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
763
772
|
# 更新工具调用统计
|
764
773
|
self._update_tool_stats(name)
|
765
774
|
|
766
|
-
|
775
|
+
# 根据工具实现声明的协议版本分发调用方式
|
776
|
+
try:
|
777
|
+
if getattr(tool, "protocol_version", "1.0") == "2.0":
|
778
|
+
# v2.0: agent与参数分离传递
|
779
|
+
return tool.func(arguments, agent) # type: ignore[misc]
|
780
|
+
else:
|
781
|
+
# v1.0: 兼容旧实现,将agent注入到arguments(如果提供)
|
782
|
+
args_to_call = arguments.copy() if isinstance(arguments, dict) else {}
|
783
|
+
if agent is not None:
|
784
|
+
args_to_call["agent"] = agent
|
785
|
+
return tool.execute(args_to_call)
|
786
|
+
except TypeError:
|
787
|
+
# 兼容处理:如果函数签名不匹配,回退到旧方式
|
788
|
+
args_to_call = arguments.copy() if isinstance(arguments, dict) else {}
|
789
|
+
if agent is not None:
|
790
|
+
args_to_call["agent"] = agent
|
791
|
+
return tool.execute(args_to_call)
|
767
792
|
|
768
793
|
def _format_tool_output(self, stdout: str, stderr: str) -> str:
|
769
794
|
"""格式化工具输出为可读字符串
|
@@ -802,14 +827,14 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
802
827
|
def handle_tool_calls(self, tool_call: Dict[str, Any], agent: Any) -> str:
|
803
828
|
try:
|
804
829
|
name = tool_call["name"] # 确保name是str类型
|
805
|
-
args = tool_call["arguments"] #
|
830
|
+
args = tool_call["arguments"] # 原始参数(来自外部协议)
|
806
831
|
want = tool_call["want"]
|
807
|
-
args["agent"] = agent
|
808
832
|
|
809
833
|
from jarvis.jarvis_agent import Agent
|
810
834
|
|
811
835
|
agent_instance: Agent = agent
|
812
836
|
|
837
|
+
# 如果args是字符串,尝试解析为JSON
|
813
838
|
if isinstance(args, str):
|
814
839
|
try:
|
815
840
|
args = json.loads(args)
|
@@ -819,8 +844,8 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
819
844
|
)
|
820
845
|
return ""
|
821
846
|
|
822
|
-
#
|
823
|
-
result = self.execute_tool(name, args)
|
847
|
+
# 执行工具调用(根据工具实现的协议版本,由系统在内部决定agent的传递方式)
|
848
|
+
result = self.execute_tool(name, args, agent)
|
824
849
|
|
825
850
|
# 格式化输出
|
826
851
|
output = self._format_tool_output(
|
@@ -853,8 +878,9 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
853
878
|
[output_file]
|
854
879
|
)
|
855
880
|
if upload_success:
|
856
|
-
# 删除args的agent
|
857
|
-
args
|
881
|
+
# 删除args的agent键(保持协议v2.0的“参数与agent分离”在可视化中的一致性)
|
882
|
+
if isinstance(args, dict):
|
883
|
+
args.pop("agent", None)
|
858
884
|
prompt = f"""
|
859
885
|
以下是之前对话的关键信息总结:
|
860
886
|
|