jarvis-ai-assistant 0.1.130__py3-none-any.whl → 0.1.132__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.
Files changed (72) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +71 -38
  3. jarvis/jarvis_agent/builtin_input_handler.py +73 -0
  4. jarvis/{jarvis_code_agent → jarvis_agent}/file_input_handler.py +1 -1
  5. jarvis/jarvis_agent/main.py +1 -1
  6. jarvis/{jarvis_code_agent → jarvis_agent}/patch.py +77 -55
  7. jarvis/{jarvis_code_agent → jarvis_agent}/shell_input_handler.py +1 -2
  8. jarvis/jarvis_code_agent/code_agent.py +93 -88
  9. jarvis/jarvis_dev/main.py +335 -626
  10. jarvis/jarvis_git_squash/main.py +11 -32
  11. jarvis/jarvis_lsp/base.py +2 -26
  12. jarvis/jarvis_lsp/cpp.py +2 -14
  13. jarvis/jarvis_lsp/go.py +0 -13
  14. jarvis/jarvis_lsp/python.py +1 -30
  15. jarvis/jarvis_lsp/registry.py +10 -14
  16. jarvis/jarvis_lsp/rust.py +0 -12
  17. jarvis/jarvis_multi_agent/__init__.py +20 -29
  18. jarvis/jarvis_platform/ai8.py +7 -32
  19. jarvis/jarvis_platform/base.py +2 -7
  20. jarvis/jarvis_platform/kimi.py +3 -144
  21. jarvis/jarvis_platform/ollama.py +54 -68
  22. jarvis/jarvis_platform/openai.py +0 -4
  23. jarvis/jarvis_platform/oyi.py +0 -75
  24. jarvis/jarvis_platform/registry.py +1 -1
  25. jarvis/jarvis_platform/yuanbao.py +264 -0
  26. jarvis/jarvis_platform_manager/main.py +3 -3
  27. jarvis/jarvis_rag/file_processors.py +138 -0
  28. jarvis/jarvis_rag/main.py +1305 -425
  29. jarvis/jarvis_tools/ask_codebase.py +227 -41
  30. jarvis/jarvis_tools/code_review.py +229 -166
  31. jarvis/jarvis_tools/create_code_agent.py +76 -72
  32. jarvis/jarvis_tools/create_sub_agent.py +32 -15
  33. jarvis/jarvis_tools/execute_python_script.py +58 -0
  34. jarvis/jarvis_tools/execute_shell.py +15 -28
  35. jarvis/jarvis_tools/execute_shell_script.py +2 -2
  36. jarvis/jarvis_tools/file_analyzer.py +271 -0
  37. jarvis/jarvis_tools/file_operation.py +3 -3
  38. jarvis/jarvis_tools/find_caller.py +213 -0
  39. jarvis/jarvis_tools/find_symbol.py +211 -0
  40. jarvis/jarvis_tools/function_analyzer.py +248 -0
  41. jarvis/jarvis_tools/git_commiter.py +89 -70
  42. jarvis/jarvis_tools/lsp_find_definition.py +83 -67
  43. jarvis/jarvis_tools/lsp_find_references.py +62 -46
  44. jarvis/jarvis_tools/lsp_get_diagnostics.py +90 -74
  45. jarvis/jarvis_tools/methodology.py +89 -48
  46. jarvis/jarvis_tools/project_analyzer.py +220 -0
  47. jarvis/jarvis_tools/read_code.py +24 -3
  48. jarvis/jarvis_tools/read_webpage.py +195 -81
  49. jarvis/jarvis_tools/registry.py +132 -11
  50. jarvis/jarvis_tools/search_web.py +73 -30
  51. jarvis/jarvis_tools/tool_generator.py +7 -9
  52. jarvis/jarvis_utils/__init__.py +1 -0
  53. jarvis/jarvis_utils/config.py +67 -3
  54. jarvis/jarvis_utils/embedding.py +344 -45
  55. jarvis/jarvis_utils/git_utils.py +18 -2
  56. jarvis/jarvis_utils/input.py +7 -4
  57. jarvis/jarvis_utils/methodology.py +379 -7
  58. jarvis/jarvis_utils/output.py +5 -3
  59. jarvis/jarvis_utils/utils.py +62 -10
  60. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/METADATA +3 -4
  61. jarvis_ai_assistant-0.1.132.dist-info/RECORD +82 -0
  62. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/entry_points.txt +2 -0
  63. jarvis/jarvis_c2rust/c2rust.yaml +0 -734
  64. jarvis/jarvis_code_agent/builtin_input_handler.py +0 -43
  65. jarvis/jarvis_codebase/__init__.py +0 -0
  66. jarvis/jarvis_codebase/main.py +0 -1011
  67. jarvis/jarvis_tools/lsp_get_document_symbols.py +0 -87
  68. jarvis/jarvis_tools/lsp_prepare_rename.py +0 -130
  69. jarvis_ai_assistant-0.1.130.dist-info/RECORD +0 -79
  70. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/LICENSE +0 -0
  71. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/WHEEL +0 -0
  72. {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.132.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,4 @@
1
+ import re
1
2
  import sys
2
3
  import argparse
3
4
  from typing import Dict, Any
@@ -18,7 +19,7 @@ class GitSquashTool:
18
19
  """Perform soft reset to specified commit hash"""
19
20
  try:
20
21
  subprocess.Popen(
21
- ["git", "reset", "--soft", commit_hash],
22
+ ["git", "reset", "--mixed", commit_hash],
22
23
  stdout=subprocess.DEVNULL,
23
24
  stderr=subprocess.DEVNULL
24
25
  ).wait()
@@ -26,39 +27,23 @@ class GitSquashTool:
26
27
  except Exception:
27
28
  return False
28
29
 
29
- def execute(self, args: Dict) -> Dict[str, Any]:
30
+ def execute(self, args: Dict):
30
31
  """Execute the squash operation"""
31
32
  try:
32
33
  if not self._confirm_squash():
33
- return {
34
- "success": False,
35
- "stdout": "Operation cancelled",
36
- "stderr": ""
37
- }
34
+ PrettyOutput.print("操作已取消", OutputType.WARNING)
35
+ return
38
36
 
39
37
  if not self._reset_to_commit(args['commit_hash']):
40
- return {
41
- "success": False,
42
- "stdout": "",
43
- "stderr": "Failed to reset to specified commit"
44
- }
38
+ PrettyOutput.print("重置到指定提交失败", OutputType.WARNING)
39
+ return
45
40
 
46
41
  # Use existing GitCommitTool for new commit
47
42
  commit_tool = GitCommitTool()
48
- result = commit_tool.execute({"lang": args.get('lang', 'Chinese')})
49
-
50
- return {
51
- "success": result['success'],
52
- "stdout": result['stdout'],
53
- "stderr": result['stderr']
54
- }
55
-
43
+ commit_tool.execute({"lang": args.get('lang', 'Chinese')})
56
44
  except Exception as e:
57
- return {
58
- "success": False,
59
- "stdout": "",
60
- "stderr": f"Squash failed: {str(e)}"
61
- }
45
+ PrettyOutput.print(f"压缩提交失败: {str(e)}", OutputType.WARNING)
46
+
62
47
  def main():
63
48
  init_env()
64
49
  parser = argparse.ArgumentParser(description='Git squash tool')
@@ -67,15 +52,9 @@ def main():
67
52
  args = parser.parse_args()
68
53
 
69
54
  tool = GitSquashTool()
70
- result = tool.execute({
55
+ tool.execute({
71
56
  'commit_hash': args.commit_hash,
72
57
  'lang': args.lang
73
58
  })
74
-
75
- if not result['success']:
76
- PrettyOutput.print(result['stderr'], OutputType.ERROR)
77
- sys.exit(1)
78
-
79
- PrettyOutput.print(result['stdout'], OutputType.SUCCESS)
80
59
  if __name__ == "__main__":
81
60
  sys.exit(main())
jarvis/jarvis_lsp/base.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import List, Dict, Optional, Tuple, Any
2
+ from typing import List, Dict, Optional, Tuple, Any, Union
3
3
 
4
4
  class BaseLSP(ABC):
5
5
  """Base class for Language Server Protocol integration.
@@ -11,7 +11,7 @@ class BaseLSP(ABC):
11
11
  4. Symbol analysis
12
12
  """
13
13
 
14
- language: str = "" # Language identifier, should be overridden by subclasses
14
+ language: Union[str, List[str]] = "" # Language identifier, should be overridden by subclasses
15
15
 
16
16
  @abstractmethod
17
17
  def initialize(self, workspace_path: str) -> bool:
@@ -67,17 +67,6 @@ class BaseLSP(ABC):
67
67
  """
68
68
  return None
69
69
 
70
- @abstractmethod
71
- def get_document_symbols(self, file_path: str) -> List[Dict[str, Any]]:
72
- """Get all symbols in document.
73
-
74
- Args:
75
- file_path: Path to the file
76
-
77
- Returns:
78
- List of symbols with their locations and types
79
- """
80
- return []
81
70
 
82
71
  @abstractmethod
83
72
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
@@ -112,19 +101,6 @@ class BaseLSP(ABC):
112
101
  """
113
102
  return []
114
103
 
115
- @abstractmethod
116
- def prepare_rename(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
117
- """Check if symbol at position can be renamed.
118
-
119
- Args:
120
- file_path: Path to the file
121
- position: Symbol position
122
-
123
- Returns:
124
- Range that would be renamed or None if rename not allowed
125
- """
126
- return None
127
-
128
104
 
129
105
  def shutdown(self):
130
106
  """Shutdown LSP server cleanly."""
jarvis/jarvis_lsp/cpp.py CHANGED
@@ -9,7 +9,7 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
9
  class CPPLSP(BaseLSP):
10
10
  """C++ LSP implementation using clangd."""
11
11
 
12
- language = "cpp"
12
+ language = ["cpp", "c"]
13
13
 
14
14
  @staticmethod
15
15
  def check() -> bool:
@@ -80,12 +80,7 @@ class CPPLSP(BaseLSP):
80
80
  "position": {"line": position[0], "character": position[1]}
81
81
  })
82
82
  return result[0] if result else None
83
-
84
- def get_document_symbols(self, file_path: str) -> List[Dict[str, Any]]:
85
- result = self._send_request("textDocument/documentSymbol", {
86
- "textDocument": {"uri": f"file://{file_path}"}
87
- })
88
- return result or [] # type: ignore
83
+
89
84
 
90
85
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
91
86
  # Send didOpen notification to trigger diagnostics
@@ -107,13 +102,6 @@ class CPPLSP(BaseLSP):
107
102
  pass
108
103
  return []
109
104
 
110
- def prepare_rename(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
111
- result = self._send_request("textDocument/prepareRename", {
112
- "textDocument": {"uri": f"file://{file_path}"},
113
- "position": {"line": position[0], "character": position[1]}
114
- })
115
- return result
116
-
117
105
 
118
106
  def shutdown(self):
119
107
  if self.clangd_process:
jarvis/jarvis_lsp/go.py CHANGED
@@ -87,12 +87,6 @@ class GoLSP(BaseLSP):
87
87
  })
88
88
  return result[0] if result else None
89
89
 
90
- def get_document_symbols(self, file_path: str) -> List[Dict[str, Any]]:
91
- result = self._send_request("textDocument/documentSymbol", {
92
- "textDocument": {"uri": f"file://{file_path}"}
93
- })
94
- return result or [] # type: ignore
95
-
96
90
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
97
91
  # Send didOpen notification to trigger diagnostics
98
92
  self._send_request("textDocument/didOpen", {
@@ -113,13 +107,6 @@ class GoLSP(BaseLSP):
113
107
  pass
114
108
  return []
115
109
 
116
- def prepare_rename(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
117
- result = self._send_request("textDocument/prepareRename", {
118
- "textDocument": {"uri": f"file://{file_path}"},
119
- "position": {"line": position[0], "character": position[1]}
120
- })
121
- return result
122
-
123
110
 
124
111
  def shutdown(self):
125
112
  if self.gopls_process:
@@ -18,7 +18,7 @@ class PythonLSP(BaseLSP):
18
18
  def _get_script(self, file_path: str):
19
19
  if file_path not in self.script_cache:
20
20
  try:
21
- with open(file_path, 'r') as f:
21
+ with open(file_path, 'r', errors="ignore") as f:
22
22
  content = f.read()
23
23
  self.script_cache[file_path] = jedi.Script(code=content, path=file_path)
24
24
  except Exception:
@@ -54,16 +54,6 @@ class PythonLSP(BaseLSP):
54
54
  }
55
55
  }
56
56
 
57
- def get_document_symbols(self, file_path: str) -> List[Dict[str, Any]]:
58
- script = self._get_script(file_path)
59
- if not script:
60
- return []
61
- try:
62
- names = script.get_names()
63
- return [self._location_to_dict(name) for name in names]
64
- except Exception:
65
- return []
66
-
67
57
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
68
58
  script = self._get_script(file_path)
69
59
  if not script:
@@ -82,24 +72,5 @@ class PythonLSP(BaseLSP):
82
72
  except Exception:
83
73
  return []
84
74
 
85
- def prepare_rename(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
86
- script = self._get_script(file_path)
87
- if not script:
88
- return None
89
- try:
90
- refs = script.get_references(line=position[0] + 1, column=position[1])
91
- if refs:
92
- ref = refs[0]
93
- return {
94
- "range": {
95
- "start": {"line": ref.line - 1, "character": ref.column},
96
- "end": {"line": ref.line - 1, "character": ref.column + len(ref.name)}
97
- }
98
- }
99
- except Exception:
100
- return None
101
- return None
102
-
103
-
104
75
  def shutdown(self):
105
76
  self.script_cache.clear()
@@ -11,9 +11,7 @@ REQUIRED_METHODS = [
11
11
  ('initialize', ['workspace_path']),
12
12
  ('find_references', ['file_path', 'position']),
13
13
  ('find_definition', ['file_path', 'position']),
14
- ('get_document_symbols', ['file_path']),
15
14
  ('get_diagnostics', ['file_path']),
16
- ('prepare_rename', ['file_path', 'position']),
17
15
  ('shutdown', [])
18
16
  ]
19
17
 
@@ -29,7 +27,7 @@ class LSPRegistry:
29
27
  if not os.path.exists(user_lsp_dir):
30
28
  try:
31
29
  os.makedirs(user_lsp_dir)
32
- with open(os.path.join(user_lsp_dir, "__init__.py"), "w") as f:
30
+ with open(os.path.join(user_lsp_dir, "__init__.py"), "w", errors="ignore") as f:
33
31
  pass
34
32
  except Exception as e:
35
33
  PrettyOutput.print(f"创建 LSP 目录失败: {str(e)}", OutputType.ERROR)
@@ -100,7 +98,11 @@ class LSPRegistry:
100
98
  if hasattr(obj, 'check'):
101
99
  if not obj.check(): # type: ignore
102
100
  continue
103
- lsp_servers[obj.language] = obj
101
+ if isinstance(obj.language, str):
102
+ lsp_servers[obj.language] = obj
103
+ elif isinstance(obj.language, list):
104
+ for lang in obj.language: # type: ignore
105
+ lsp_servers[lang] = obj
104
106
  break
105
107
  except Exception as e:
106
108
  PrettyOutput.print(f"加载 LSP {module_name} 失败: {str(e)}", OutputType.ERROR)
@@ -154,7 +156,7 @@ class LSPRegistry:
154
156
  @staticmethod
155
157
  def get_text_at_position(file_path: str, line: int, start_character: int) -> str:
156
158
  """Get text at position."""
157
- with open(file_path, 'r') as file:
159
+ with open(file_path, 'r', errors="ignore") as file:
158
160
  lines = file.readlines()
159
161
  symbol = re.search(r'\b\w+\b', lines[line][start_character:])
160
162
  return symbol.group() if symbol else ""
@@ -162,7 +164,7 @@ class LSPRegistry:
162
164
  @staticmethod
163
165
  def get_line_at_position(file_path: str, line: int) -> str:
164
166
  """Get line at position."""
165
- with open(file_path, 'r') as file:
167
+ with open(file_path, 'r', errors="ignore") as file:
166
168
  lines = file.readlines()
167
169
  return lines[line]
168
170
 
@@ -192,14 +194,8 @@ def main():
192
194
  PrettyOutput.print("LSP 初始化失败", OutputType.WARNING)
193
195
  return 1
194
196
 
195
- try:
196
- # Execute requested action
197
- if args.action == 'symbols':
198
- symbols = lsp.get_document_symbols(args.file)
199
- for symbol in symbols:
200
- print(f"Symbol {LSPRegistry.get_text_at_position(args.file, symbol['range']['start']['line'], symbol['range']['start']['character'])} at {symbol['range']['start']['line']}:{symbol['range']['start']['character']}: {symbol['uri']}")
201
-
202
- elif args.action == 'diagnostics':
197
+ try:
198
+ if args.action == 'diagnostics':
203
199
  diagnostics = lsp.get_diagnostics(args.file)
204
200
  for diag in diagnostics:
205
201
  severity = ['Error', 'Warning', 'Info', 'Hint'][diag['severity'] - 1]
jarvis/jarvis_lsp/rust.py CHANGED
@@ -89,11 +89,6 @@ class RustLSP(BaseLSP):
89
89
  })
90
90
  return result[0] if result else None
91
91
 
92
- def get_document_symbols(self, file_path: str) -> List[Dict[str, Any]]:
93
- result = self._send_request("textDocument/documentSymbol", {
94
- "textDocument": {"uri": f"file://{file_path}"}
95
- })
96
- return result or [] # type: ignore
97
92
 
98
93
  def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
99
94
  # Send didOpen notification to trigger diagnostics
@@ -115,13 +110,6 @@ class RustLSP(BaseLSP):
115
110
  pass
116
111
  return []
117
112
 
118
- def prepare_rename(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
119
- result = self._send_request("textDocument/prepareRename", {
120
- "textDocument": {"uri": f"file://{file_path}"},
121
- "position": {"line": position[0], "character": position[1]}
122
- })
123
- return result
124
-
125
113
 
126
114
  def shutdown(self):
127
115
  if self.analyzer_process:
@@ -8,7 +8,7 @@ from jarvis.jarvis_agent.output_handler import OutputHandler
8
8
  from jarvis.jarvis_tools.registry import ToolRegistry
9
9
  from jarvis.jarvis_utils.input import get_multiline_input
10
10
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
11
- from jarvis.jarvis_utils.utils import init_env
11
+ from jarvis.jarvis_utils.utils import ct, ot, init_env
12
12
 
13
13
 
14
14
  class MultiAgent(OutputHandler):
@@ -20,12 +20,7 @@ class MultiAgent(OutputHandler):
20
20
 
21
21
  def prompt(self) -> str:
22
22
  return f"""
23
- # 多智能体协作系统
24
-
25
- ## 身份与角色定位
26
- - **核心职责**:作为多智能体系统的协调者,通过结构化消息实现高效协作
27
- - **关键能力**:消息路由、任务分发、结果整合、流程协调
28
- - **工作范围**:在多个专业智能体之间建立有效沟通渠道
23
+ # 多智能体消息发送
29
24
 
30
25
  ## 交互原则与策略
31
26
  ### 消息处理规范
@@ -36,7 +31,7 @@ class MultiAgent(OutputHandler):
36
31
 
37
32
  ### 消息格式标准
38
33
  ```
39
- <SEND_MESSAGE>
34
+ {ot("SEND_MESSAGE")}
40
35
  to: 智能体名称 # 目标智能体名称
41
36
  content: |
42
37
  # 消息主题
@@ -52,31 +47,27 @@ content: |
52
47
 
53
48
  ## 期望结果
54
49
  [描述期望的输出格式和内容]
55
- </SEND_MESSAGE>
50
+
51
+ ## 下一步计划
52
+ [描述下一步的计划和行动]
53
+ {ct("SEND_MESSAGE")}
56
54
  ```
57
55
 
58
- ## 协作流程规范
59
- ### 任务分发流程
60
- 1. **需求分析**:理解用户需求并确定最适合的智能体
61
- 2. **任务分解**:将复杂任务分解为可管理的子任务
62
- 3. **精准分发**:根据专长将任务分配给合适的智能体
63
- 4. **结果整合**:收集各智能体的输出并整合为连贯结果
56
+ 或者:
64
57
 
65
- ### 消息流控制
66
- 1. **单向流动**:发送消息后等待响应,避免消息风暴
67
- 2. **优先级管理**:处理紧急消息优先,保持任务顺序
68
- 3. **状态跟踪**:记录每个任务的当前状态和处理进度
69
- 4. **异常处理**:优雅处理超时、错误和意外响应
58
+ ```
59
+ {ot("SEND_MESSAGE")}
60
+ to: 智能体名称 # 目标智能体名称
61
+ content: |
62
+ # 消息主题
63
+
64
+ ## 任务结果
65
+ [任务完成结果,用于反馈]
66
+ {ct("SEND_MESSAGE")}
67
+ ```
70
68
 
71
69
  ## 可用智能体资源
72
70
  {chr(10).join([f"- **{c['name']}**: {c.get('description', '')}" for c in self.agents_config])}
73
-
74
- ## 最佳实践指南
75
- 1. **任务明确化**:每个消息专注于单一、明确的任务
76
- 2. **信息充分性**:提供足够信息让接收者能独立完成任务
77
- 3. **反馈循环**:建立清晰的反馈机制,及时调整方向
78
- 4. **知识共享**:确保关键信息在相关智能体间共享
79
- 5. **协作效率**:避免不必要的消息传递,减少协调开销
80
71
  """
81
72
 
82
73
  def can_handle(self, response: str) -> bool:
@@ -102,7 +93,7 @@ content: |
102
93
  Args:
103
94
  content: The content containing send message
104
95
  """
105
- data = re.findall(r'<SEND_MESSAGE>(.*?)</SEND_MESSAGE>', content, re.DOTALL)
96
+ data = re.findall(ot("SEND_MESSAGE")+r'\n(.*?)\n'+ct("SEND_MESSAGE"), content, re.DOTALL)
106
97
  ret = []
107
98
  for item in data:
108
99
  try:
@@ -163,7 +154,7 @@ def main():
163
154
  args = parser.parse_args()
164
155
 
165
156
  try:
166
- with open(args.config, 'r') as f:
157
+ with open(args.config, 'r', errors="ignore") as f:
167
158
  config_data = yaml.safe_load(f)
168
159
 
169
160
  # 获取agents配置
@@ -23,7 +23,6 @@ class AI8Model(BasePlatform):
23
23
  super().__init__()
24
24
  self.system_message = ""
25
25
  self.conversation = {}
26
- self.files = []
27
26
  self.models = {} # 存储模型信息
28
27
 
29
28
  self.token = os.getenv("AI8_API_KEY")
@@ -103,18 +102,6 @@ class AI8Model(BasePlatform):
103
102
  except Exception as e:
104
103
  PrettyOutput.print(f"创建会话失败: {str(e)}", OutputType.ERROR)
105
104
  return False
106
-
107
- def upload_files(self, file_list: List[str]) -> List[Dict]:
108
- for file_path in file_list:
109
- name = os.path.basename(file_path)
110
- with open(file_path, 'rb') as f:
111
- file_data = f.read()
112
- base64_data = base64.b64encode(file_data).decode('utf-8')
113
- self.files.append({
114
- "name": name,
115
- "data": f"data:image/png;base64,{base64_data}"
116
- })
117
- return self.files
118
105
 
119
106
  def set_system_message(self, message: str):
120
107
  """Set system message"""
@@ -145,14 +132,6 @@ class AI8Model(BasePlatform):
145
132
  "files": []
146
133
  }
147
134
 
148
- # 如果有文件需要发送
149
- if self.files:
150
- for file_data in self.files:
151
- payload["files"].append({
152
- "name": file_data["name"],
153
- "data": file_data["data"]
154
- })
155
- self.files = [] # 清空已使用的文件
156
135
 
157
136
  response = requests.post(
158
137
  f"{self.BASE_URL}/api/chat/completions",
@@ -200,7 +179,6 @@ class AI8Model(BasePlatform):
200
179
  def reset(self):
201
180
  """Reset model state"""
202
181
  self.conversation = None
203
- self.files = [] # 清空文件列表
204
182
 
205
183
  def delete_chat(self) -> bool:
206
184
  """Delete current chat session"""
@@ -284,13 +262,6 @@ class AI8Model(BasePlatform):
284
262
  # 添加标签
285
263
  model_str = f"{model['label']}"
286
264
 
287
- # 添加标签和积分信息
288
- attrs = []
289
- if model['attr'].get('tag'):
290
- attrs.append(model['attr']['tag'])
291
- if model['attr'].get('integral'):
292
- attrs.append(model['attr']['integral'])
293
-
294
265
  # 添加特性标记
295
266
  features = []
296
267
  if model['attr'].get('multimodal'):
@@ -299,12 +270,16 @@ class AI8Model(BasePlatform):
299
270
  features.append("Plugin support")
300
271
  if model['attr'].get('onlyImg'):
301
272
  features.append("Image support")
302
- if features:
303
- model_str += f" [{'|'.join(features)}]"
304
-
273
+ if model['attr'].get('tag'):
274
+ features.append(model['attr']['tag'])
275
+ if model['attr'].get('integral'):
276
+ features.append(model['attr']['integral'])
305
277
  # 添加备注
306
278
  if model['attr'].get('note'):
307
279
  model_str += f" - {model['attr']['note']}"
280
+ if features:
281
+ model_str += f" [{'|'.join(features)}]"
282
+
308
283
  model['desc'] = model_str
309
284
 
310
285
  return list(self.models.keys())
@@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
2
2
  import re
3
3
  from typing import Dict, List, Tuple
4
4
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
5
- from jarvis.jarvis_utils.utils import get_context_token_count, while_success, while_true
5
+ from jarvis.jarvis_utils.utils import ct, ot, get_context_token_count, while_success, while_true
6
6
 
7
7
 
8
8
  class BasePlatform(ABC):
@@ -53,16 +53,11 @@ class BasePlatform(ABC):
53
53
  )
54
54
 
55
55
  # Keep original think tag handling
56
- response = re.sub(r'<think>.*?</think>', '', response, flags=re.DOTALL)
56
+ response = re.sub(ot("think")+r'.*?'+ct("think"), '', response, flags=re.DOTALL)
57
57
  return response
58
58
 
59
59
  return while_true(lambda: while_success(lambda: _chat(), 5), 5)
60
60
 
61
- @abstractmethod
62
- def upload_files(self, file_list: List[str]) -> List[Dict]:
63
- """Upload files"""
64
- raise NotImplementedError("upload_files is not implemented")
65
-
66
61
  @abstractmethod
67
62
  def reset(self):
68
63
  """Reset model"""