jarvis-ai-assistant 0.1.115__py3-none-any.whl → 0.1.117__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 (51) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/{agent.py → jarvis_agent/__init__.py} +122 -203
  3. jarvis/jarvis_agent/output_handler.py +23 -0
  4. jarvis/jarvis_code_agent/code_agent.py +113 -100
  5. jarvis/jarvis_code_agent/file_select.py +28 -7
  6. jarvis/jarvis_code_agent/patch.py +80 -2
  7. jarvis/jarvis_code_agent/relevant_files.py +82 -42
  8. jarvis/jarvis_codebase/main.py +53 -25
  9. jarvis/jarvis_dev/main.py +719 -547
  10. jarvis/jarvis_lsp/cpp.py +1 -1
  11. jarvis/jarvis_lsp/go.py +1 -1
  12. jarvis/jarvis_lsp/registry.py +1 -1
  13. jarvis/jarvis_lsp/rust.py +1 -1
  14. jarvis/jarvis_multi_agent/__init__.py +170 -0
  15. jarvis/jarvis_platform/ai8.py +2 -2
  16. jarvis/jarvis_platform/base.py +14 -4
  17. jarvis/jarvis_platform/kimi.py +2 -2
  18. jarvis/jarvis_platform/ollama.py +1 -1
  19. jarvis/jarvis_platform/openai.py +1 -1
  20. jarvis/jarvis_platform/oyi.py +1 -1
  21. jarvis/jarvis_platform/registry.py +1 -1
  22. jarvis/jarvis_platform_manager/main.py +422 -6
  23. jarvis/jarvis_platform_manager/openai_test.py +139 -0
  24. jarvis/jarvis_rag/main.py +57 -20
  25. jarvis/jarvis_smart_shell/main.py +55 -29
  26. jarvis/jarvis_tools/ask_codebase.py +1 -1
  27. jarvis/jarvis_tools/ask_user.py +1 -1
  28. jarvis/jarvis_tools/chdir.py +1 -1
  29. jarvis/jarvis_tools/code_review.py +3 -3
  30. jarvis/jarvis_tools/create_code_agent.py +1 -1
  31. jarvis/jarvis_tools/create_sub_agent.py +2 -2
  32. jarvis/jarvis_tools/execute_shell.py +1 -1
  33. jarvis/jarvis_tools/file_operation.py +16 -14
  34. jarvis/jarvis_tools/git_commiter.py +2 -2
  35. jarvis/jarvis_tools/methodology.py +1 -1
  36. jarvis/jarvis_tools/rag.py +1 -1
  37. jarvis/jarvis_tools/read_code.py +19 -8
  38. jarvis/jarvis_tools/read_webpage.py +1 -1
  39. jarvis/jarvis_tools/registry.py +157 -31
  40. jarvis/jarvis_tools/search.py +1 -1
  41. jarvis/jarvis_tools/select_code_files.py +1 -1
  42. jarvis/{utils.py → jarvis_utils/__init__.py} +69 -53
  43. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/METADATA +1 -1
  44. jarvis_ai_assistant-0.1.117.dist-info/RECORD +65 -0
  45. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/WHEEL +1 -1
  46. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/entry_points.txt +1 -1
  47. jarvis/multi_agent.py +0 -76
  48. jarvis/utils/date_utils.py +0 -19
  49. jarvis_ai_assistant-0.1.115.dist-info/RECORD +0 -64
  50. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/LICENSE +0 -0
  51. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/top_level.txt +0 -0
jarvis/jarvis_lsp/cpp.py CHANGED
@@ -4,7 +4,7 @@ import subprocess
4
4
  from typing import List, Dict, Optional, Tuple, Any
5
5
  import json
6
6
  from jarvis.jarvis_lsp.base import BaseLSP
7
- from jarvis.utils import PrettyOutput, OutputType
7
+ from jarvis.jarvis_utils import PrettyOutput, OutputType
8
8
 
9
9
  class CPPLSP(BaseLSP):
10
10
  """C++ LSP implementation using clangd."""
jarvis/jarvis_lsp/go.py CHANGED
@@ -4,7 +4,7 @@ import subprocess
4
4
  from typing import List, Dict, Optional, Tuple, Any
5
5
  import json
6
6
  from jarvis.jarvis_lsp.base import BaseLSP
