jarvis-ai-assistant 0.1.138__py3-none-any.whl → 0.1.141__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.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (85) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +62 -14
  3. jarvis/jarvis_agent/builtin_input_handler.py +4 -14
  4. jarvis/jarvis_agent/main.py +1 -1
  5. jarvis/jarvis_agent/patch.py +37 -40
  6. jarvis/jarvis_agent/shell_input_handler.py +2 -3
  7. jarvis/jarvis_code_agent/code_agent.py +23 -30
  8. jarvis/jarvis_code_analysis/checklists/__init__.py +3 -0
  9. jarvis/jarvis_code_analysis/checklists/c_cpp.py +50 -0
  10. jarvis/jarvis_code_analysis/checklists/csharp.py +75 -0
  11. jarvis/jarvis_code_analysis/checklists/data_format.py +82 -0
  12. jarvis/jarvis_code_analysis/checklists/devops.py +107 -0
  13. jarvis/jarvis_code_analysis/checklists/docs.py +87 -0
  14. jarvis/jarvis_code_analysis/checklists/go.py +52 -0
  15. jarvis/jarvis_code_analysis/checklists/infrastructure.py +98 -0
  16. jarvis/jarvis_code_analysis/checklists/java.py +66 -0
  17. jarvis/jarvis_code_analysis/checklists/javascript.py +73 -0
  18. jarvis/jarvis_code_analysis/checklists/kotlin.py +107 -0
  19. jarvis/jarvis_code_analysis/checklists/loader.py +76 -0
  20. jarvis/jarvis_code_analysis/checklists/php.py +77 -0
  21. jarvis/jarvis_code_analysis/checklists/python.py +56 -0
  22. jarvis/jarvis_code_analysis/checklists/ruby.py +107 -0
  23. jarvis/jarvis_code_analysis/checklists/rust.py +58 -0
  24. jarvis/jarvis_code_analysis/checklists/shell.py +75 -0
  25. jarvis/jarvis_code_analysis/checklists/sql.py +72 -0
  26. jarvis/jarvis_code_analysis/checklists/swift.py +77 -0
  27. jarvis/jarvis_code_analysis/checklists/web.py +97 -0
  28. jarvis/jarvis_code_analysis/code_review.py +660 -0
  29. jarvis/jarvis_dev/main.py +61 -88
  30. jarvis/jarvis_git_squash/main.py +3 -3
  31. jarvis/jarvis_git_utils/git_commiter.py +242 -0
  32. jarvis/jarvis_init/main.py +62 -0
  33. jarvis/jarvis_platform/base.py +4 -0
  34. jarvis/jarvis_platform/kimi.py +173 -5
  35. jarvis/jarvis_platform/openai.py +3 -0
  36. jarvis/jarvis_platform/registry.py +1 -0
  37. jarvis/jarvis_platform/yuanbao.py +275 -5
  38. jarvis/jarvis_tools/ask_codebase.py +6 -9
  39. jarvis/jarvis_tools/ask_user.py +17 -5
  40. jarvis/jarvis_tools/base.py +3 -1
  41. jarvis/jarvis_tools/chdir.py +1 -0
  42. jarvis/jarvis_tools/create_code_agent.py +4 -3
  43. jarvis/jarvis_tools/create_sub_agent.py +1 -0
  44. jarvis/jarvis_tools/execute_script.py +170 -0
  45. jarvis/jarvis_tools/file_analyzer.py +90 -239
  46. jarvis/jarvis_tools/file_operation.py +99 -31
  47. jarvis/jarvis_tools/{find_methodolopy.py → find_methodology.py} +2 -1
  48. jarvis/jarvis_tools/lsp_get_diagnostics.py +2 -0
  49. jarvis/jarvis_tools/methodology.py +11 -11
  50. jarvis/jarvis_tools/read_code.py +2 -0
  51. jarvis/jarvis_tools/read_webpage.py +33 -196
  52. jarvis/jarvis_tools/registry.py +68 -131
  53. jarvis/jarvis_tools/search_web.py +14 -6
  54. jarvis/jarvis_tools/virtual_tty.py +399 -0
  55. jarvis/jarvis_utils/config.py +29 -3
  56. jarvis/jarvis_utils/embedding.py +0 -317
  57. jarvis/jarvis_utils/file_processors.py +343 -0
  58. jarvis/jarvis_utils/input.py +0 -1
  59. jarvis/jarvis_utils/methodology.py +94 -435
  60. jarvis/jarvis_utils/utils.py +207 -9
  61. {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/METADATA +4 -4
  62. jarvis_ai_assistant-0.1.141.dist-info/RECORD +94 -0
  63. {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/entry_points.txt +4 -4
  64. jarvis/jarvis_code_agent/file_select.py +0 -202
  65. jarvis/jarvis_platform/ai8.py +0 -268
  66. jarvis/jarvis_platform/ollama.py +0 -137
  67. jarvis/jarvis_platform/oyi.py +0 -307
  68. jarvis/jarvis_rag/file_processors.py +0 -138
  69. jarvis/jarvis_rag/main.py +0 -1734
  70. jarvis/jarvis_tools/code_review.py +0 -333
  71. jarvis/jarvis_tools/execute_python_script.py +0 -58
  72. jarvis/jarvis_tools/execute_shell.py +0 -97
  73. jarvis/jarvis_tools/execute_shell_script.py +0 -58
  74. jarvis/jarvis_tools/find_caller.py +0 -278
  75. jarvis/jarvis_tools/find_symbol.py +0 -295
  76. jarvis/jarvis_tools/function_analyzer.py +0 -331
  77. jarvis/jarvis_tools/git_commiter.py +0 -167
  78. jarvis/jarvis_tools/project_analyzer.py +0 -304
  79. jarvis/jarvis_tools/rag.py +0 -143
  80. jarvis/jarvis_tools/tool_generator.py +0 -221
  81. jarvis_ai_assistant-0.1.138.dist-info/RECORD +0 -85
  82. /jarvis/{jarvis_rag → jarvis_init}/__init__.py +0 -0
  83. {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/LICENSE +0 -0
  84. {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/WHEEL +0 -0
  85. {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/top_level.txt +0 -0
@@ -1,268 +0,0 @@
1
- import os
2
- from typing import Dict, List, Tuple
3
- from jarvis.jarvis_platform.base import BasePlatform
4
- import requests
5
- import json
6
- import base64
7
-
8
- from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
-
10
- class AI8Model(BasePlatform):
11
- """AI8 model implementation"""
12
-
13
- platform_name = "ai8"
14
- BASE_URL = "https://ai8.rcouyi.com"
15
-
16
- def get_model_list(self) -> List[Tuple[str, str]]:
17
- """获取模型列表"""
18
- self.get_available_models()
19
- return [(name,info['desc']) for name,info in self.models.items()]
20
-
21
- def __init__(self):
22
- """Initialize model"""
23
- super().__init__()
24
- self.system_message = ""
25
- self.conversation = {}
26
- self.models = {} # 存储模型信息
27
-
28
- self.token = os.getenv("AI8_API_KEY")
29
- if not self.token:
30
- PrettyOutput.print("未设置 AI8_API_KEY", OutputType.WARNING)
31
-
32
- self.headers = {
33
- 'Authorization': self.token,
34
- 'Content-Type': 'application/json',
35
- 'Accept': 'application/json, text/plain, */*',
36
- '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',
37
- 'X-APP-VERSION': '2.3.0',
38
- 'Origin': self.BASE_URL,
39
- 'Referer': f'{self.BASE_URL}/chat?_userMenuKey=chat',
40
- 'Sec-Fetch-Site': 'same-origin',
41
- 'Sec-Fetch-Mode': 'cors',
42
- 'Sec-Fetch-Dest': 'empty',
43
- }
44
-
45
- self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-chat"
46
- if self.model_name not in self.get_available_models():
47
- PrettyOutput.print(f"警告: 选择的模型 {self.model_name} 不在可用列表中", OutputType.WARNING)
48
-
49
-
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
-
62
- # 1. 创建会话
63
- response = requests.post(
64
- f"{self.BASE_URL}/api/chat/session",
65
- headers=self.headers,
66
- json={}
67
- )
68
-
69
- if response.status_code != 200:
70
- PrettyOutput.print(f"创建会话失败: {response.status_code}", OutputType.WARNING)
71
- return False
72
-
73
- data = response.json()
74
- if data['code'] != 0:
75
- PrettyOutput.print(f"创建会话失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
76
- return False
77
-
78
- self.conversation = data['data']
79
-
80
- # 2. 更新会话设置
81
- session_data = {
82
- **self.conversation,
83
- "model": self.model_name,
84
- "contextCount": 65536,
85
- "prompt": self.system_message,
86
- "plugins": [],
87
- "localPlugins": None,
88
- "useAppId": 0
89
- }
90
-
91
- response = requests.put(
92
- f"{self.BASE_URL}/api/chat/session/{self.conversation['id']}",
93
- headers=self.headers,
94
- json=session_data
95
- )
96
-
97
- if response.status_code == 200:
98
- data = response.json()
99
- if data['code'] == 0:
100
- self.conversation = data['data']
101
- return True
102
- else:
103
- PrettyOutput.print(f"更新会话设置失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
104
- return False
105
- else:
106
- PrettyOutput.print(f"更新会话设置失败: {response.status_code}", OutputType.WARNING)
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_message(self, message: str):
114
- """Set system message"""
115
- self.system_message = message
116
-
117
- def chat(self, message: str) -> str:
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
-
127
-
128
- payload = {
129
- "text": message,
130
- "sessionId": self.conversation['id'] if self.conversation else None,
131
- "files": []
132
- }
133
-
134
-
135
- response = requests.post(
136
- f"{self.BASE_URL}/api/chat/completions",
137
- headers=self.headers,
138
- json=payload,
139
- stream=True
140
- )
141
-
142
- if response.status_code != 200:
143
- error_msg = f"Failed to chat: {response.status_code} {response.text}"
144
- PrettyOutput.print(error_msg, OutputType.WARNING)
145
- raise Exception(error_msg)
146
-
147
- # 处理流式响应
148
- full_response = ""
149
- for line in response.iter_lines():
150
- if line:
151
- line = line.decode('utf-8')
152
- if line.startswith('data: '):
153
- try:
154
- data = json.loads(line[6:])
155
- if data.get('type') == 'string':
156
- chunk = data.get('data', '')
157
- if chunk:
158
- full_response += chunk
159
- if not self.suppress_output:
160
- PrettyOutput.print_stream(chunk)
161
-
162
- except json.JSONDecodeError:
163
- continue
164
-
165
- if not self.suppress_output:
166
- PrettyOutput.print_stream_end()
167
-
168
- return full_response
169
-
170
- except Exception as e:
171
- PrettyOutput.print(f"对话异常: {str(e)}", OutputType.ERROR)
172
- raise e
173
-
174
- def name(self) -> str:
175
- """Return model name"""
176
- return self.model_name
177
-
178
-
179
- def delete_chat(self) -> bool:
180
- """Delete current chat session"""
181
- try:
182
- if not self.conversation:
183
- return True
184
-
185
-
186
- response = requests.delete(
187
- f"{self.BASE_URL}/api/chat/session/{self.conversation['id']}",
188
- headers=self.headers
189
- )
190
-
191
- if response.status_code == 200:
192
- data = response.json()
193
- if data['code'] == 0:
194
- self.conversation = None
195
- return True
196
- else:
197
- error_msg = f"删除会话失败: {data.get('msg', '未知错误')}"
198
- PrettyOutput.print(error_msg, OutputType.WARNING)
199
- return False
200
- else:
201
- error_msg = f"删除会话请求失败: {response.status_code}"
202
- PrettyOutput.print(error_msg, OutputType.WARNING)
203
- return False
204
-
205
- except Exception as e:
206
- PrettyOutput.print(f"删除会话失败: {str(e)}", OutputType.ERROR)
207
- return False
208
-
209
- def get_available_models(self) -> List[str]:
210
- """Get available model list
211
-
212
- Returns:
213
- List[str]: Available model name list
214
- """
215
- try:
216
- if self.models:
217
- return list(self.models.keys())
218
-
219
- response = requests.get(
220
- f"{self.BASE_URL}/api/chat/tmpl",
221
- headers=self.headers
222
- )
223
-
224
- if response.status_code != 200:
225
- PrettyOutput.print(f"获取模型列表失败: {response.status_code}", OutputType.WARNING)
226
- return []
227
-
228
- data = response.json()
229
- if data['code'] != 0:
230
- PrettyOutput.print(f"获取模型列表失败: {data.get('msg', '未知错误')}", OutputType.WARNING)
231
- return []
232
-
233
- # 保存模型信息
234
- self.models = {
235
- model['value']: model
236
- for model in data['data']['models']
237
- }
238
-
239
- for model in self.models.values():
240
- # 添加标签
241
- model_str = f"{model['label']}"
242
-
243
- # 添加特性标记
244
- features = []
245
- if model['attr'].get('multimodal'):
246
- features.append("Multimodal")
247
- if model['attr'].get('plugin'):
248
- features.append("Plugin support")
249
- if model['attr'].get('onlyImg'):
250
- features.append("Image support")
251
- if model['attr'].get('tag'):
252
- features.append(model['attr']['tag'])
253
- if model['attr'].get('integral'):
254
- features.append(model['attr']['integral'])
255
- # 添加备注
256
- if model['attr'].get('note'):
257
- model_str += f" - {model['attr']['note']}"
258
- if features:
259
- model_str += f" [{'|'.join(features)}]"
260
-
261
- model['desc'] = model_str
262
-
263
- return list(self.models.keys())
264
-
265
- except Exception as e:
266
- PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.ERROR)
267
- return []
268
-
@@ -1,137 +0,0 @@
1
- from typing import List, Dict, Tuple
2
- from jarvis.jarvis_platform.base import BasePlatform
3
- import os
4
-
5
- from jarvis.jarvis_utils.output import OutputType, PrettyOutput
6
-
7
-
8
- import ollama
9
-
10
- class OllamaPlatform(BasePlatform):
11
- """Ollama platform implementation"""
12
-
13
- platform_name = "ollama"
14
-
15
- def __init__(self):
16
- """Initialize model"""
17
- super().__init__()
18
-
19
- # Check environment variables and provide help information
20
- self.api_base = os.getenv("OLLAMA_API_BASE", "http://localhost:11434")
21
- self.model_name = os.getenv("JARVIS_MODEL") or "deepseek-r1:1.5b"
22
-
23
- # Setup client based on availability
24
- self.client = None
25
- self.client = ollama.Client(host=self.api_base)
26
-
27
- # Check if Ollama service is available
28
- try:
29
- available_models = self._get_available_models()
30
-
31
- if not available_models:
32
- message = (
33
- "需要先下载 Ollama 模型才能使用:\n"
34
- "1. 安装 Ollama: https://ollama.ai\n"
35
- "2. 下载模型:\n"
36
- f" ollama pull {self.model_name}"
37
- )
38
- PrettyOutput.print(message, OutputType.INFO)
39
- PrettyOutput.print("Ollama 没有可用的模型", OutputType.WARNING)
40
-
41
- except Exception as e:
42
- message = (
43
- f"Ollama 服务未启动或无法连接: {str(e)}\n"
44
- "请确保您已:\n"
45
- "1. 安装 Ollama: https://ollama.ai\n"
46
- "2. 启动 Ollama 服务\n"
47
- "3. 正确配置服务地址 (默认: http://localhost:11434)"
48
- )
49
- PrettyOutput.print(message, OutputType.WARNING)
50
-
51
-
52
- self.messages = []
53
- self.system_message = ""
54
-
55
- def _get_available_models(self) -> List[str]:
56
- """Get list of available models using appropriate method"""
57
- models_response = self.client.list() # type: ignore
58
- return [model["model"] for model in models_response.get("models", [])]
59
-
60
- def get_model_list(self) -> List[Tuple[str, str]]:
61
- """Get model list"""
62
- try:
63
- models = self._get_available_models()
64
- return [(model, "") for model in models]
65
- except Exception as e:
66
- PrettyOutput.print(f"获取模型列表失败: {str(e)}", OutputType.ERROR)
67
- return []
68
-
69
- def set_model_name(self, model_name: str):
70
- """Set model name"""
71
- self.model_name = model_name
72
-
73
- def chat(self, message: str) -> str:
74
- """Execute conversation"""
75
- try:
76
- # Build message list
77
- messages = []
78
- if self.system_message:
79
- messages.append({"role": "system", "content": self.system_message})
80
- messages.extend(self.messages)
81
- messages.append({"role": "user", "content": message})
82
-
83
- return self._chat_with_package(messages)
84
-
85
- except Exception as e:
86
- PrettyOutput.print(f"对话失败: {str(e)}", OutputType.ERROR)
87
- raise Exception(f"Chat failed: {str(e)}")
88
-
89
- def _chat_with_package(self, messages: List[Dict]) -> str:
90
- """Chat using the ollama package"""
91
- # The client should not be None here due to the check in the chat method
92
- if not self.client:
93
- raise ValueError("Ollama client is not initialized")
94
-
95
- # Use ollama-python's streaming API
96
- stream = self.client.chat(
97
- model=self.model_name,
98
- messages=messages,
99
- stream=True
100
- )
101
-
102
- # Process the streaming response
103
- full_response = ""
104
- for chunk in stream:
105
- if "message" in chunk and "content" in chunk["message"]:
106
- text = chunk["message"]["content"]
107
- if not self.suppress_output:
108
- PrettyOutput.print_stream(text)
109
- full_response += text
110
-
111
- if not self.suppress_output:
112
- PrettyOutput.print_stream_end()
113
-
114
- # Update message history
115
- self.messages.append({"role": "user", "content": messages[-1]["content"]})
116
- self.messages.append({"role": "assistant", "content": full_response})
117
-
118
- return full_response
119
-
120
-
121
- def name(self) -> str:
122
- """Return model name"""
123
- return self.model_name
124
-
125
- def delete_chat(self) -> bool:
126
- """Delete current chat session"""
127
- self.messages = []
128
- if self.system_message:
129
- self.messages.append({"role": "system", "content": self.system_message})
130
- return True
131
-
132
- def set_system_message(self, message: str):
133
- """Set system message"""
134
- self.system_message = message
135
- self.messages = []
136
- if self.system_message:
137
- self.messages.append({"role": "system", "content": self.system_message})