jarvis-ai-assistant 0.1.41__py3-none-any.whl → 0.1.43__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/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/__pycache__/agent.cpython-313.pyc +0 -0
- jarvis/__pycache__/main.cpython-313.pyc +0 -0
- jarvis/agent.py +2 -2
- jarvis/main.py +3 -3
- jarvis/models/__init__.py +2 -2
- jarvis/models/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/ai8.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/base.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/kimi.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/openai.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/oyi.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/registry.cpython-313.pyc +0 -0
- jarvis/models/ai8.py +11 -7
- jarvis/models/base.py +5 -2
- jarvis/models/kimi.py +22 -18
- jarvis/models/openai.py +7 -3
- jarvis/models/oyi.py +11 -7
- jarvis/models/registry.py +83 -79
- jarvis/tools/__pycache__/generator.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/registry.cpython-313.pyc +0 -0
- jarvis/tools/generator.py +7 -2
- jarvis/tools/registry.py +1 -1
- {jarvis_ai_assistant-0.1.41.dist-info → jarvis_ai_assistant-0.1.43.dist-info}/METADATA +18 -17
- {jarvis_ai_assistant-0.1.41.dist-info → jarvis_ai_assistant-0.1.43.dist-info}/RECORD +30 -30
- {jarvis_ai_assistant-0.1.41.dist-info → jarvis_ai_assistant-0.1.43.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.41.dist-info → jarvis_ai_assistant-0.1.43.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.41.dist-info → jarvis_ai_assistant-0.1.43.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.41.dist-info → jarvis_ai_assistant-0.1.43.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
Binary file
|
Binary file
|
Binary file
|
jarvis/agent.py
CHANGED
@@ -3,7 +3,7 @@ from typing import Dict, List, Optional
|
|
3
3
|
|
4
4
|
import yaml
|
5
5
|
|
6
|
-
from .models.registry import
|
6
|
+
from .models.registry import PlatformRegistry
|
7
7
|
from .tools import ToolRegistry
|
8
8
|
from .utils import PrettyOutput, OutputType, get_multiline_input, while_success
|
9
9
|
import os
|
@@ -20,7 +20,7 @@ class Agent:
|
|
20
20
|
name: Agent名称,默认为"Jarvis"
|
21
21
|
is_sub_agent: 是否为子Agent,默认为False
|
22
22
|
"""
|
23
|
-
self.model =
|
23
|
+
self.model = PlatformRegistry.get_global_platform()
|
24
24
|
self.tool_registry = ToolRegistry.get_global_tool_registry()
|
25
25
|
self.name = name
|
26
26
|
self.is_sub_agent = is_sub_agent
|
jarvis/main.py
CHANGED
@@ -8,7 +8,7 @@ import sys
|
|
8
8
|
from pathlib import Path
|
9
9
|
from prompt_toolkit import prompt
|
10
10
|
|
11
|
-
from jarvis.models.registry import
|
11
|
+
from jarvis.models.registry import PlatformRegistry
|
12
12
|
|
13
13
|
# 添加父目录到Python路径以支持导入
|
14
14
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
@@ -114,14 +114,14 @@ def main():
|
|
114
114
|
PrettyOutput.print("未指定AI平台,请使用 -p 参数或者设置 JARVIS_PLATFORM 环境变量", OutputType.ERROR)
|
115
115
|
return 1
|
116
116
|
|
117
|
-
|
117
|
+
PlatformRegistry.get_global_platform_registry().set_global_platform_name(platform)
|
118
118
|
|
119
119
|
try:
|
120
120
|
# 获取全局模型实例
|
121
121
|
agent = Agent()
|
122
122
|
|
123
123
|
# 欢迎信息
|
124
|
-
PrettyOutput.print(f"Jarvis 已初始化 - With {platform}
|
124
|
+
PrettyOutput.print(f"Jarvis 已初始化 - With {platform} 平台,模型: {agent.model.name()}", OutputType.SYSTEM)
|
125
125
|
if args.keep_history:
|
126
126
|
PrettyOutput.print("已启用历史保留模式", OutputType.INFO)
|
127
127
|
|
jarvis/models/__init__.py
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
from .base import
|
1
|
+
from .base import BasePlatform
|
2
2
|
|
3
|
-
__all__ = ['
|
3
|
+
__all__ = ['BasePlatform']
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
jarvis/models/ai8.py
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
import os
|
2
2
|
from typing import Dict, List
|
3
|
-
from jarvis.models.base import
|
3
|
+
from jarvis.models.base import BasePlatform
|
4
4
|
from jarvis.utils import PrettyOutput, OutputType
|
5
5
|
import requests
|
6
6
|
import json
|
7
7
|
import base64
|
8
8
|
|
9
|
-
class AI8Model(
|
9
|
+
class AI8Model(BasePlatform):
|
10
10
|
"""AI8 model implementation"""
|
11
11
|
|
12
|
-
|
12
|
+
platform_name = "ai8"
|
13
13
|
BASE_URL = "https://ai8.rcouyi.com"
|
14
14
|
|
15
15
|
def __init__(self):
|
@@ -62,11 +62,15 @@ class AI8Model(BaseModel):
|
|
62
62
|
self.system_message = ""
|
63
63
|
self.conversation = None
|
64
64
|
self.files = []
|
65
|
-
self.
|
65
|
+
self.model_name = os.getenv("AI8_MODEL") or "deepseek-chat"
|
66
66
|
self.token = os.getenv("AI8_API_KEY")
|
67
|
-
if not all([self.
|
67
|
+
if not all([self.model_name, self.token]):
|
68
68
|
raise Exception("AI8_MODEL or AI8_API_KEY is not set")
|
69
|
-
PrettyOutput.print(f"当前使用模型: {self.
|
69
|
+
PrettyOutput.print(f"当前使用模型: {self.model_name}", OutputType.SYSTEM)
|
70
|
+
|
71
|
+
def set_model_name(self, model_name: str):
|
72
|
+
"""设置模型名称"""
|
73
|
+
self.model_name = model_name
|
70
74
|
|
71
75
|
def create_conversation(self) -> bool:
|
72
76
|
"""Create a new conversation"""
|
@@ -102,7 +106,7 @@ class AI8Model(BaseModel):
|
|
102
106
|
# 2. 更新会话设置
|
103
107
|
session_data = {
|
104
108
|
**self.conversation,
|
105
|
-
"model": self.
|
109
|
+
"model": self.model_name,
|
106
110
|
"contextCount": 1024,
|
107
111
|
"prompt": self.system_message,
|
108
112
|
"plugins": ["tavily_search"],
|
jarvis/models/base.py
CHANGED
@@ -3,14 +3,17 @@ from typing import Dict, List
|
|
3
3
|
from ..utils import OutputType, PrettyOutput
|
4
4
|
|
5
5
|
|
6
|
-
class
|
6
|
+
class BasePlatform(ABC):
|
7
7
|
"""大语言模型基类"""
|
8
8
|
|
9
9
|
def __init__(self):
|
10
10
|
"""初始化模型"""
|
11
11
|
pass
|
12
|
+
|
13
|
+
def set_model_name(self, model_name: str):
|
14
|
+
"""设置模型名称"""
|
15
|
+
raise NotImplementedError("set_model_name is not implemented")
|
12
16
|
|
13
|
-
|
14
17
|
@abstractmethod
|
15
18
|
def chat(self, message: str) -> str:
|
16
19
|
"""执行对话"""
|
jarvis/models/kimi.py
CHANGED
@@ -4,14 +4,14 @@ import json
|
|
4
4
|
import os
|
5
5
|
import mimetypes
|
6
6
|
import time
|
7
|
-
from jarvis.models.base import
|
7
|
+
from jarvis.models.base import BasePlatform
|
8
8
|
from jarvis.utils import PrettyOutput, OutputType
|
9
9
|
from jarvis.utils import while_success
|
10
10
|
|
11
|
-
class KimiModel(
|
11
|
+
class KimiModel(BasePlatform):
|
12
12
|
"""Kimi模型实现"""
|
13
13
|
|
14
|
-
|
14
|
+
platform_name = "kimi"
|
15
15
|
|
16
16
|
def __init__(self):
|
17
17
|
"""
|
@@ -19,21 +19,21 @@ class KimiModel(BaseModel):
|
|
19
19
|
"""
|
20
20
|
self.api_key = os.getenv("KIMI_API_KEY")
|
21
21
|
if not self.api_key:
|
22
|
-
PrettyOutput.
|
23
|
-
PrettyOutput.
|
24
|
-
PrettyOutput.
|
25
|
-
PrettyOutput.
|
26
|
-
PrettyOutput.
|
27
|
-
PrettyOutput.
|
28
|
-
PrettyOutput.
|
29
|
-
PrettyOutput.
|
30
|
-
PrettyOutput.
|
31
|
-
PrettyOutput.
|
32
|
-
PrettyOutput.
|
33
|
-
PrettyOutput.
|
34
|
-
PrettyOutput.
|
35
|
-
PrettyOutput.
|
36
|
-
PrettyOutput.
|
22
|
+
PrettyOutput.print("\n需要设置 KIMI_API_KEY 才能使用 Jarvis。请按以下步骤操作:", OutputType.INFO)
|
23
|
+
PrettyOutput.print("\n1. 获取 Kimi API Key:", OutputType.INFO)
|
24
|
+
PrettyOutput.print(" • 访问 Kimi AI 平台: https://kimi.moonshot.cn", OutputType.INFO)
|
25
|
+
PrettyOutput.print(" • 登录您的账号", OutputType.INFO)
|
26
|
+
PrettyOutput.print(" • 打开浏览器开发者工具 (F12 或右键 -> 检查)", OutputType.INFO)
|
27
|
+
PrettyOutput.print(" • 切换到 Network 标签页", OutputType.INFO)
|
28
|
+
PrettyOutput.print(" • 发送任意消息", OutputType.INFO)
|
29
|
+
PrettyOutput.print(" • 在请求中找到 Authorization 头部", OutputType.INFO)
|
30
|
+
PrettyOutput.print(" • 复制 token 值(去掉 'Bearer ' 前缀)", OutputType.INFO)
|
31
|
+
PrettyOutput.print("\n2. 设置环境变量:", OutputType.INFO)
|
32
|
+
PrettyOutput.print(" 方法 1: 创建或编辑 ~/.jarvis_env 文件:", OutputType.INFO)
|
33
|
+
PrettyOutput.print(" echo 'KIMI_API_KEY=your_key_here' > ~/.jarvis_env", OutputType.INFO)
|
34
|
+
PrettyOutput.print("\n 方法 2: 直接设置环境变量:", OutputType.INFO)
|
35
|
+
PrettyOutput.print(" export KIMI_API_KEY=your_key_here", OutputType.INFO)
|
36
|
+
PrettyOutput.print("\n设置完成后重新运行 Jarvis。", OutputType.INFO)
|
37
37
|
raise Exception("KIMI_API_KEY is not set")
|
38
38
|
self.auth_header = f"Bearer {self.api_key}"
|
39
39
|
self.chat_id = ""
|
@@ -45,6 +45,10 @@ class KimiModel(BaseModel):
|
|
45
45
|
"""设置系统消息"""
|
46
46
|
self.system_message = message
|
47
47
|
|
48
|
+
def set_model_name(self, model_name: str):
|
49
|
+
"""设置模型名称"""
|
50
|
+
pass
|
51
|
+
|
48
52
|
def _create_chat(self) -> bool:
|
49
53
|
"""创建新的对话会话"""
|
50
54
|
url = "https://kimi.moonshot.cn/api/chat"
|
jarvis/models/openai.py
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
from typing import Dict, List
|
2
2
|
import os
|
3
3
|
from openai import OpenAI
|
4
|
-
from jarvis.models.base import
|
4
|
+
from jarvis.models.base import BasePlatform
|
5
5
|
from jarvis.utils import PrettyOutput, OutputType
|
6
6
|
|
7
|
-
class OpenAIModel(
|
7
|
+
class OpenAIModel(BasePlatform):
|
8
8
|
"""DeepSeek模型实现"""
|
9
9
|
|
10
|
-
|
10
|
+
platform_name = "openai"
|
11
11
|
|
12
12
|
def __init__(self):
|
13
13
|
"""
|
@@ -41,6 +41,10 @@ class OpenAIModel(BaseModel):
|
|
41
41
|
self.messages: List[Dict[str, str]] = []
|
42
42
|
self.system_message = ""
|
43
43
|
|
44
|
+
def set_model_name(self, model_name: str):
|
45
|
+
"""设置模型名称"""
|
46
|
+
self.model_name = model_name
|
47
|
+
|
44
48
|
def set_system_message(self, message: str):
|
45
49
|
"""设置系统消息"""
|
46
50
|
self.system_message = message
|
jarvis/models/oyi.py
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
import mimetypes
|
2
2
|
import os
|
3
3
|
from typing import Dict, List
|
4
|
-
from jarvis.models.base import
|
4
|
+
from jarvis.models.base import BasePlatform
|
5
5
|
from jarvis.utils import PrettyOutput, OutputType
|
6
6
|
import requests
|
7
7
|
import json
|
8
8
|
|
9
|
-
class OyiModel(
|
9
|
+
class OyiModel(BasePlatform):
|
10
10
|
"""Oyi model implementation"""
|
11
11
|
|
12
|
-
|
12
|
+
platform_name = "oyi"
|
13
13
|
BASE_URL = "https://api-10086.rcouyi.com"
|
14
14
|
|
15
15
|
def __init__(self):
|
@@ -47,11 +47,15 @@ class OyiModel(BaseModel):
|
|
47
47
|
self.conversation = None
|
48
48
|
self.upload_files = []
|
49
49
|
self.first_chat = True
|
50
|
-
self.
|
50
|
+
self.model_name = os.getenv("OYI_MODEL") or "deepseek-chat"
|
51
51
|
self.token = os.getenv("OYI_API_KEY")
|
52
|
-
if not all([self.
|
52
|
+
if not all([self.model_name, self.token]):
|
53
53
|
raise Exception("OYI_MODEL or OYI_API_KEY is not set")
|
54
|
-
PrettyOutput.print(f"当前使用模型: {self.
|
54
|
+
PrettyOutput.print(f"当前使用模型: {self.model_name}", OutputType.SYSTEM)
|
55
|
+
|
56
|
+
def set_model_name(self, model_name: str):
|
57
|
+
"""设置模型名称"""
|
58
|
+
self.model_name = model_name
|
55
59
|
|
56
60
|
|
57
61
|
def create_conversation(self) -> bool:
|
@@ -71,7 +75,7 @@ class OyiModel(BaseModel):
|
|
71
75
|
"isLock": False,
|
72
76
|
"systemMessage": "",
|
73
77
|
"params": json.dumps({
|
74
|
-
"model":
|
78
|
+
"model": self.model_name,
|
75
79
|
"is_webSearch": True,
|
76
80
|
"message": [],
|
77
81
|
"systemMessage": None,
|
jarvis/models/registry.py
CHANGED
@@ -3,7 +3,7 @@ import inspect
|
|
3
3
|
import os
|
4
4
|
import sys
|
5
5
|
from typing import Dict, Type, Optional, List
|
6
|
-
from .base import
|
6
|
+
from .base import BasePlatform
|
7
7
|
from ..utils import PrettyOutput, OutputType
|
8
8
|
|
9
9
|
REQUIRED_METHODS = [
|
@@ -14,33 +14,33 @@ REQUIRED_METHODS = [
|
|
14
14
|
('set_system_message', ['message'])
|
15
15
|
]
|
16
16
|
|
17
|
-
class
|
18
|
-
"""
|
17
|
+
class PlatformRegistry:
|
18
|
+
"""平台注册器"""
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
global_platform_name = "kimi"
|
21
|
+
global_platform_registry = None
|
22
22
|
|
23
23
|
@staticmethod
|
24
|
-
def
|
25
|
-
|
26
|
-
if not os.path.exists(
|
24
|
+
def get_platform_dir() -> str:
|
25
|
+
user_platform_dir = os.path.expanduser("~/.jarvis_models")
|
26
|
+
if not os.path.exists(user_platform_dir):
|
27
27
|
try:
|
28
|
-
os.makedirs(
|
28
|
+
os.makedirs(user_platform_dir)
|
29
29
|
# 创建 __init__.py 使其成为 Python 包
|
30
|
-
with open(os.path.join(
|
30
|
+
with open(os.path.join(user_platform_dir, "__init__.py"), "w") as f:
|
31
31
|
pass
|
32
|
-
PrettyOutput.print(f"
|
32
|
+
PrettyOutput.print(f"已创建平台目录: {user_platform_dir}", OutputType.INFO)
|
33
33
|
except Exception as e:
|
34
|
-
PrettyOutput.print(f"
|
34
|
+
PrettyOutput.print(f"创建平台目录失败: {str(e)}", OutputType.ERROR)
|
35
35
|
return ""
|
36
|
-
return
|
36
|
+
return user_platform_dir
|
37
37
|
|
38
38
|
@staticmethod
|
39
|
-
def
|
40
|
-
"""
|
39
|
+
def check_platform_implementation(platform_class: Type[BasePlatform]) -> bool:
|
40
|
+
"""检查平台类是否实现了所有必要的方法
|
41
41
|
|
42
42
|
Args:
|
43
|
-
|
43
|
+
platform_class: 要检查的平台类
|
44
44
|
|
45
45
|
Returns:
|
46
46
|
bool: 是否实现了所有必要的方法
|
@@ -48,11 +48,11 @@ class ModelRegistry:
|
|
48
48
|
missing_methods = []
|
49
49
|
|
50
50
|
for method_name, params in REQUIRED_METHODS:
|
51
|
-
if not hasattr(
|
51
|
+
if not hasattr(platform_class, method_name):
|
52
52
|
missing_methods.append(method_name)
|
53
53
|
continue
|
54
54
|
|
55
|
-
method = getattr(
|
55
|
+
method = getattr(platform_class, method_name)
|
56
56
|
if not callable(method):
|
57
57
|
missing_methods.append(method_name)
|
58
58
|
continue
|
@@ -66,7 +66,7 @@ class ModelRegistry:
|
|
66
66
|
|
67
67
|
if missing_methods:
|
68
68
|
PrettyOutput.print(
|
69
|
-
f"
|
69
|
+
f"平台 {platform_class.__name__} 缺少必要的方法: {', '.join(missing_methods)}",
|
70
70
|
OutputType.ERROR
|
71
71
|
)
|
72
72
|
return False
|
@@ -74,21 +74,21 @@ class ModelRegistry:
|
|
74
74
|
return True
|
75
75
|
|
76
76
|
@staticmethod
|
77
|
-
def
|
78
|
-
"""
|
77
|
+
def load_platform_from_dir(directory: str) -> Dict[str, Type[BasePlatform]]:
|
78
|
+
"""从指定目录加载平台
|
79
79
|
|
80
80
|
Args:
|
81
|
-
directory:
|
81
|
+
directory: 平台目录路径
|
82
82
|
|
83
83
|
Returns:
|
84
|
-
Dict[str, Type[BaseModel]]:
|
84
|
+
Dict[str, Type[BaseModel]]: 平台名称到平台类的映射
|
85
85
|
"""
|
86
|
-
|
86
|
+
platforms = {}
|
87
87
|
|
88
88
|
# 确保目录存在
|
89
89
|
if not os.path.exists(directory):
|
90
|
-
PrettyOutput.print(f"
|
91
|
-
return
|
90
|
+
PrettyOutput.print(f"平台目录不存在: {directory}", OutputType.ERROR)
|
91
|
+
return platforms
|
92
92
|
|
93
93
|
# 获取目录的包名
|
94
94
|
package_name = None
|
@@ -114,86 +114,90 @@ class ModelRegistry:
|
|
114
114
|
for name, obj in inspect.getmembers(module):
|
115
115
|
# 检查是否是BaseModel的子类,但不是BaseModel本身
|
116
116
|
if (inspect.isclass(obj) and
|
117
|
-
issubclass(obj,
|
118
|
-
obj !=
|
119
|
-
hasattr(obj, '
|
120
|
-
#
|
121
|
-
if not
|
117
|
+
issubclass(obj, BasePlatform) and
|
118
|
+
obj != BasePlatform and
|
119
|
+
hasattr(obj, 'platform_name')):
|
120
|
+
# 检查平台实现
|
121
|
+
if not PlatformRegistry.check_platform_implementation(obj):
|
122
122
|
continue
|
123
|
-
|
124
|
-
PrettyOutput.print(f"从 {directory}
|
123
|
+
platforms[obj.platform_name] = obj
|
124
|
+
PrettyOutput.print(f"从 {directory} 加载平台: {obj.platform_name}", OutputType.INFO)
|
125
125
|
break
|
126
126
|
except Exception as e:
|
127
|
-
PrettyOutput.print(f"
|
127
|
+
PrettyOutput.print(f"加载平台 {module_name} 失败: {str(e)}", OutputType.ERROR)
|
128
128
|
|
129
|
-
return
|
129
|
+
return platforms
|
130
130
|
|
131
131
|
|
132
132
|
@staticmethod
|
133
|
-
def
|
134
|
-
"""
|
135
|
-
if
|
136
|
-
|
133
|
+
def get_global_platform_registry():
|
134
|
+
"""获取全局平台注册器"""
|
135
|
+
if PlatformRegistry.global_platform_registry is None:
|
136
|
+
PlatformRegistry.global_platform_registry = PlatformRegistry()
|
137
137
|
|
138
|
-
#
|
139
|
-
|
140
|
-
if
|
141
|
-
for
|
142
|
-
|
143
|
-
|
144
|
-
if
|
145
|
-
for
|
146
|
-
|
147
|
-
return
|
138
|
+
# 从用户平台目录加载额外平台
|
139
|
+
platform_dir = PlatformRegistry.get_platform_dir()
|
140
|
+
if platform_dir and os.path.exists(platform_dir):
|
141
|
+
for platform_name, platform_class in PlatformRegistry.load_platform_from_dir(platform_dir).items():
|
142
|
+
PlatformRegistry.global_platform_registry.register_platform(platform_name, platform_class)
|
143
|
+
platform_dir = os.path.dirname(__file__)
|
144
|
+
if platform_dir and os.path.exists(platform_dir):
|
145
|
+
for platform_name, platform_class in PlatformRegistry.load_platform_from_dir(platform_dir).items():
|
146
|
+
PlatformRegistry.global_platform_registry.register_platform(platform_name, platform_class)
|
147
|
+
return PlatformRegistry.global_platform_registry
|
148
148
|
|
149
149
|
def __init__(self):
|
150
|
-
"""
|
150
|
+
"""初始化平台注册器
|
151
151
|
"""
|
152
|
-
self.
|
152
|
+
self.platforms: Dict[str, Type[BasePlatform]] = {}
|
153
153
|
|
154
154
|
@staticmethod
|
155
|
-
def
|
156
|
-
"""
|
157
|
-
|
158
|
-
if not
|
159
|
-
raise Exception(f"Failed to create
|
160
|
-
return
|
155
|
+
def get_global_platform() -> BasePlatform:
|
156
|
+
"""获取全局平台实例"""
|
157
|
+
platform = PlatformRegistry.get_global_platform_registry().create_platform(PlatformRegistry.global_platform_name)
|
158
|
+
if not platform:
|
159
|
+
raise Exception(f"Failed to create platform: {PlatformRegistry.global_platform_name}")
|
160
|
+
return platform
|
161
161
|
|
162
|
-
def
|
163
|
-
"""
|
162
|
+
def register_platform(self, name: str, platform_class: Type[BasePlatform]):
|
163
|
+
"""注册平台类
|
164
164
|
|
165
165
|
Args:
|
166
|
-
name:
|
167
|
-
model_class:
|
166
|
+
name: 平台名称
|
167
|
+
model_class: 平台类
|
168
168
|
"""
|
169
|
-
self.
|
170
|
-
PrettyOutput.print(f"
|
169
|
+
self.platforms[name] = platform_class
|
170
|
+
PrettyOutput.print(f"已注册平台: {name}", OutputType.INFO)
|
171
171
|
|
172
|
-
def
|
173
|
-
"""
|
172
|
+
def create_platform(self, name: str) -> Optional[BasePlatform]:
|
173
|
+
"""创建平台实例
|
174
174
|
|
175
175
|
Args:
|
176
|
-
name:
|
176
|
+
name: 平台名称
|
177
177
|
|
178
178
|
Returns:
|
179
|
-
BaseModel:
|
179
|
+
BaseModel: 平台实例
|
180
180
|
"""
|
181
|
-
if name not in self.
|
182
|
-
PrettyOutput.print(f"
|
181
|
+
if name not in self.platforms:
|
182
|
+
PrettyOutput.print(f"未找到平台: {name}", OutputType.ERROR)
|
183
183
|
return None
|
184
184
|
|
185
185
|
try:
|
186
|
-
|
187
|
-
PrettyOutput.print(f"
|
188
|
-
return
|
186
|
+
platform = self.platforms[name]()
|
187
|
+
PrettyOutput.print(f"已创建平台实例: {name}", OutputType.INFO)
|
188
|
+
return platform
|
189
189
|
except Exception as e:
|
190
|
-
PrettyOutput.print(f"
|
190
|
+
PrettyOutput.print(f"创建平台失败: {str(e)}", OutputType.ERROR)
|
191
191
|
return None
|
192
192
|
|
193
|
-
def
|
194
|
-
"""
|
195
|
-
return list(self.
|
193
|
+
def get_available_platforms(self) -> List[str]:
|
194
|
+
"""获取可用平台列表"""
|
195
|
+
return list(self.platforms.keys())
|
196
196
|
|
197
|
-
def
|
198
|
-
"""
|
199
|
-
|
197
|
+
def set_global_platform_name(self, platform_name: str):
|
198
|
+
"""设置全局平台"""
|
199
|
+
PlatformRegistry.global_platform_name = platform_name
|
200
|
+
|
201
|
+
def get_global_platform_name(self) -> str:
|
202
|
+
"""获取全局平台名称"""
|
203
|
+
return PlatformRegistry.global_platform_name
|
Binary file
|
Binary file
|
jarvis/tools/generator.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
import os
|
1
2
|
from typing import Dict, Any
|
2
3
|
from pathlib import Path
|
3
|
-
from jarvis.models.registry import
|
4
|
+
from jarvis.models.registry import PlatformRegistry
|
4
5
|
from jarvis.tools.registry import ToolRegistry
|
5
6
|
from jarvis.utils import OutputType, PrettyOutput
|
6
7
|
|
@@ -41,7 +42,11 @@ class ToolGeneratorTool:
|
|
41
42
|
|
42
43
|
def _generate_tool_code(self, tool_name: str, class_name: str, description: str, parameters: Dict) -> str:
|
43
44
|
"""使用大模型生成工具代码"""
|
44
|
-
|
45
|
+
platform_name = os.getenv("JARVIS_CODEGEN_PLATFORM") or PlatformRegistry.get_global_platform_name()
|
46
|
+
model = PlatformRegistry.create_platform(platform_name)
|
47
|
+
model_name = os.getenv("JARVIS_CODEGEN_MODEL")
|
48
|
+
if model_name:
|
49
|
+
model.set_model_name(model_name)
|
45
50
|
|
46
51
|
prompt = f"""请生成一个Python工具类的代码,要求如下,除了代码,不要输出任何内容:
|
47
52
|
|
jarvis/tools/registry.py
CHANGED
@@ -5,7 +5,7 @@ from pathlib import Path
|
|
5
5
|
import sys
|
6
6
|
from typing import Any, Callable, Dict, List, Optional
|
7
7
|
|
8
|
-
from jarvis.models.registry import
|
8
|
+
from jarvis.models.registry import PlatformRegistry
|
9
9
|
from jarvis.tools.base import Tool
|
10
10
|
from jarvis.utils import OutputType, PrettyOutput
|
11
11
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: jarvis-ai-assistant
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.43
|
4
4
|
Summary: Jarvis: An AI assistant that uses tools to interact with the system
|
5
5
|
Home-page: https://github.com/skyfireitdiy/Jarvis
|
6
6
|
Author: skyfire
|
@@ -134,8 +134,8 @@ jarvis
|
|
134
134
|
|
135
135
|
### With Specific Model
|
136
136
|
```bash
|
137
|
-
jarvis -
|
138
|
-
jarvis -
|
137
|
+
jarvis -p kimi # Use Kimi platform
|
138
|
+
jarvis -p openai # Use OpenAI platform
|
139
139
|
```
|
140
140
|
|
141
141
|
### Process Files
|
@@ -154,10 +154,11 @@ jarvis --keep-history # Don't delete chat session after completion
|
|
154
154
|
|
155
155
|
| Tool | Description |
|
156
156
|
|------|-------------|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
| methodology |
|
157
|
+
| execute_shell | Execute system commands and capture output |
|
158
|
+
| file_operation | File operations (read/write/append/delete) |
|
159
|
+
| generate_tool | AI-powered tool generation and integration |
|
160
|
+
| methodology | Experience accumulation and methodology management |
|
161
|
+
| create_sub_agent | Create specialized sub-agents for specific tasks |
|
161
162
|
|
162
163
|
### Tool Locations
|
163
164
|
- Built-in tools: `src/jarvis/tools/`
|
@@ -166,21 +167,21 @@ jarvis --keep-history # Don't delete chat session after completion
|
|
166
167
|
### Key Features
|
167
168
|
|
168
169
|
#### 1. Self-Extending Capabilities
|
169
|
-
-
|
170
|
-
- Automatic
|
171
|
-
- Dynamic capability expansion
|
170
|
+
- Tool generation through natural language description
|
171
|
+
- Automatic code generation and integration
|
172
|
+
- Dynamic capability expansion through sub-agents
|
172
173
|
|
173
174
|
#### 2. Methodology Learning
|
174
|
-
- Automatic
|
175
|
-
-
|
176
|
-
-
|
175
|
+
- Automatic experience accumulation from interactions
|
176
|
+
- Pattern recognition and methodology extraction
|
177
|
+
- Continuous refinement through usage
|
177
178
|
|
178
179
|
#### 3. Adaptive Problem Solving
|
179
|
-
- Context-aware
|
180
|
-
- Dynamic
|
181
|
-
- Learning from execution
|
180
|
+
- Context-aware sub-agent creation
|
181
|
+
- Dynamic tool composition
|
182
|
+
- Learning from execution feedback
|
182
183
|
|
183
|
-
##
|
184
|
+
## 🎯 Extending Jarvis
|
184
185
|
|
185
186
|
### Adding New Tools
|
186
187
|
|
@@ -1,34 +1,34 @@
|
|
1
|
-
jarvis/__init__.py,sha256=
|
2
|
-
jarvis/agent.py,sha256=
|
3
|
-
jarvis/main.py,sha256=
|
1
|
+
jarvis/__init__.py,sha256=OJVxHJQi99bOxMOkdKLvxRutQ_Lc4AyKCH4e-FnQNfw,50
|
2
|
+
jarvis/agent.py,sha256=5GmC9iAOerTR4JoxzrfgLSspoz6qRm1E6xEIWLTR2OI,12222
|
3
|
+
jarvis/main.py,sha256=3kpohHORc13A5RBjTSHYF7cdnc6W15hO23R78Iqnz8w,5843
|
4
4
|
jarvis/utils.py,sha256=JlkuC9RtspXH2VWDmj9nR0vnb8ie1gIsKc4vC7WRco8,7321
|
5
|
-
jarvis/__pycache__/__init__.cpython-313.pyc,sha256=
|
6
|
-
jarvis/__pycache__/agent.cpython-313.pyc,sha256=
|
7
|
-
jarvis/__pycache__/main.cpython-313.pyc,sha256
|
5
|
+
jarvis/__pycache__/__init__.cpython-313.pyc,sha256=FWB9E8zChLF1EI0hTB-cEMjRy5wB24APzutV1cZJLqY,209
|
6
|
+
jarvis/__pycache__/agent.cpython-313.pyc,sha256=H7FXCYJSJm0k062oMVFZx1unUD-khreKrZfaKQ2aJqY,15870
|
7
|
+
jarvis/__pycache__/main.cpython-313.pyc,sha256=-tDMANWAyPk45zx-lnxM1_uxTUzEqrWwcBe2nWtzH2E,8133
|
8
8
|
jarvis/__pycache__/models.cpython-313.pyc,sha256=uWuRIjGrY4YDB3dGW5PGDLWaS03et8g11O725TjY_eU,5960
|
9
9
|
jarvis/__pycache__/tools.cpython-313.pyc,sha256=lAD4LrnnWzNZQmHXGfZ_2l7oskOpr2_2OC-gdFhxQY8,33933
|
10
10
|
jarvis/__pycache__/utils.cpython-313.pyc,sha256=eXXM-V-2ax7qBNxktdUrEIwhAXPQHAlI7gLGewlKOj4,10276
|
11
11
|
jarvis/__pycache__/zte_llm.cpython-313.pyc,sha256=kMm9IGundGmOPqjsgrm9oIaWLDagYGCPRAaE3ipkc-0,5662
|
12
|
-
jarvis/models/__init__.py,sha256=
|
13
|
-
jarvis/models/ai8.py,sha256=
|
14
|
-
jarvis/models/base.py,sha256=
|
15
|
-
jarvis/models/kimi.py,sha256=
|
16
|
-
jarvis/models/openai.py,sha256=
|
17
|
-
jarvis/models/oyi.py,sha256=
|
18
|
-
jarvis/models/registry.py,sha256=
|
19
|
-
jarvis/models/__pycache__/__init__.cpython-313.pyc,sha256=
|
20
|
-
jarvis/models/__pycache__/ai8.cpython-313.pyc,sha256=
|
21
|
-
jarvis/models/__pycache__/base.cpython-313.pyc,sha256=
|
22
|
-
jarvis/models/__pycache__/kimi.cpython-313.pyc,sha256=
|
23
|
-
jarvis/models/__pycache__/openai.cpython-313.pyc,sha256
|
24
|
-
jarvis/models/__pycache__/oyi.cpython-313.pyc,sha256=
|
25
|
-
jarvis/models/__pycache__/registry.cpython-313.pyc,sha256=
|
12
|
+
jarvis/models/__init__.py,sha256=mrOt67nselz_H1gX9wdAO4y2DY5WPXzABqJbr5Des8k,63
|
13
|
+
jarvis/models/ai8.py,sha256=d1h3L32QBfyf5iQvyncTo-RfvA-kTDGrL7gtxAL6gDg,11609
|
14
|
+
jarvis/models/base.py,sha256=CMjODEh2c9KbCMfQGF7WgGbn-CfpIaGdA5yK1RxKMLY,1282
|
15
|
+
jarvis/models/kimi.py,sha256=N0bPQ1ugx0RwjR96jLchmOPvCmws-fXyA0mnOAdo2k4,17161
|
16
|
+
jarvis/models/openai.py,sha256=pB7AaZuorHlmudTPaUnEbFOyl51Fy6uhU9KQBm98Ov8,4156
|
17
|
+
jarvis/models/oyi.py,sha256=2-PTdoboHl0Jtn0RrBXC7gSCYbI9_yVUmNDBVYw-U5M,12458
|
18
|
+
jarvis/models/registry.py,sha256=iVBjN9ImEvGHcz8WR-z8pPMJQZI907o_nccVOFANhak,7951
|
19
|
+
jarvis/models/__pycache__/__init__.cpython-313.pyc,sha256=b9Z3owWpzLnKKwqQH6bWHZJZDeThHGD9Oa7TMCpyHwc,224
|
20
|
+
jarvis/models/__pycache__/ai8.cpython-313.pyc,sha256=Bu4NXc_CV-GViEL55b0keW6coToPW9aYXhTcOsZIcvg,14972
|
21
|
+
jarvis/models/__pycache__/base.cpython-313.pyc,sha256=Bsu0p7yNCNa4jO-i2A58i3H3xYzxzhtty5BeHAC5lmE,2488
|
22
|
+
jarvis/models/__pycache__/kimi.cpython-313.pyc,sha256=uqDghVAZe5bpw9RtVGoiFd3-hJnIkhbNDaBdrAwiq2w,21662
|
23
|
+
jarvis/models/__pycache__/openai.cpython-313.pyc,sha256=3buu7rqBwDV8mJ4wMff6xy_8pf6XPt2NYTlfIdPpz8M,6384
|
24
|
+
jarvis/models/__pycache__/oyi.cpython-313.pyc,sha256=49JKEc1tGhbdMV0PiBRnGxq4OGAfNnKmozNw87aRmP8,14441
|
25
|
+
jarvis/models/__pycache__/registry.cpython-313.pyc,sha256=iL3zjkiOC-xUnW3SLV_UN1P_CaxS8-RJm5njLZ1z3cg,10384
|
26
26
|
jarvis/tools/__init__.py,sha256=Kj1bKj34lwRDKMKHLOrLyQElf2lHbqA2tDgP359eaDo,71
|
27
27
|
jarvis/tools/base.py,sha256=EGRGbdfbLXDLwtyoWdvp9rlxNX7bzc20t0Vc2VkwIEY,652
|
28
28
|
jarvis/tools/file_ops.py,sha256=h8g0eT9UvlJf4kt0DLXvdSsjcPj7x19lxWdDApeDfpg,3842
|
29
|
-
jarvis/tools/generator.py,sha256=
|
29
|
+
jarvis/tools/generator.py,sha256=vVP3eN5cCDpRXf_fn0skETkPXAW1XZFWx9pt2_ahK48,5999
|
30
30
|
jarvis/tools/methodology.py,sha256=G3cOaHTMujGZBhDLhQEqyCV2NISizO3MXRuho1KfI6Y,5223
|
31
|
-
jarvis/tools/registry.py,sha256=
|
31
|
+
jarvis/tools/registry.py,sha256=NbH7A4A2lyN2IoyZGFwa5Ghed2dpzbJWCAd1Dg95WBI,7183
|
32
32
|
jarvis/tools/shell.py,sha256=UPKshPyOaUwTngresUw-ot1jHjQIb4wCY5nkJqa38lU,2520
|
33
33
|
jarvis/tools/sub_agent.py,sha256=rEtAmSVY2ZjFOZEKr5m5wpACOQIiM9Zr_3dT92FhXYU,2621
|
34
34
|
jarvis/tools/__pycache__/__init__.cpython-313.pyc,sha256=2ezw_ULVg9CJCUdX-RXTgYHLxQBs5X7wWJu1GNAN3ro,231
|
@@ -37,11 +37,11 @@ jarvis/tools/__pycache__/bing_search.cpython-313.pyc,sha256=1G_wPbk5wcQYh7H0drLI
|
|
37
37
|
jarvis/tools/__pycache__/calculator.cpython-313.pyc,sha256=C_qwTDGm6gc7QNxtPzPZXyStdKEintJVQIt5NMHQ8oY,4205
|
38
38
|
jarvis/tools/__pycache__/calculator_tool.cpython-313.pyc,sha256=PI4LZNDTPdSe3ffWDRovLZ-r-vF8Kl-n6xdGdFWiBpY,4296
|
39
39
|
jarvis/tools/__pycache__/file_ops.cpython-313.pyc,sha256=qfgRIcO7JFsa_FxOOXV-3pNSnlovZDrcIkZ1WN3pOJI,3773
|
40
|
-
jarvis/tools/__pycache__/generator.cpython-313.pyc,sha256=
|
40
|
+
jarvis/tools/__pycache__/generator.cpython-313.pyc,sha256=KxHCnyEZTUL3pNozcUWhMHG-cq2HAJOvi3cOEVSPX_A,6561
|
41
41
|
jarvis/tools/__pycache__/methodology.cpython-313.pyc,sha256=GWPSF5b0i6gUsgvJgXIkVQHpLRYQ7OzEiTLwe6aAuWU,6226
|
42
42
|
jarvis/tools/__pycache__/python_script.cpython-313.pyc,sha256=8JpryqTovEiTvBlWAK1KjZmPvHUuPc9GT9rTXBEQoJc,6693
|
43
43
|
jarvis/tools/__pycache__/rag.cpython-313.pyc,sha256=JH6-PSZRMKAvTZqCwlRXJGClxYXNMs-vetU0q7hBLz0,6064
|
44
|
-
jarvis/tools/__pycache__/registry.cpython-313.pyc,sha256=
|
44
|
+
jarvis/tools/__pycache__/registry.cpython-313.pyc,sha256=dXrc1wOTipUJELYl681SM7x1ZyhBNLWIF3ldtrx-HS4,9347
|
45
45
|
jarvis/tools/__pycache__/search.cpython-313.pyc,sha256=wLMIkFwT-h4NGHgssytT4xme7sGO6ZhEnex7kjcy0-k,5990
|
46
46
|
jarvis/tools/__pycache__/shell.cpython-313.pyc,sha256=ATt7BraEX6Sd3Ih6etwFpZ8fYczlZn5f0IqdjaqXt6c,3349
|
47
47
|
jarvis/tools/__pycache__/sub_agent.cpython-313.pyc,sha256=ROqk3BEwB_2-ALp6jG3wf18ShUr1lO0bhJjibOn6f3o,2799
|
@@ -49,9 +49,9 @@ jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc,sha256=wK3Ev10lHSUSRv
|
|
49
49
|
jarvis/tools/__pycache__/user_input.cpython-313.pyc,sha256=JjTFOhObKsKF4Pn8KBRuKfV1_Ssj083fjU7Mfc_5z7c,2531
|
50
50
|
jarvis/tools/__pycache__/user_interaction.cpython-313.pyc,sha256=RuVZ-pmiPBDywY3efgXSfohMAciC1avMGPmBK5qlnew,3305
|
51
51
|
jarvis/tools/__pycache__/webpage.cpython-313.pyc,sha256=BjzSfnNzsKCrLETCcWjt32lNDLzwnjqcVGg4JfWd9OM,3008
|
52
|
-
jarvis_ai_assistant-0.1.
|
53
|
-
jarvis_ai_assistant-0.1.
|
54
|
-
jarvis_ai_assistant-0.1.
|
55
|
-
jarvis_ai_assistant-0.1.
|
56
|
-
jarvis_ai_assistant-0.1.
|
57
|
-
jarvis_ai_assistant-0.1.
|
52
|
+
jarvis_ai_assistant-0.1.43.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
53
|
+
jarvis_ai_assistant-0.1.43.dist-info/METADATA,sha256=BolaQ4qPW5JleYCO9bdksEjAEgBVCuJVXIFs6zzlLz8,10015
|
54
|
+
jarvis_ai_assistant-0.1.43.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
55
|
+
jarvis_ai_assistant-0.1.43.dist-info/entry_points.txt,sha256=iKu7OMfew9dtfGhW71gIMTg4wvafuPqKb4wyQOnMAGU,44
|
56
|
+
jarvis_ai_assistant-0.1.43.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
57
|
+
jarvis_ai_assistant-0.1.43.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{jarvis_ai_assistant-0.1.41.dist-info → jarvis_ai_assistant-0.1.43.dist-info}/entry_points.txt
RENAMED
File without changes
|
File without changes
|