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.
Files changed (105) hide show
  1. {jarvis_ai_assistant-0.1.212/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.213}/PKG-INFO +2 -2
  2. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/pyproject.toml +2 -2
  3. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/setup.py +4 -3
  4. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/__init__.py +1 -1
  5. jarvis_ai_assistant-0.1.213/src/jarvis/jarvis_platform/ai8.py +263 -0
  6. jarvis_ai_assistant-0.1.213/src/jarvis/jarvis_platform/oyi.py +307 -0
  7. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/input.py +5 -5
  8. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213/src/jarvis_ai_assistant.egg-info}/PKG-INFO +2 -2
  9. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/requires.txt +1 -1
  10. jarvis_ai_assistant-0.1.212/src/jarvis/jarvis_platform/ai8.py +0 -270
  11. jarvis_ai_assistant-0.1.212/src/jarvis/jarvis_platform/oyi.py +0 -314
  12. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/LICENSE +0 -0
  13. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/MANIFEST.in +0 -0
  14. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/README.md +0 -0
  15. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/setup.cfg +0 -0
  16. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/__init__.py +0 -0
  17. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/builtin_input_handler.py +0 -0
  18. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/edit_file_handler.py +0 -0
  19. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/jarvis.py +0 -0
  20. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/main.py +0 -0
  21. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/output_handler.py +0 -0
  22. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_agent/shell_input_handler.py +0 -0
  23. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
  24. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_agent/code_agent.py +0 -0
  25. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_agent/lint.py +0 -0
  26. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/__init__.py +0 -0
  27. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/c_cpp.py +0 -0
  28. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/csharp.py +0 -0
  29. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/data_format.py +0 -0
  30. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/devops.py +0 -0
  31. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/docs.py +0 -0
  32. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/go.py +0 -0
  33. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/infrastructure.py +0 -0
  34. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/java.py +0 -0
  35. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/javascript.py +0 -0
  36. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/kotlin.py +0 -0
  37. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/loader.py +0 -0
  38. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/php.py +0 -0
  39. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/python.py +0 -0
  40. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/ruby.py +0 -0
  41. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/rust.py +0 -0
  42. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/shell.py +0 -0
  43. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/sql.py +0 -0
  44. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/swift.py +0 -0
  45. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/checklists/web.py +0 -0
  46. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_code_analysis/code_review.py +0 -0
  47. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_data/config_schema.json +0 -0
  48. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
  49. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_details/__init__.py +0 -0
  50. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_details/main.py +0 -0
  51. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
  52. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_squash/main.py +0 -0
  53. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_git_utils/git_commiter.py +0 -0
  54. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_mcp/__init__.py +0 -0
  55. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_mcp/sse_mcp_client.py +0 -0
  56. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_mcp/stdio_mcp_client.py +0 -0
  57. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_mcp/streamable_mcp_client.py +0 -0
  58. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_methodology/main.py +0 -0
  59. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_multi_agent/__init__.py +0 -0
  60. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_multi_agent/main.py +0 -0
  61. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/__init__.py +0 -0
  62. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/base.py +0 -0
  63. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/human.py +0 -0
  64. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/kimi.py +0 -0
  65. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/openai.py +0 -0
  66. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/registry.py +0 -0
  67. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/tongyi.py +0 -0
  68. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform/yuanbao.py +0 -0
  69. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
  70. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform_manager/main.py +0 -0
  71. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_platform_manager/service.py +0 -0
  72. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
  73. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_smart_shell/main.py +0 -0
  74. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/__init__.py +0 -0
  75. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/ask_user.py +0 -0
  76. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/base.py +0 -0
  77. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/cli/__init__.py +0 -0
  78. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/cli/main.py +0 -0
  79. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/edit_file.py +0 -0
  80. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/execute_script.py +0 -0
  81. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/file_analyzer.py +0 -0
  82. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/generate_new_tool.py +0 -0
  83. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/methodology.py +0 -0
  84. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/read_code.py +0 -0
  85. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
  86. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/registry.py +0 -0
  87. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/rewrite_file.py +0 -0
  88. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/search_web.py +0 -0
  89. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_tools/virtual_tty.py +0 -0
  90. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/__init__.py +0 -0
  91. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/builtin_replace_map.py +0 -0
  92. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/config.py +0 -0
  93. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/embedding.py +0 -0
  94. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/file_processors.py +0 -0
  95. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/git_utils.py +0 -0
  96. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/globals.py +0 -0
  97. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/http.py +0 -0
  98. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/methodology.py +0 -0
  99. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/output.py +0 -0
  100. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/tag.py +0 -0
  101. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis/jarvis_utils/utils.py +0 -0
  102. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +0 -0
  103. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  104. {jarvis_ai_assistant-0.1.212 → jarvis_ai_assistant-0.1.213}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
  105. {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.212
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.212"
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.212",
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>=6.0.2",
34
+ "pyyaml>=5.3.1",
35
35
  "httpx>=0.28.1",
36
36
  ],
37
- extras_require={"dev": ["pytest", "black", "isort", "mypy", "build", "twine"]},
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",
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.1.212"
4
+ __version__ = "0.1.213"
@@ -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
@@ -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+L 复制最后一条消息,按 Ctrl+C 取消输入",
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-l")
215
+ @bindings.add("c-o")
216
216
  def _(event):
217
- """处理Ctrl+L以复制最后一条消息到剪贴板。"""
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,