7
- from jarvis.utils import PrettyOutput, OutputType
7
+ from jarvis.jarvis_utils import PrettyOutput, OutputType
8
8
 
9
9
  class GoLSP(BaseLSP):
10
10
  """Go LSP implementation using gopls."""
@@ -5,7 +5,7 @@ import re
5
5
  import sys
6
6
  from typing import Dict, Type, Optional, List
7
7
  from jarvis.jarvis_lsp.base import BaseLSP
8
- from jarvis.utils import PrettyOutput, OutputType
8
+ from jarvis.jarvis_utils import PrettyOutput, OutputType
9
9
 
10
10
  REQUIRED_METHODS = [
11
11
  ('initialize', ['workspace_path']),
jarvis/jarvis_lsp/rust.py CHANGED
@@ -4,7 +4,7 @@ import subprocess
4
4
  from typing import List, Dict, Optional, Tuple, Any
5
5
  import json
6
6
  from jarvis.jarvis_lsp.base import BaseLSP
7
- from jarvis.utils import PrettyOutput, OutputType
7
+ from jarvis.jarvis_utils import PrettyOutput, OutputType
8
8
 
9
9
  class RustLSP(BaseLSP):
10
10
  """Rust LSP implementation using rust-analyzer."""
@@ -0,0 +1,170 @@
1
+ import re
2
+ from typing import Any, Dict, List, Optional, Tuple
3
+
4
+ import yaml
5
+
6
+ from jarvis.jarvis_agent import Agent
7
+ from jarvis.jarvis_agent.output_handler import OutputHandler
8
+ from jarvis.jarvis_utils import OutputType, PrettyOutput
9
+
10
+
11
+ class AgentConfig:
12
+ def __init__(self, **config):
13
+ self.system_prompt = config.get('system_prompt', '')
14
+ self.name = config.get('name', 'Jarvis')
15
+ self.description = config.get('description', '')
16
+ self.is_sub_agent = config.get('is_sub_agent', False)
17
+ self.output_handler = config.get('output_handler', [])
18
+ self.platform = config.get('platform')
19
+ self.model_name = config.get('model_name')
20
+ self.summary_prompt = config.get('summary_prompt')
21
+ self.auto_complete = config.get('auto_complete', False)
22
+ self.input_handler = config.get('input_handler')
23
+ self.max_context_length = config.get('max_context_length')
24
+ self.execute_tool_confirm = config.get('execute_tool_confirm')
25
+
26
+ class MultiAgent(OutputHandler):
27
+ def __init__(self, configs: List[AgentConfig], main_agent_name: str):
28
+ self.agents_config = configs
29
+ self.agents = {}
30
+ self.init_agents()
31
+ self.main_agent_name = main_agent_name
32
+
33
+ def prompt(self) -> str:
34
+ return f"""
35
+ # 🤖 Message Handling System
36
+ You are part of a multi-agent system that communicates through structured messages.
37
+
38
+ # 🎯 Core Rules
39
+ ## Critical Action Rules
40
+ - Execute ONLY ONE action per turn:
41
+ - Either use ONE tool (file_operation, ask_user, etc.)
42
+ - OR send ONE message to another agent
43
+ - NEVER combine both in same turn
44
+
45
+ ## Message Flow Control
46
+ - Wait for response after sending message
47
+ - Process response before next action
48
+ - Never send multiple messages at once
49
+ - Never combine messages with tool calls
50
+
51
+ # 📝 Message Format
52
+ ```
53
+ <SEND_MESSAGE>
54
+ to: agent_name # Target agent name
55
+ content: |
56
+ message_content # Message content
57
+ use multiple lines # If needed
58
+ with proper indentation
59
+ </SEND_MESSAGE>
60
+ ```
61
+
62
+ # 🔄 Action Sequence
63
+ 1. Choose Most Important Action
64
+ - Evaluate priority
65
+ - Select ONE action
66
+ - Execute action
67
+
68
+ 2. Wait for Response
69
+ - Process result/response
70
+ - Plan next action
71
+ - Wait for next turn
72
+
73
+ 3. Handle Responses
74
+ - Process incoming messages
75
+ - Reply to sender when needed
76
+ - Continue task based on response
77
+
78
+ # 👥 Available Agents
79
+ {chr(10).join([f"- {c.name}: {c.description}" for c in self.agents_config])}
80
+
81
+ # ❗ Important Rules
82
+ 1. ONE action per turn only
83
+ 2. Wait for responses
84
+ 3. Process before next action
85
+ 4. Reply to messages
86
+ 5. Forward task if needed
87
+
88
+ # 💡 Tips
89
+ - First action will be executed
90
+ - Additional actions will be ignored
91
+ - Always process responses first
92
+ - Send message to continue task if needed
93
+ - Handle and reply to received messages
94
+ """
95
+
96
+ def can_handle(self, response: str) -> bool:
97
+ return len(self._extract_send_msg(response)) > 0
98
+
99
+
100
+ def handle(self, response: str) -> Tuple[bool, Any]:
101
+ send_messages = self._extract_send_msg(response)
102
+ if len(send_messages) > 1:
103
+ return False, f"Send multiple messages, please only send one message at a time."
104
+ if len(send_messages) == 0:
105
+ return False, ""
106
+ return True, send_messages[0]
107
+
108
+ def name(self) -> str:
109
+ return "SEND_MESSAGE"
110
+
111
+
112
+ @staticmethod
113
+ def _extract_send_msg(content: str) -> List[Dict]:
114
+ """Extract send message from content.
115
+
116
+ Args:
117
+ content: The content containing send message
118
+ """
119
+ data = re.findall(r'<SEND_MESSAGE>(.*?)</SEND_MESSAGE>', content, re.DOTALL)
120
+ ret = []
121
+ for item in data:
122
+ try:
123
+ msg = yaml.safe_load(item)
124
+ if 'to' in msg and 'content' in msg:
125
+ ret.append(msg)
126
+ except Exception as e:
127
+ continue
128
+ return ret
129
+
130
+ def init_agents(self):
131
+ for agent_config in self.agents_config:
132
+ agent = Agent(system_prompt=agent_config.system_prompt,
133
+ name=agent_config.name,
134
+ description=agent_config.description,
135
+ model_name=agent_config.model_name,
136
+ platform=agent_config.platform,
137
+ max_context_length=agent_config.max_context_length,
138
+ execute_tool_confirm=agent_config.execute_tool_confirm,
139
+ input_handler=agent_config.input_handler,
140
+ use_methodology=False,
141
+ record_methodology=False,
142
+ need_summary=False,
143
+ auto_complete=agent_config.auto_complete,
144
+ summary_prompt=agent_config.summary_prompt,
145
+ is_sub_agent=agent_config.is_sub_agent,
146
+ output_handler=[*agent_config.output_handler, self],
147
+ )
148
+
149
+ self.agents[agent_config.name] = agent
150
+
151
+ def run(self, user_input: str, file_list: Optional[List[str]] = None) -> str:
152
+ last_agent = self.main_agent_name
153
+ msg = self.agents[self.main_agent_name].run(user_input, file_list)
154
+ while msg:
155
+ if isinstance(msg, str):
156
+ return msg
157
+ elif isinstance(msg, Dict):
158
+ prompt = f"""
159
+ Please handle this message:
160
+ from: {last_agent}
161
+ content: {msg['content']}
162
+ """
163
+ if msg['to'] not in self.agents:
164
+ PrettyOutput.print(f"没有找到{msg['to']},重试...", OutputType.WARNING)
165
+ msg = self.agents[last_agent].run(f"The agent {msg['to']} is not found, agent list: {self.agents.keys()}")
166
+ continue
167
+ PrettyOutput.print(f"{last_agent} 发送消息给 {msg['to']}...", OutputType.INFO)
168
+ last_agent = self.agents[msg['to']].name
169
+ msg = self.agents[msg['to']].run(prompt)
170
+ return ""
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  from typing import Dict, List, Tuple
3
3
  from jarvis.jarvis_platform.base import BasePlatform
4
- from jarvis.utils import PrettyOutput, OutputType
4
+ from jarvis.jarvis_utils import PrettyOutput, OutputType
5
5
  import requests
6
6
  import json
7
7
  import base64
@@ -260,7 +260,7 @@ class AI8Model(BasePlatform):
260
260
  }
