jarvis-ai-assistant 0.1.212__tar.gz → 0.1.213__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.1.212/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.213}/PKG-INFO +2 -2
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/pyproject.toml +2 -2
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/setup.py +4 -3
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/__init__.py +1 -1
- jarvis_ai_assistant-0.1.213/src/jarvis/jarvis_platform/ai8.py +263 -0
- jarvis_ai_assistant-0.1.213/src/jarvis/jarvis_platform/oyi.py +307 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/input.py +5 -5
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213/src/jarvis_ai_assistant.egg-info}/PKG-INFO +2 -2
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/requires.txt +1 -1
- jarvis_ai_assistant-0.1.212/src/jarvis/jarvis_platform/ai8.py +0 -270
- jarvis_ai_assistant-0.1.212/src/jarvis/jarvis_platform/oyi.py +0 -314
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/README.md +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/edit_file_handler.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/jarvis.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/main.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_agent/code_agent.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_agent/lint.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_data/config_schema.json +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_details/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_details/main.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_squash/main.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_utils/git_commiter.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_mcp/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_methodology/main.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_multi_agent/main.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/base.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/human.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/kimi.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/tongyi.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform_manager/main.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform_manager/service.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_smart_shell/main.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/base.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/cli/main.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/edit_file.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/execute_script.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/read_code.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/registry.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/search_web.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/config.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/embedding.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/file_processors.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/git_utils.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/globals.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/http.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/methodology.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/output.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/tag.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/utils.py +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: jarvis-ai-assistant
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.213
|
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
|
@@ -54,8 +54,8 @@ Requires-Dist: pillow==10.2.0
|
|
54
54
|
Requires-Dist: openai==1.78.1
|
55
55
|
Requires-Dist: tabulate==0.9.0
|
56
56
|
Requires-Dist: pyte==0.8.2
|
57
|
-
Requires-Dist: pyyaml>=6.0.2
|
58
57
|
Requires-Dist: httpx>=0.28.1
|
58
|
+
Requires-Dist: pyyaml>=5.3.1
|
59
59
|
Provides-Extra: dev
|
60
60
|
Requires-Dist: pytest; extra == "dev"
|
61
61
|
Requires-Dist: black; extra == "dev"
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "jarvis-ai-assistant"
|
7
|
-
version = "0.1.
|
7
|
+
version = "0.1.213"
|
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" }]
|
@@ -36,8 +36,8 @@ dependencies = [
|
|
36
36
|
"openai==1.78.1",
|
37
37
|
"tabulate==0.9.0",
|
38
38
|
"pyte==0.8.2",
|
39
|
-
"pyyaml>=6.0.2",
|
40
39
|
"httpx>=0.28.1",
|
40
|
+
"pyyaml>=5.3.1",
|
41
41
|
]
|
42
42
|
requires-python = ">=3.8"
|
43
43
|
|
@@ -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.1.
|
6
|
+
version="0.1.213",
|
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",
|
@@ -31,10 +31,11 @@ setup(
|
|
31
31
|
"openai==1.78.1",
|
32
32
|
"tabulate==0.9.0",
|
33
33
|
"pyte==0.8.2",
|
34
|
-
"pyyaml>=
|
34
|
+
"pyyaml>=5.3.1",
|
35
35
|
"httpx>=0.28.1",
|
36
36
|
],
|
37
|
-
extras_require={"dev": ["pytest", "black",
|
37
|
+
extras_require={"dev": ["pytest", "black",
|
38
|
+
"isort", "mypy", "build", "twine"]},
|
38
39
|
entry_points={
|
39
40
|
"console_scripts": [
|
40
41
|
"jarvis=jarvis.jarvis_agent.jarvis:main",
|
@@ -0,0 +1,263 @@
|
|
1
|
+
import os
|
2
|
+
from typing import Generator, List, Tuple
|
3
|
+
from jarvis.jarvis_platform.base import BasePlatform
|
4
|
+
import json
|
5
|
+
|
6
|
+
from jarvis.jarvis_utils import http
|
7
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
8
|
+
from jarvis.jarvis_utils.utils import while_success
|
9
|
+
|
10
|
+
|
11
|
+
class AI8Model(BasePlatform):
|
12
|
+
"""AI8 model implementation"""
|
13
|
+
|
14
|
+
platform_name = "ai8"
|
15
|
+
BASE_URL = "https://ai8.rcouyi.com"
|
16
|
+
|
17
|
+
def get_model_list(self) -> List[Tuple[str, str]]:
|
18
|
+
"""获取模型列表"""
|
19
|
+
self.get_available_models()
|
20
|
+
return [(name, info["desc"]) for name, info in self.models.items()]
|
21
|
+
|
22
|
+
def __init__(self):
|
23
|
+
"""Initialize model"""
|
24
|
+
super().__init__()
|
25
|
+
self.system_prompt = ""
|
26
|
+
self.conversation = {}
|
27
|
+
self.models = {} # 存储模型信息
|
28
|
+
|
29
|
+
self.token = os.getenv("AI8_API_KEY")
|
30
|
+
if not self.token:
|
31
|
+
PrettyOutput.print("未设置 AI8_API_KEY", OutputType.WARNING)
|
32
|
+
|
33
|
+
self.headers = {
|
34
|
+
"Authorization": self.token,
|
35
|
+
"Content-Type": "application/json",
|
36
|
+
"Accept": "application/json, text/plain, */*",
|
37
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
38
|
+
"X-APP-VERSION": "2.3.0",
|
39
|
+
"Origin": self.BASE_URL,
|
40
|
+
"Referer": f"{self.BASE_URL}/chat?_userMenuKey=chat",
|
41
|
+
"Sec-Fetch-Site": "same-origin",
|
42
|
+
"Sec-Fetch-Mode": "cors",
|
43
|
+
"Sec-Fetch-Dest": "empty",
|
44
|
+
}
|
45
|
+
|
46
|
+
self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-chat"
|
47
|
+
if self.model_name not in self.get_available_models():
|
48
|
+
PrettyOutput.print(
|
49
|
+
f"警告: 选择的模型 {self.model_name} 不在可用列表中", OutputType.WARNING
|
50
|
+
)
|
51
|
+
|
52
|
+
def set_model_name(self, model_name: str):
|
53
|
+
"""Set model name"""
|
54
|
+
|
55
|
+
self.model_name = model_name
|
56
|
+
|
57
|
+
def create_conversation(self) -> bool:
|
58
|
+
"""Create a new conversation"""
|
59
|
+
try:
|
60
|
+
|
61
|
+
# 1. 创建会话
|
62
|
+
response = while_success(
|
63
|
+
lambda: http.post(
|
64
|
+
f"{self.BASE_URL}/api/chat/session", headers=self.headers, json={}
|
65
|
+
),
|
66
|
+
sleep_time=5,
|
67
|
+
)
|
68
|
+
|
69
|
+
data = response.json()
|
70
|
+
if data["code"] != 0:
|
71
|
+
PrettyOutput.print(
|
72
|
+
f"创建会话失败: {data.get('msg', '未知错误')}", OutputType.WARNING
|
73
|
+
)
|
74
|
+
return False
|
75
|
+
|
76
|
+
self.conversation = data["data"]
|
77
|
+
|
78
|
+
# 2. 更新会话设置
|
79
|
+
session_data = {
|
80
|
+
**self.conversation,
|
81
|
+
"model": self.model_name,
|
82
|
+
"contextCount": 65536,
|
83
|
+
"prompt": self.system_prompt,
|
84
|
+
"plugins": [],
|
85
|
+
"localPlugins": None,
|
86
|
+
"useAppId": 0,
|
87
|
+
}
|
88
|
+
|
89
|
+
response = while_success(
|
90
|
+
lambda: http.put(
|
91
|
+
f"{self.BASE_URL}/api/chat/session/{self.conversation['id']}", # type: ignore
|
92
|
+
headers=self.headers,
|
93
|
+
json=session_data,
|
94
|
+
),
|
95
|
+
sleep_time=5,
|
96
|
+
)
|
97
|
+
|
98
|
+
data = response.json()
|
99
|
+
if data["code"] == 0:
|
100
|
+
self.conversation = data["data"]
|
101
|
+
return True
|
102
|
+
else:
|
103
|
+
PrettyOutput.print(
|
104
|
+
f"更新会话设置失败: {data.get('msg', '未知错误')}",
|
105
|
+
OutputType.WARNING,
|
106
|
+
)
|
107
|
+
return False
|
108
|
+
|
109
|
+
except Exception as e:
|
110
|
+
PrettyOutput.print(f"创建会话失败: {str(e)}", OutputType.ERROR)
|
111
|
+
return False
|
112
|
+
|
113
|
+
def set_system_prompt(self, message: str):
|
114
|
+
"""Set system message"""
|
115
|
+
self.system_prompt = message
|
116
|
+
|
117
|
+
def chat(self, message: str) -> Generator[str, None, None]:
|
118
|
+
"""Execute conversation"""
|
119
|
+
try:
|
120
|
+
|
121
|
+
# 确保有会话ID
|
122
|
+
if not self.conversation:
|
123
|
+
if not self.create_conversation():
|
124
|
+
raise Exception("Failed to create conversation")
|
125
|
+
|
126
|
+
payload = {
|
127
|
+
"text": message,
|
128
|
+
"sessionId": self.conversation["id"] if self.conversation else None,
|
129
|
+
"files": [],
|
130
|
+
}
|
131
|
+
|
132
|
+
# 使用stream_post进行流式请求
|
133
|
+
response_stream = while_success(
|
134
|
+
lambda: http.stream_post(
|
135
|
+
f"{self.BASE_URL}/api/chat/completions",
|
136
|
+
headers=self.headers,
|
137
|
+
json=payload,
|
138
|
+
),
|
139
|
+
sleep_time=5,
|
140
|
+
)
|
141
|
+
|
142
|
+
# 处理流式响应
|
143
|
+
for chunk in response_stream:
|
144
|
+
if chunk:
|
145
|
+
try:
|
146
|
+
line = chunk.decode("utf-8")
|
147
|
+
if line.startswith("data: "):
|
148
|
+
try:
|
149
|
+
data = json.loads(line[6:])
|
150
|
+
if data.get("type") == "string":
|
151
|
+
chunk_data = data.get("data", "")
|
152
|
+
if chunk_data:
|
153
|
+
yield chunk_data
|
154
|
+
|
155
|
+
except json.JSONDecodeError:
|
156
|
+
continue
|
157
|
+
|
158
|
+
except UnicodeDecodeError:
|
159
|
+
continue
|
160
|
+
|
161
|
+
return None
|
162
|
+
|
163
|
+
except Exception as e:
|
164
|
+
PrettyOutput.print(f"对话异常: {str(e)}", OutputType.ERROR)
|
165
|
+
raise e
|
166
|
+
|
167
|
+
def name(self) -> str:
|
168
|
+
"""Return model name"""
|
169
|
+
return self.model_name
|
170
|
+
|
171
|
+
def delete_chat(self) -> bool:
|
172
|
+
"""Delete current chat session"""
|
173
|
+
try:
|
174
|
+
if not self.conversation:
|
175
|
+
return True
|
176
|
+
|
177
|
+
response = while_success(
|
178
|
+
lambda: http.delete(
|
179
|
+
f"{self.BASE_URL}/api/chat/session/{self.conversation['id']}", # type: ignore
|
180
|
+
headers=self.headers,
|
181
|
+
),
|
182
|
+
sleep_time=5,
|
183
|
+
)
|
184
|
+
|
185
|
+
data = response.json()
|
186
|
+
if data["code"] == 0:
|
187
|
+
self.conversation = None
|
188
|
+
return True
|
189
|
+
else:
|
190
|
+
error_msg = f"删除会话失败: {data.get('msg', '未知错误')}"
|
191
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
192
|
+
return False
|
193
|
+
|
194
|
+
except Exception as e:
|
195
|
+
PrettyOutput.print(f"删除会话失败: {str(e)}", OutputType.ERROR)
|
196
|
+
return False
|
197
|
+
|
198
|
+
def get_available_models(self) -> List[str]:
|
199
|
+
"""Get available model list
|
200
|
+
|
201
|
+
Returns:
|
202
|
+
List[str]: Available model name list
|
203
|
+
"""
|
204
|
+
try:
|
205
|
+
if self.models:
|
206
|
+
return list(self.models.keys())
|
207
|
+
|
208
|
+
response = while_success(
|
209
|
+
lambda: http.get(
|
210
|
+
f"{self.BASE_URL}/api/chat/tmpl", headers=self.headers
|
211
|
+
),
|
212
|
+
sleep_time=5,
|
213
|
+
)
|
214
|
+
|
215
|
+
data = response.json()
|
216
|
+
if data["code"] != 0:
|
217
|
+
PrettyOutput.print(
|
218
|
+
f"获取模型列表失败: {data.get('msg', '未知错误')}",
|
219
|
+
OutputType.WARNING,
|
220
|
+
)
|
221
|
+
return []
|
222
|
+
|
223
|
+
# 保存模型信息
|
224
|
+
self.models = {model["value"]: model for model in data["data"]["models"]}
|
225
|
+
|
226
|
+
for model in self.models.values():
|
227
|
+
# 添加标签
|
228
|
+
model_str = f"{model['label']}"
|
229
|
+
|
230
|
+
# 添加特性标记
|
231
|
+
features = []
|
232
|
+
if model["attr"].get("multimodal"):
|
233
|
+
features.append("Multimodal")
|
234
|
+
if model["attr"].get("plugin"):
|
235
|
+
features.append("Plugin support")
|
236
|
+
if model["attr"].get("onlyImg"):
|
237
|
+
features.append("Image support")
|
238
|
+
if model["attr"].get("tag"):
|
239
|
+
features.append(model["attr"]["tag"])
|
240
|
+
if model["attr"].get("integral"):
|
241
|
+
features.append(model["attr"]["integral"])
|
242
|
+
# 添加备注
|
243
|
+
if model["attr"].get("note"):
|
244
|
+
model_str += f" - {model['attr']['note']}"
|
245
|
+
if features:
|
246
|
+
model_str += f" [{'|'.join(features)}]"
|
247
|
+
|
248
|
+
model["desc"] = model_str
|
249
|
+
|
250
|
+
return list(self.models.keys())
|
251
|
+
|
252
|
+
except Exception as e:
|
253
|
+
PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.ERROR)
|
254
|
+
return []
|
255
|
+
|
256
|
+
def support_upload_files(self) -> bool:
|
257
|
+
return False
|
258
|
+
|
259
|
+
def support_web(self) -> bool:
|
260
|
+
return False
|
261
|
+
|
262
|
+
def upload_files(self, file_list: List[str]) -> bool:
|
263
|
+
return False
|
@@ -0,0 +1,307 @@
|
|
1
|
+
import mimetypes
|
2
|
+
import os
|
3
|
+
from typing import Dict, Generator, List, Tuple
|
4
|
+
from jarvis.jarvis_platform.base import BasePlatform
|
5
|
+
import json
|
6
|
+
|
7
|
+
from jarvis.jarvis_utils import http
|
8
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
9
|
+
from jarvis.jarvis_utils.utils import while_success
|
10
|
+
|
11
|
+
|
12
|
+
class OyiModel(BasePlatform):
|
13
|
+
"""Oyi model implementation"""
|
14
|
+
|
15
|
+
platform_name = "oyi"
|
16
|
+
BASE_URL = "https://api-10086.rcouyi.com"
|
17
|
+
|
18
|
+
def get_model_list(self) -> List[Tuple[str, str]]:
|
19
|
+
"""Get model list"""
|
20
|
+
self.get_available_models()
|
21
|
+
return [(name, info["desc"]) for name, info in self.models.items()]
|
22
|
+
|
23
|
+
def __init__(self):
|
24
|
+
"""Initialize model"""
|
25
|
+
super().__init__()
|
26
|
+
self.models = {}
|
27
|
+
self.messages = []
|
28
|
+
self.system_prompt = ""
|
29
|
+
self.conversation = None
|
30
|
+
self.first_chat = True
|
31
|
+
|
32
|
+
self.token = os.getenv("OYI_API_KEY")
|
33
|
+
if not self.token:
|
34
|
+
PrettyOutput.print("OYI_API_KEY 未设置", OutputType.WARNING)
|
35
|
+
|
36
|
+
self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-chat"
|
37
|
+
if self.model_name not in [m.split()[0] for m in self.get_available_models()]:
|
38
|
+
PrettyOutput.print(
|
39
|
+
f"警告: 选择的模型 {self.model_name} 不在可用列表中", OutputType.WARNING
|
40
|
+
)
|
41
|
+
|
42
|
+
def set_model_name(self, model_name: str):
|
43
|
+
"""Set model name"""
|
44
|
+
|
45
|
+
self.model_name = model_name
|
46
|
+
|
47
|
+
def create_conversation(self) -> bool:
|
48
|
+
"""Create a new conversation"""
|
49
|
+
try:
|
50
|
+
headers = {
|
51
|
+
"Authorization": f"Bearer {self.token}",
|
52
|
+
"Content-Type": "application/json",
|
53
|
+
"Accept": "application/json",
|
54
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
55
|
+
}
|
56
|
+
|
57
|
+
payload = {
|
58
|
+
"id": 0,
|
59
|
+
"roleId": 0,
|
60
|
+
"title": "New conversation",
|
61
|
+
"isLock": False,
|
62
|
+
"systemMessage": "",
|
63
|
+
"params": json.dumps(
|
64
|
+
{
|
65
|
+
"model": self.model_name,
|
66
|
+
"is_webSearch": True,
|
67
|
+
"message": [],
|
68
|
+
"systemMessage": None,
|
69
|
+
"requestMsgCount": 65536,
|
70
|
+
"temperature": 0.8,
|
71
|
+
"speechVoice": "Alloy",
|
72
|
+
"max_tokens": 8192,
|
73
|
+
"chatPluginIds": [],
|
74
|
+
}
|
75
|
+
),
|
76
|
+
}
|
77
|
+
|
78
|
+
response = while_success(
|
79
|
+
lambda: http.post(
|
80
|
+
f"{self.BASE_URL}/chatapi/chat/save", headers=headers, json=payload
|
81
|
+
),
|
82
|
+
sleep_time=5,
|
83
|
+
)
|
84
|
+
|
85
|
+
data = response.json()
|
86
|
+
if data["code"] == 200 and data["type"] == "success":
|
87
|
+
self.conversation = data
|
88
|
+
return True
|
89
|
+
else:
|
90
|
+
PrettyOutput.print(
|
91
|
+
f"创建会话失败: {data['message']}", OutputType.WARNING
|
92
|
+
)
|
93
|
+
return False
|
94
|
+
|
95
|
+
except Exception as e:
|
96
|
+
PrettyOutput.print(f"创建会话失败: {str(e)}", OutputType.ERROR)
|
97
|
+
return False
|
98
|
+
|
99
|
+
def set_system_prompt(self, message: str):
|
100
|
+
"""Set system message"""
|
101
|
+
self.system_prompt = message
|
102
|
+
|
103
|
+
def chat(self, message: str) -> Generator[str, None, None]:
|
104
|
+
"""Execute chat with the model
|
105
|
+
|
106
|
+
Args:
|
107
|
+
message: User input message
|
108
|
+
|
109
|
+
Returns:
|
110
|
+
str: Model response
|
111
|
+
"""
|
112
|
+
try:
|
113
|
+
# 确保有会话ID
|
114
|
+
if not self.conversation:
|
115
|
+
if not self.create_conversation():
|
116
|
+
raise Exception("Failed to create conversation")
|
117
|
+
|
118
|
+
# 1. 发送消息
|
119
|
+
headers = {
|
120
|
+
"Authorization": f"Bearer {self.token}",
|
121
|
+
"Content-Type": "application/json",
|
122
|
+
"Accept": "application/json, text/plain, */*",
|
123
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
124
|
+
"Origin": "https://ai.rcouyi.com",
|
125
|
+
"Referer": "https://ai.rcouyi.com/",
|
126
|
+
}
|
127
|
+
|
128
|
+
payload = {
|
129
|
+
"topicId": (
|
130
|
+
self.conversation["result"]["id"] if self.conversation else None
|
131
|
+
),
|
132
|
+
"messages": self.messages,
|
133
|
+
"content": message,
|
134
|
+
"contentFiles": [],
|
135
|
+
}
|
136
|
+
|
137
|
+
# 如果有上传的文件,添加到请求中
|
138
|
+
if self.first_chat:
|
139
|
+
message = self.system_prompt + "\n" + message
|
140
|
+
payload["content"] = message
|
141
|
+
self.first_chat = False
|
142
|
+
|
143
|
+
self.messages.append({"role": "user", "content": message})
|
144
|
+
|
145
|
+
# 发送消息
|
146
|
+
response = while_success(
|
147
|
+
lambda: http.post(
|
148
|
+
f"{self.BASE_URL}/chatapi/chat/message",
|
149
|
+
headers=headers,
|
150
|
+
json=payload,
|
151
|
+
),
|
152
|
+
sleep_time=5,
|
153
|
+
)
|
154
|
+
|
155
|
+
data = response.json()
|
156
|
+
if data["code"] != 200 or data["type"] != "success":
|
157
|
+
error_msg = f"聊天失败: {data.get('message', '未知错误')}"
|
158
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
159
|
+
raise Exception(error_msg)
|
160
|
+
|
161
|
+
message_id = data["result"][-1]
|
162
|
+
|
163
|
+
# 获取响应内容
|
164
|
+
response = while_success(
|
165
|
+
lambda: http.stream_post(
|
166
|
+
f"{self.BASE_URL}/chatapi/chat/message/{message_id}",
|
167
|
+
headers=headers,
|
168
|
+
),
|
169
|
+
sleep_time=5,
|
170
|
+
)
|
171
|
+
|
172
|
+
full_response = ""
|
173
|
+
bin = b""
|
174
|
+
for chunk in response:
|
175
|
+
if chunk:
|
176
|
+
bin += chunk
|
177
|
+
try:
|
178
|
+
text = bin.decode("utf-8")
|
179
|
+
except UnicodeDecodeError:
|
180
|
+
continue
|
181
|
+
full_response += text
|
182
|
+
bin = b""
|
183
|
+
yield text
|
184
|
+
|
185
|
+
self.messages.append({"role": "assistant", "content": full_response})
|
186
|
+
return None
|
187
|
+
except Exception as e:
|
188
|
+
PrettyOutput.print(f"聊天失败: {str(e)}", OutputType.ERROR)
|
189
|
+
raise e
|
190
|
+
|
191
|
+
def name(self) -> str:
|
192
|
+
"""Return model name"""
|
193
|
+
return self.model_name
|
194
|
+
|
195
|
+
def delete_chat(self) -> bool:
|
196
|
+
"""Delete current chat session"""
|
197
|
+
try:
|
198
|
+
if not self.conversation:
|
199
|
+
return True
|
200
|
+
|
201
|
+
headers = {
|
202
|
+
"Authorization": f"Bearer {self.token}",
|
203
|
+
"Content-Type": "application/json",
|
204
|
+
"Accept": "application/json, text/plain, */*",
|
205
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
206
|
+
"Origin": "https://ai.rcouyi.com",
|
207
|
+
"Referer": "https://ai.rcouyi.com/",
|
208
|
+
}
|
209
|
+
|
210
|
+
response = while_success(
|
211
|
+
lambda: http.post(
|
212
|
+
f"{self.BASE_URL}/chatapi/chat/{self.conversation['result']['id']}", # type: ignore
|
213
|
+
headers=headers,
|
214
|
+
json={},
|
215
|
+
),
|
216
|
+
sleep_time=5,
|
217
|
+
)
|
218
|
+
|
219
|
+
data = response.json()
|
220
|
+
if data["code"] == 200 and data["type"] == "success":
|
221
|
+
self.messages = []
|
222
|
+
self.conversation = None
|
223
|
+
self.first_chat = True
|
224
|
+
return True
|
225
|
+
else:
|
226
|
+
error_msg = f"删除会话失败: {data.get('message', '未知错误')}"
|
227
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
228
|
+
return False
|
229
|
+
|
230
|
+
except Exception as e:
|
231
|
+
PrettyOutput.print(f"删除会话失败: {str(e)}", OutputType.ERROR)
|
232
|
+
return False
|
233
|
+
|
234
|
+
def get_available_models(self) -> List[str]:
|
235
|
+
"""Get available model list
|
236
|
+
|
237
|
+
Returns:
|
238
|
+
List[str]: Available model name list
|
239
|
+
"""
|
240
|
+
try:
|
241
|
+
if self.models:
|
242
|
+
return list(self.models.keys())
|
243
|
+
|
244
|
+
headers = {
|
245
|
+
"Content-Type": "application/json",
|
246
|
+
"Accept": "application/json, text/plain, */*",
|
247
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
248
|
+
"Origin": "https://ai.rcouyi.com",
|
249
|
+
"Referer": "https://ai.rcouyi.com/",
|
250
|
+
}
|
251
|
+
|
252
|
+
response = while_success(
|
253
|
+
lambda: http.get(
|
254
|
+
"https://ai.rcouyi.com/config/system.json", headers=headers
|
255
|
+
),
|
256
|
+
sleep_time=5,
|
257
|
+
)
|
258
|
+
|
259
|
+
data = response.json()
|
260
|
+
|
261
|
+
# 保存模型信息
|
262
|
+
self.models = {
|
263
|
+
model["value"]: model
|
264
|
+
for model in data.get("model", [])
|
265
|
+
if model.get("enable", False) # 只保存启用的模型
|
266
|
+
}
|
267
|
+
|
268
|
+
# 格式化显示
|
269
|
+
models = []
|
270
|
+
for model in self.models.values():
|
271
|
+
# 基本信息
|
272
|
+
model_name = model["value"]
|
273
|
+
model_str = model["label"]
|
274
|
+
|
275
|
+
# 添加后缀标签
|
276
|
+
suffix = model.get("suffix", [])
|
277
|
+
if suffix:
|
278
|
+
# 处理新格式的suffix (字典列表)
|
279
|
+
if suffix and isinstance(suffix[0], dict):
|
280
|
+
suffix_str = ", ".join(s.get("tag", "") for s in suffix)
|
281
|
+
# 处理旧格式的suffix (字符串列表)
|
282
|
+
else:
|
283
|
+
suffix_str = ", ".join(str(s) for s in suffix)
|
284
|
+
model_str += f" ({suffix_str})"
|
285
|
+
|
286
|
+
# 添加描述或提示
|
287
|
+
info = model.get("tooltip") or model.get("description", "")
|
288
|
+
if info:
|
289
|
+
model_str += f" - {info}"
|
290
|
+
|
291
|
+
model["desc"] = model_str
|
292
|
+
models.append(model_name)
|
293
|
+
|
294
|
+
return sorted(models)
|
295
|
+
|
296
|
+
except Exception as e:
|
297
|
+
PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.WARNING)
|
298
|
+
return []
|
299
|
+
|
300
|
+
def support_upload_files(self) -> bool:
|
301
|
+
return False
|
302
|
+
|
303
|
+
def support_web(self) -> bool:
|
304
|
+
return False
|
305
|
+
|
306
|
+
def upload_files(self, file_list: List[str]) -> bool:
|
307
|
+
return False
|
{jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/input.py
RENAMED
@@ -38,7 +38,7 @@ def get_single_line_input(tip: str) -> str:
|
|
38
38
|
返回:
|
39
39
|
str: 用户的输入
|
40
40
|
"""
|
41
|
-
session = PromptSession(history=None)
|
41
|
+
session: PromptSession = PromptSession(history=None)
|
42
42
|
style = PromptStyle.from_dict(
|
43
43
|
{
|
44
44
|
"prompt": "ansicyan",
|
@@ -190,7 +190,7 @@ def get_multiline_input(tip: str) -> str:
|
|
190
190
|
"""
|
191
191
|
# 显示输入说明
|
192
192
|
PrettyOutput.section(
|
193
|
-
"用户输入 - 使用 @ 触发文件补全,Tab 选择补全项,Ctrl+J 提交,Ctrl+
|
193
|
+
"用户输入 - 使用 @ 触发文件补全,Tab 选择补全项,Ctrl+J 提交,Ctrl+O 复制最后一条消息,按 Ctrl+C 取消输入",
|
194
194
|
OutputType.USER,
|
195
195
|
)
|
196
196
|
print(f"{Fore.GREEN}{tip}{ColoramaStyle.RESET_ALL}")
|
@@ -212,9 +212,9 @@ def get_multiline_input(tip: str) -> str:
|
|
212
212
|
"""处理Ctrl+J以提交输入。"""
|
213
213
|
event.current_buffer.validate_and_handle()
|
214
214
|
|
215
|
-
@bindings.add("c-
|
215
|
+
@bindings.add("c-o")
|
216
216
|
def _(event):
|
217
|
-
"""处理Ctrl+
|
217
|
+
"""处理Ctrl+O以复制最后一条消息到剪贴板。"""
|
218
218
|
from jarvis.jarvis_utils.globals import get_last_message
|
219
219
|
import subprocess
|
220
220
|
|
@@ -246,7 +246,7 @@ def get_multiline_input(tip: str) -> str:
|
|
246
246
|
# 获取数据目录路径
|
247
247
|
history_dir = get_data_dir()
|
248
248
|
# 初始化带历史记录的会话
|
249
|
-
session = PromptSession(
|
249
|
+
session: PromptSession = PromptSession(
|
250
250
|
history=FileHistory(os.path.join(history_dir, "multiline_input_history")),
|
251
251
|
completer=FileCompleter(),
|
252
252
|
key_bindings=bindings,
|