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.
- jarvis/__init__.py +1 -1
- jarvis/{agent.py → jarvis_agent/__init__.py} +122 -203
- jarvis/jarvis_agent/output_handler.py +23 -0
- jarvis/jarvis_code_agent/code_agent.py +113 -100
- jarvis/jarvis_code_agent/file_select.py +28 -7
- jarvis/jarvis_code_agent/patch.py +80 -2
- jarvis/jarvis_code_agent/relevant_files.py +82 -42
- jarvis/jarvis_codebase/main.py +53 -25
- jarvis/jarvis_dev/main.py +719 -547
- jarvis/jarvis_lsp/cpp.py +1 -1
- jarvis/jarvis_lsp/go.py +1 -1
- jarvis/jarvis_lsp/registry.py +1 -1
- jarvis/jarvis_lsp/rust.py +1 -1
- jarvis/jarvis_multi_agent/__init__.py +170 -0
- jarvis/jarvis_platform/ai8.py +2 -2
- jarvis/jarvis_platform/base.py +14 -4
- jarvis/jarvis_platform/kimi.py +2 -2
- jarvis/jarvis_platform/ollama.py +1 -1
- jarvis/jarvis_platform/openai.py +1 -1
- jarvis/jarvis_platform/oyi.py +1 -1
- jarvis/jarvis_platform/registry.py +1 -1
- jarvis/jarvis_platform_manager/main.py +422 -6
- jarvis/jarvis_platform_manager/openai_test.py +139 -0
- jarvis/jarvis_rag/main.py +57 -20
- jarvis/jarvis_smart_shell/main.py +55 -29
- jarvis/jarvis_tools/ask_codebase.py +1 -1
- jarvis/jarvis_tools/ask_user.py +1 -1
- jarvis/jarvis_tools/chdir.py +1 -1
- jarvis/jarvis_tools/code_review.py +3 -3
- jarvis/jarvis_tools/create_code_agent.py +1 -1
- jarvis/jarvis_tools/create_sub_agent.py +2 -2
- jarvis/jarvis_tools/execute_shell.py +1 -1
- jarvis/jarvis_tools/file_operation.py +16 -14
- jarvis/jarvis_tools/git_commiter.py +2 -2
- jarvis/jarvis_tools/methodology.py +1 -1
- jarvis/jarvis_tools/rag.py +1 -1
- jarvis/jarvis_tools/read_code.py +19 -8
- jarvis/jarvis_tools/read_webpage.py +1 -1
- jarvis/jarvis_tools/registry.py +157 -31
- jarvis/jarvis_tools/search.py +1 -1
- jarvis/jarvis_tools/select_code_files.py +1 -1
- jarvis/{utils.py → jarvis_utils/__init__.py} +69 -53
- {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/METADATA +1 -1
- jarvis_ai_assistant-0.1.117.dist-info/RECORD +65 -0
- {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/WHEEL +1 -1
- {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/entry_points.txt +1 -1
- jarvis/multi_agent.py +0 -76
- jarvis/utils/date_utils.py +0 -19
- jarvis_ai_assistant-0.1.115.dist-info/RECORD +0 -64
- {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/LICENSE +0 -0
- {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.
|
|
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.
|
|
7
|
+
from jarvis.jarvis_utils import PrettyOutput, OutputType
|
|
8
8
|
|
|
9
9
|
class GoLSP(BaseLSP):
|
|
10
10
|
"""Go LSP implementation using gopls."""
|
jarvis/jarvis_lsp/registry.py
CHANGED
|
@@ -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.
|
|
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.
|
|
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 ""
|
jarvis/jarvis_platform/ai8.py
CHANGED
|
@@ -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.
|
|
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/
|
|
263
|
+
f"{self.BASE_URL}/api/chat/tmpl",
|
|
264
264
|
headers=headers
|
|
265
265
|
)
|
|
266
266
|
|
jarvis/jarvis_platform/base.py
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
jarvis/jarvis_platform/kimi.py
CHANGED
|
@@ -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.
|
|
9
|
-
from jarvis.
|
|
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"""
|
jarvis/jarvis_platform/ollama.py
CHANGED
|
@@ -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.
|
|
4
|
+
from jarvis.jarvis_utils import OutputType, PrettyOutput, get_single_line_input
|
|
5
5
|
import os
|
|
6
6
|
import json
|
|
7
7
|
|
jarvis/jarvis_platform/openai.py
CHANGED
|
@@ -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.
|
|
5
|
+
from jarvis.jarvis_utils import PrettyOutput, OutputType
|
|
6
6
|
|
|
7
7
|
class OpenAIModel(BasePlatform):
|
|
8
8
|
platform_name = "openai"
|
jarvis/jarvis_platform/oyi.py
CHANGED
|
@@ -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.
|
|
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']), # 方法名和参数列表
|