261
261
 
262
262
  response = requests.get(
263
- f"{self.BASE_URL}/api/chat/template",
263
+ f"{self.BASE_URL}/api/chat/tmpl",
264
264
  headers=headers
265
265
  )
266
266
 
@@ -2,7 +2,9 @@ from abc import ABC, abstractmethod
2
2
  import re
3
3
  from typing import Dict, List, Tuple
4
4
 
5
- from jarvis.utils import while_success, while_true
5
+ from jarvis.jarvis_utils import OutputType, PrettyOutput, while_success, while_true
6
+ from yaspin import yaspin
7
+ from yaspin.spinners import Spinners
6
8
 
7
9
 
8
10
  class BasePlatform(ABC):
@@ -28,9 +30,17 @@ class BasePlatform(ABC):
28
30
 
29
31
  def chat_until_success(self, message: str) -> str:
30
32
  def _chat():
31
- response = self.chat(message)
32
- response = re.sub(r'<think>(.*?)</think>', '', response, flags=re.DOTALL)
33
- return response
33
+ if self.suppress_output:
34
+ with yaspin(Spinners.dots, text="Thinking", color="yellow") as spinner:
35
+ response = self.chat(message)
36
+ response = re.sub(r'<think>(.*?)</think>', '', response, flags=re.DOTALL)
37
+ spinner.ok("✓")
38
+ return response
39
+ else:
40
+ response = self.chat(message)
41
+ response = re.sub(r'<think>(.*?)</think>', '', response, flags=re.DOTALL)
42
+ return response
43
+
34
44
  return while_true(lambda: while_success(lambda: _chat(), 5), 5)
