jarvis-ai-assistant 0.1.131__py3-none-any.whl → 0.1.134__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/jarvis_agent/__init__.py +165 -285
- jarvis/jarvis_agent/jarvis.py +143 -0
- jarvis/jarvis_agent/main.py +0 -2
- jarvis/jarvis_agent/patch.py +70 -48
- jarvis/jarvis_agent/shell_input_handler.py +1 -1
- jarvis/jarvis_code_agent/code_agent.py +169 -117
- jarvis/jarvis_dev/main.py +327 -626
- jarvis/jarvis_git_squash/main.py +10 -31
- jarvis/jarvis_lsp/base.py +0 -42
- jarvis/jarvis_lsp/cpp.py +0 -15
- jarvis/jarvis_lsp/go.py +0 -15
- jarvis/jarvis_lsp/python.py +0 -19
- jarvis/jarvis_lsp/registry.py +0 -62
- jarvis/jarvis_lsp/rust.py +0 -15
- jarvis/jarvis_multi_agent/__init__.py +19 -69
- jarvis/jarvis_multi_agent/main.py +43 -0
- jarvis/jarvis_platform/ai8.py +7 -32
- jarvis/jarvis_platform/base.py +2 -7
- jarvis/jarvis_platform/kimi.py +3 -144
- jarvis/jarvis_platform/ollama.py +54 -68
- jarvis/jarvis_platform/openai.py +0 -4
- jarvis/jarvis_platform/oyi.py +0 -75
- jarvis/jarvis_platform/registry.py +2 -16
- jarvis/jarvis_platform/yuanbao.py +264 -0
- jarvis/jarvis_rag/file_processors.py +138 -0
- jarvis/jarvis_rag/main.py +1305 -425
- jarvis/jarvis_tools/ask_codebase.py +216 -43
- jarvis/jarvis_tools/code_review.py +158 -113
- jarvis/jarvis_tools/create_sub_agent.py +0 -1
- jarvis/jarvis_tools/execute_python_script.py +58 -0
- jarvis/jarvis_tools/execute_shell.py +13 -26
- jarvis/jarvis_tools/execute_shell_script.py +1 -1
- jarvis/jarvis_tools/file_analyzer.py +282 -0
- jarvis/jarvis_tools/file_operation.py +1 -1
- jarvis/jarvis_tools/find_caller.py +278 -0
- jarvis/jarvis_tools/find_symbol.py +295 -0
- jarvis/jarvis_tools/function_analyzer.py +331 -0
- jarvis/jarvis_tools/git_commiter.py +5 -5
- jarvis/jarvis_tools/methodology.py +88 -53
- jarvis/jarvis_tools/project_analyzer.py +308 -0
- jarvis/jarvis_tools/rag.py +0 -5
- jarvis/jarvis_tools/read_code.py +24 -3
- jarvis/jarvis_tools/read_webpage.py +195 -81
- jarvis/jarvis_tools/registry.py +132 -11
- jarvis/jarvis_tools/search_web.py +22 -307
- jarvis/jarvis_tools/tool_generator.py +8 -10
- jarvis/jarvis_utils/__init__.py +1 -0
- jarvis/jarvis_utils/config.py +80 -76
- jarvis/jarvis_utils/embedding.py +344 -45
- jarvis/jarvis_utils/git_utils.py +9 -1
- jarvis/jarvis_utils/input.py +7 -6
- jarvis/jarvis_utils/methodology.py +384 -15
- jarvis/jarvis_utils/output.py +5 -3
- jarvis/jarvis_utils/utils.py +60 -8
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/METADATA +8 -16
- jarvis_ai_assistant-0.1.134.dist-info/RECORD +82 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/entry_points.txt +4 -3
- jarvis/jarvis_codebase/__init__.py +0 -0
- jarvis/jarvis_codebase/main.py +0 -1011
- jarvis/jarvis_tools/lsp_find_definition.py +0 -150
- jarvis/jarvis_tools/lsp_find_references.py +0 -127
- jarvis/jarvis_tools/treesitter_analyzer.py +0 -331
- jarvis/jarvis_treesitter/README.md +0 -104
- jarvis/jarvis_treesitter/__init__.py +0 -20
- jarvis/jarvis_treesitter/database.py +0 -258
- jarvis/jarvis_treesitter/example.py +0 -115
- jarvis/jarvis_treesitter/grammar_builder.py +0 -182
- jarvis/jarvis_treesitter/language.py +0 -117
- jarvis/jarvis_treesitter/symbol.py +0 -31
- jarvis/jarvis_treesitter/tools_usage.md +0 -121
- jarvis_ai_assistant-0.1.131.dist-info/RECORD +0 -85
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/top_level.txt +0 -0
jarvis/jarvis_git_squash/main.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import re
|
|
1
2
|
import sys
|
|
2
3
|
import argparse
|
|
3
4
|
from typing import Dict, Any
|
|
@@ -26,39 +27,23 @@ class GitSquashTool:
|
|
|
26
27
|
except Exception:
|
|
27
28
|
return False
|
|
28
29
|
|
|
29
|
-
def execute(self, args: Dict)
|
|
30
|
+
def execute(self, args: Dict):
|
|
30
31
|
"""Execute the squash operation"""
|
|
31
32
|
try:
|
|
32
33
|
if not self._confirm_squash():
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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
|
-
|
|
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
|
@@ -25,48 +25,6 @@ class BaseLSP(ABC):
|
|
|
25
25
|
"""
|
|
26
26
|
return False
|
|
27
27
|
|
|
28
|
-
@abstractmethod
|
|
29
|
-
def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
|
|
30
|
-
"""Find all references of symbol at position.
|
|
31
|
-
|
|
32
|
-
Args:
|
|
33
|
-
file_path: Path to the file
|
|
34
|
-
position: (line, character) tuple
|
|
35
|
-
|
|
36
|
-
Returns:
|
|
37
|
-
List of references with location info:
|
|
38
|
-
[
|
|
39
|
-
{
|
|
40
|
-
"uri": "file path",
|
|
41
|
-
"range": {
|
|
42
|
-
"start": {"line": int, "character": int},
|
|
43
|
-
"end": {"line": int, "character": int}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
]
|
|
47
|
-
"""
|
|
48
|
-
return []
|
|
49
|
-
|
|
50
|
-
@abstractmethod
|
|
51
|
-
def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
|
|
52
|
-
"""Find definition of symbol at position.
|
|
53
|
-
|
|
54
|
-
Args:
|
|
55
|
-
file_path: Path to the file
|
|
56
|
-
position: (line, character) tuple
|
|
57
|
-
|
|
58
|
-
Returns:
|
|
59
|
-
Location of definition:
|
|
60
|
-
{
|
|
61
|
-
"uri": "file path",
|
|
62
|
-
"range": {
|
|
63
|
-
"start": {"line": int, "character": int},
|
|
64
|
-
"end": {"line": int, "character": int}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
"""
|
|
68
|
-
return None
|
|
69
|
-
|
|
70
28
|
|
|
71
29
|
@abstractmethod
|
|
72
30
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
jarvis/jarvis_lsp/cpp.py
CHANGED
|
@@ -66,21 +66,6 @@ class CPPLSP(BaseLSP):
|
|
|
66
66
|
except Exception:
|
|
67
67
|
return None
|
|
68
68
|
|
|
69
|
-
def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
|
|
70
|
-
result = self._send_request("textDocument/references", {
|
|
71
|
-
"textDocument": {"uri": f"file://{file_path}"},
|
|
72
|
-
"position": {"line": position[0], "character": position[1]},
|
|
73
|
-
"context": {"includeDeclaration": True}
|
|
74
|
-
})
|
|
75
|
-
return result or [] # type: ignore
|
|
76
|
-
|
|
77
|
-
def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
|
|
78
|
-
result = self._send_request("textDocument/definition", {
|
|
79
|
-
"textDocument": {"uri": f"file://{file_path}"},
|
|
80
|
-
"position": {"line": position[0], "character": position[1]}
|
|
81
|
-
})
|
|
82
|
-
return result[0] if result else None
|
|
83
|
-
|
|
84
69
|
|
|
85
70
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
|
86
71
|
# Send didOpen notification to trigger diagnostics
|
jarvis/jarvis_lsp/go.py
CHANGED
|
@@ -72,21 +72,6 @@ class GoLSP(BaseLSP):
|
|
|
72
72
|
except Exception:
|
|
73
73
|
return None
|
|
74
74
|
|
|
75
|
-
def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
|
|
76
|
-
result = self._send_request("textDocument/references", {
|
|
77
|
-
"textDocument": {"uri": f"file://{file_path}"},
|
|
78
|
-
"position": {"line": position[0], "character": position[1]},
|
|
79
|
-
"context": {"includeDeclaration": True}
|
|
80
|
-
})
|
|
81
|
-
return result or [] # type: ignore
|
|
82
|
-
|
|
83
|
-
def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
|
|
84
|
-
result = self._send_request("textDocument/definition", {
|
|
85
|
-
"textDocument": {"uri": f"file://{file_path}"},
|
|
86
|
-
"position": {"line": position[0], "character": position[1]}
|
|
87
|
-
})
|
|
88
|
-
return result[0] if result else None
|
|
89
|
-
|
|
90
75
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
|
91
76
|
# Send didOpen notification to trigger diagnostics
|
|
92
77
|
self._send_request("textDocument/didOpen", {
|
jarvis/jarvis_lsp/python.py
CHANGED
|
@@ -25,25 +25,6 @@ class PythonLSP(BaseLSP):
|
|
|
25
25
|
return None
|
|
26
26
|
return self.script_cache[file_path]
|
|
27
27
|
|
|
28
|
-
def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
|
|
29
|
-
script = self._get_script(file_path)
|
|
30
|
-
if not script:
|
|
31
|
-
return []
|
|
32
|
-
try:
|
|
33
|
-
refs = script.get_references(line=position[0] + 1, column=position[1])
|
|
34
|
-
return [self._location_to_dict(ref) for ref in refs]
|
|
35
|
-
except Exception:
|
|
36
|
-
return []
|
|
37
|
-
|
|
38
|
-
def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
|
|
39
|
-
script = self._get_script(file_path)
|
|
40
|
-
if not script:
|
|
41
|
-
return None
|
|
42
|
-
try:
|
|
43
|
-
defs = script.goto(line=position[0] + 1, column=position[1])
|
|
44
|
-
return self._location_to_dict(defs[0]) if defs else None
|
|
45
|
-
except Exception:
|
|
46
|
-
return None
|
|
47
28
|
|
|
48
29
|
def _location_to_dict(self, location) -> Dict[str, Any]:
|
|
49
30
|
return {
|
jarvis/jarvis_lsp/registry.py
CHANGED
|
@@ -9,8 +9,6 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
|
9
9
|
|
|
10
10
|
REQUIRED_METHODS = [
|
|
11
11
|
('initialize', ['workspace_path']),
|
|
12
|
-
('find_references', ['file_path', 'position']),
|
|
13
|
-
('find_definition', ['file_path', 'position']),
|
|
14
12
|
('get_diagnostics', ['file_path']),
|
|
15
13
|
('shutdown', [])
|
|
16
14
|
]
|
|
@@ -167,63 +165,3 @@ class LSPRegistry:
|
|
|
167
165
|
with open(file_path, 'r', errors="ignore") as file:
|
|
168
166
|
lines = file.readlines()
|
|
169
167
|
return lines[line]
|
|
170
|
-
|
|
171
|
-
def main():
|
|
172
|
-
"""CLI entry point for LSP testing."""
|
|
173
|
-
import argparse
|
|
174
|
-
|
|
175
|
-
parser = argparse.ArgumentParser(description='LSP functionality testing')
|
|
176
|
-
parser.add_argument('--language', type=str, required=True, help='Programming language')
|
|
177
|
-
parser.add_argument('--file', type=str, required=True, help='File to analyze')
|
|
178
|
-
parser.add_argument('--action', choices=['symbols', 'diagnostics', 'references', 'definition'],
|
|
179
|
-
required=True, help='Action to perform')
|
|
180
|
-
parser.add_argument('--line', type=int, help='Line number (0-based) for references/definition')
|
|
181
|
-
parser.add_argument('--character', type=int, help='Character position for references/definition')
|
|
182
|
-
|
|
183
|
-
args = parser.parse_args()
|
|
184
|
-
|
|
185
|
-
# Initialize LSP
|
|
186
|
-
registry = LSPRegistry.get_global_lsp_registry()
|
|
187
|
-
lsp = registry.create_lsp(args.language)
|
|
188
|
-
|
|
189
|
-
if not lsp:
|
|
190
|
-
PrettyOutput.print(f"没有 LSP 支持的语言: {args.language}", OutputType.WARNING)
|
|
191
|
-
return 1
|
|
192
|
-
|
|
193
|
-
if not lsp.initialize(os.path.abspath(os.getcwd())):
|
|
194
|
-
PrettyOutput.print("LSP 初始化失败", OutputType.WARNING)
|
|
195
|
-
return 1
|
|
196
|
-
|
|
197
|
-
try:
|
|
198
|
-
if args.action == 'diagnostics':
|
|
199
|
-
diagnostics = lsp.get_diagnostics(args.file)
|
|
200
|
-
for diag in diagnostics:
|
|
201
|
-
severity = ['Error', 'Warning', 'Info', 'Hint'][diag['severity'] - 1]
|
|
202
|
-
PrettyOutput.print(f"{severity} 在 {diag['range']['start']['line']}:{diag['range']['start']['character']}: {diag['message']}", OutputType.INFO)
|
|
203
|
-
|
|
204
|
-
elif args.action in ('references', 'definition'):
|
|
205
|
-
if args.line is None or args.character is None:
|
|
206
|
-
PrettyOutput.print("需要行和字符位置用于 references/definition", OutputType.WARNING)
|
|
207
|
-
return 1
|
|
208
|
-
|
|
209
|
-
if args.action == 'references':
|
|
210
|
-
refs = lsp.find_references(args.file, (args.line, args.character))
|
|
211
|
-
for ref in refs:
|
|
212
|
-
PrettyOutput.print(f"引用在 {ref['uri']} 在 {ref['range']['start']['line']}:{ref['range']['start']['character']}\n行: {LSPRegistry.get_line_at_position(ref['uri'], ref['range']['start']['line'])}", OutputType.INFO)
|
|
213
|
-
else:
|
|
214
|
-
defn = lsp.find_definition(args.file, (args.line, args.character))
|
|
215
|
-
if defn:
|
|
216
|
-
PrettyOutput.print(f"定义在 {defn['uri']} 在 {defn['range']['start']['line']}:{defn['range']['start']['character']}\n行: {LSPRegistry.get_line_at_position(defn['uri'], defn['range']['start']['line'])}", OutputType.INFO)
|
|
217
|
-
else:
|
|
218
|
-
PrettyOutput.print("没有找到定义", OutputType.WARNING)
|
|
219
|
-
|
|
220
|
-
except Exception as e:
|
|
221
|
-
PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
|
|
222
|
-
return 1
|
|
223
|
-
finally:
|
|
224
|
-
lsp.shutdown()
|
|
225
|
-
|
|
226
|
-
return 0
|
|
227
|
-
|
|
228
|
-
if __name__ == "__main__":
|
|
229
|
-
exit(main())
|
jarvis/jarvis_lsp/rust.py
CHANGED
|
@@ -74,21 +74,6 @@ class RustLSP(BaseLSP):
|
|
|
74
74
|
except Exception:
|
|
75
75
|
return None
|
|
76
76
|
|
|
77
|
-
def find_references(self, file_path: str, position: Tuple[int, int]) -> List[Dict[str, Any]]:
|
|
78
|
-
result = self._send_request("textDocument/references", {
|
|
79
|
-
"textDocument": {"uri": f"file://{file_path}"},
|
|
80
|
-
"position": {"line": position[0], "character": position[1]},
|
|
81
|
-
"context": {"includeDeclaration": True}
|
|
82
|
-
})
|
|
83
|
-
return result or [] # type: ignore
|
|
84
|
-
|
|
85
|
-
def find_definition(self, file_path: str, position: Tuple[int, int]) -> Optional[Dict[str, Any]]:
|
|
86
|
-
result = self._send_request("textDocument/definition", {
|
|
87
|
-
"textDocument": {"uri": f"file://{file_path}"},
|
|
88
|
-
"position": {"line": position[0], "character": position[1]}
|
|
89
|
-
})
|
|
90
|
-
return result[0] if result else None
|
|
91
|
-
|
|
92
77
|
|
|
93
78
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
|
94
79
|
# Send didOpen notification to trigger diagnostics
|
|
@@ -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
|
-
|
|
34
|
+
{ot("SEND_MESSAGE")}
|
|
40
35
|
to: 智能体名称 # 目标智能体名称
|
|
41
36
|
content: |
|
|
42
37
|
# 消息主题
|
|
@@ -52,31 +47,27 @@ content: |
|
|
|
52
47
|
|
|
53
48
|
## 期望结果
|
|
54
49
|
[描述期望的输出格式和内容]
|
|
55
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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'
|
|
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:
|
|
@@ -147,45 +138,4 @@ content: {msg['content']}
|
|
|
147
138
|
last_agent = self.agents[msg['to']].name
|
|
148
139
|
msg = self.agents[msg['to']].run(prompt)
|
|
149
140
|
return ""
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def main():
|
|
153
|
-
"""从YAML配置文件初始化并运行多智能体系统
|
|
154
|
-
|
|
155
|
-
Returns:
|
|
156
|
-
最终处理结果
|
|
157
|
-
"""
|
|
158
|
-
init_env()
|
|
159
|
-
import argparse
|
|
160
|
-
parser = argparse.ArgumentParser(description="多智能体系统启动器")
|
|
161
|
-
parser.add_argument("--config", "-c", required=True, help="YAML配置文件路径")
|
|
162
|
-
parser.add_argument("--input", "-i", help="用户输入(可选)")
|
|
163
|
-
args = parser.parse_args()
|
|
164
|
-
|
|
165
|
-
try:
|
|
166
|
-
with open(args.config, 'r', errors="ignore") as f:
|
|
167
|
-
config_data = yaml.safe_load(f)
|
|
168
|
-
|
|
169
|
-
# 获取agents配置
|
|
170
|
-
agents_config = config_data.get('agents', [])
|
|
171
|
-
|
|
172
|
-
main_agent_name = config_data.get('main_agent', '')
|
|
173
|
-
if not main_agent_name:
|
|
174
|
-
raise ValueError("必须指定main_agent作为主智能体")
|
|
175
|
-
|
|
176
|
-
# 创建并运行多智能体系统
|
|
177
|
-
multi_agent = MultiAgent(agents_config, main_agent_name)
|
|
178
|
-
user_input = args.input if args.input is not None else get_multiline_input("请输入内容(输入空行结束):")
|
|
179
|
-
if user_input == "":
|
|
180
|
-
return
|
|
181
|
-
return multi_agent.run(user_input)
|
|
182
|
-
|
|
183
|
-
except yaml.YAMLError as e:
|
|
184
|
-
raise ValueError(f"YAML配置文件解析错误: {str(e)}")
|
|
185
|
-
except Exception as e:
|
|
186
|
-
raise RuntimeError(f"多智能体系统初始化失败: {str(e)}")
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
if __name__ == "__main__":
|
|
190
|
-
result = main()
|
|
191
141
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import yaml
|
|
2
|
+
from jarvis.jarvis_multi_agent import MultiAgent
|
|
3
|
+
from jarvis.jarvis_utils.utils import init_env
|
|
4
|
+
from jarvis.jarvis_utils.input import get_multiline_input
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
"""从YAML配置文件初始化并运行多智能体系统
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
最终处理结果
|
|
11
|
+
"""
|
|
12
|
+
init_env()
|
|
13
|
+
import argparse
|
|
14
|
+
parser = argparse.ArgumentParser(description="多智能体系统启动器")
|
|
15
|
+
parser.add_argument("--config", "-c", required=True, help="YAML配置文件路径")
|
|
16
|
+
parser.add_argument("--input", "-i", help="用户输入(可选)")
|
|
17
|
+
args = parser.parse_args()
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
with open(args.config, 'r', errors="ignore") as f:
|
|
21
|
+
config_data = yaml.safe_load(f)
|
|
22
|
+
|
|
23
|
+
# 获取agents配置
|
|
24
|
+
agents_config = config_data.get('agents', [])
|
|
25
|
+
|
|
26
|
+
main_agent_name = config_data.get('main_agent', '')
|
|
27
|
+
if not main_agent_name:
|
|
28
|
+
raise ValueError("必须指定main_agent作为主智能体")
|
|
29
|
+
|
|
30
|
+
# 创建并运行多智能体系统
|
|
31
|
+
multi_agent = MultiAgent(agents_config, main_agent_name)
|
|
32
|
+
user_input = args.input if args.input is not None else get_multiline_input("请输入内容(输入空行结束):")
|
|
33
|
+
if user_input == "":
|
|
34
|
+
return
|
|
35
|
+
return multi_agent.run(user_input)
|
|
36
|
+
|
|
37
|
+
except yaml.YAMLError as e:
|
|
38
|
+
raise ValueError(f"YAML配置文件解析错误: {str(e)}")
|
|
39
|
+
except Exception as e:
|
|
40
|
+
raise RuntimeError(f"多智能体系统初始化失败: {str(e)}")
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
result = main()
|
jarvis/jarvis_platform/ai8.py
CHANGED
|
@@ -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
|
|
303
|
-
|
|
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())
|
jarvis/jarvis_platform/base.py
CHANGED
|
@@ -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'
|
|
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"""
|