35
45
 
36
46
  @abstractmethod
@@ -5,8 +5,8 @@ import os
5
5
  import mimetypes
6
6
  import time
7
7
  from jarvis.jarvis_platform.base import BasePlatform
8
- from jarvis.utils import PrettyOutput, OutputType
9
- from jarvis.utils import while_success
8
+ from jarvis.jarvis_utils import PrettyOutput, OutputType
9
+ from jarvis.jarvis_utils import while_success
10
10
 
11
11
  class KimiModel(BasePlatform):
12
12
  """Kimi model implementation"""
@@ -1,7 +1,7 @@
1
1
  import requests
2
2
  from typing import List, Dict, Tuple
3
3
  from jarvis.jarvis_platform.base import BasePlatform
4
- from jarvis.utils import OutputType, PrettyOutput, get_single_line_input
4
+ from jarvis.jarvis_utils import OutputType, PrettyOutput, get_single_line_input
5
5
  import os
6
6
  import json
7
7
 
@@ -2,7 +2,7 @@ from typing import Dict, List, Tuple
2
2
  import os
3
3
  from openai import OpenAI
4
4
  from jarvis.jarvis_platform.base import BasePlatform
5
- from jarvis.utils import PrettyOutput, OutputType
5
+ from jarvis.jarvis_utils import PrettyOutput, OutputType
6
6
 
7
7
  class OpenAIModel(BasePlatform):
8
8
  platform_name = "openai"
@@ -2,7 +2,7 @@ import mimetypes
2
2
  import os
3
3
  from typing import Dict, List, Tuple
4
4
  from jarvis.jarvis_platform.base import BasePlatform
5
- from jarvis.utils import PrettyOutput, OutputType
5
+ from jarvis.jarvis_utils import PrettyOutput, OutputType
6
6
  import requests
7
7
  import json
8
8
 
@@ -4,7 +4,7 @@ import os
4
4
  import sys
5
5
  from typing import Dict, Type, Optional, List
6
6
  from jarvis.jarvis_platform.base import BasePlatform
7
- from jarvis.utils import PrettyOutput, OutputType, get_cheap_model_name, get_cheap_platform_name, get_codegen_model_name, get_codegen_platform_name, get_normal_model_name, get_normal_platform_name, get_thinking_model_name, get_thinking_platform_name
7
+ from jarvis.jarvis_utils import PrettyOutput, OutputType, get_cheap_model_name, get_cheap_platform_name, get_codegen_model_name, get_codegen_platform_name, get_normal_model_name, get_normal_platform_name, get_thinking_model_name, get_thinking_platform_name
8
8
 
9
9
  REQUIRED_METHODS = [
10
10
  ('chat', ['message']), # 方法名和参数列表