jarvis-ai-assistant 0.1.134__py3-none-any.whl → 0.1.138__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 +201 -79
- jarvis/jarvis_agent/builtin_input_handler.py +16 -6
- jarvis/jarvis_agent/file_input_handler.py +9 -9
- jarvis/jarvis_agent/jarvis.py +10 -10
- jarvis/jarvis_agent/main.py +12 -11
- jarvis/jarvis_agent/output_handler.py +3 -3
- jarvis/jarvis_agent/patch.py +86 -62
- jarvis/jarvis_agent/shell_input_handler.py +5 -3
- jarvis/jarvis_code_agent/code_agent.py +134 -99
- jarvis/jarvis_code_agent/file_select.py +24 -24
- jarvis/jarvis_dev/main.py +45 -51
- jarvis/jarvis_git_details/__init__.py +0 -0
- jarvis/jarvis_git_details/main.py +179 -0
- jarvis/jarvis_git_squash/main.py +7 -7
- jarvis/jarvis_lsp/base.py +11 -11
- jarvis/jarvis_lsp/cpp.py +14 -14
- jarvis/jarvis_lsp/go.py +13 -13
- jarvis/jarvis_lsp/python.py +8 -8
- jarvis/jarvis_lsp/registry.py +21 -21
- jarvis/jarvis_lsp/rust.py +15 -15
- jarvis/jarvis_methodology/main.py +101 -0
- jarvis/jarvis_multi_agent/__init__.py +11 -11
- jarvis/jarvis_multi_agent/main.py +6 -6
- jarvis/jarvis_platform/__init__.py +1 -1
- jarvis/jarvis_platform/ai8.py +67 -89
- jarvis/jarvis_platform/base.py +14 -13
- jarvis/jarvis_platform/kimi.py +25 -28
- jarvis/jarvis_platform/ollama.py +24 -26
- jarvis/jarvis_platform/openai.py +15 -19
- jarvis/jarvis_platform/oyi.py +48 -50
- jarvis/jarvis_platform/registry.py +27 -28
- jarvis/jarvis_platform/yuanbao.py +38 -42
- jarvis/jarvis_platform_manager/main.py +81 -81
- jarvis/jarvis_platform_manager/openai_test.py +21 -21
- jarvis/jarvis_rag/file_processors.py +18 -18
- jarvis/jarvis_rag/main.py +261 -277
- jarvis/jarvis_smart_shell/main.py +12 -12
- jarvis/jarvis_tools/ask_codebase.py +28 -28
- jarvis/jarvis_tools/ask_user.py +8 -8
- jarvis/jarvis_tools/base.py +4 -4
- jarvis/jarvis_tools/chdir.py +9 -9
- jarvis/jarvis_tools/code_review.py +19 -19
- jarvis/jarvis_tools/create_code_agent.py +15 -15
- jarvis/jarvis_tools/execute_python_script.py +3 -3
- jarvis/jarvis_tools/execute_shell.py +11 -11
- jarvis/jarvis_tools/execute_shell_script.py +3 -3
- jarvis/jarvis_tools/file_analyzer.py +29 -29
- jarvis/jarvis_tools/file_operation.py +22 -20
- jarvis/jarvis_tools/find_caller.py +25 -25
- jarvis/jarvis_tools/find_methodolopy.py +65 -0
- jarvis/jarvis_tools/find_symbol.py +24 -24
- jarvis/jarvis_tools/function_analyzer.py +27 -27
- jarvis/jarvis_tools/git_commiter.py +9 -9
- jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -19
- jarvis/jarvis_tools/methodology.py +23 -62
- jarvis/jarvis_tools/project_analyzer.py +29 -33
- jarvis/jarvis_tools/rag.py +15 -15
- jarvis/jarvis_tools/read_code.py +24 -22
- jarvis/jarvis_tools/read_webpage.py +31 -31
- jarvis/jarvis_tools/registry.py +72 -52
- jarvis/jarvis_tools/tool_generator.py +18 -18
- jarvis/jarvis_utils/config.py +23 -23
- jarvis/jarvis_utils/embedding.py +83 -83
- jarvis/jarvis_utils/git_utils.py +20 -20
- jarvis/jarvis_utils/globals.py +18 -6
- jarvis/jarvis_utils/input.py +10 -9
- jarvis/jarvis_utils/methodology.py +140 -136
- jarvis/jarvis_utils/output.py +11 -11
- jarvis/jarvis_utils/utils.py +22 -70
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/METADATA +1 -1
- jarvis_ai_assistant-0.1.138.dist-info/RECORD +85 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/entry_points.txt +2 -0
- jarvis/jarvis_tools/select_code_files.py +0 -62
- jarvis_ai_assistant-0.1.134.dist-info/RECORD +0 -82
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/top_level.txt +0 -0
jarvis/jarvis_lsp/go.py
CHANGED
|
@@ -8,19 +8,19 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
|
8
8
|
|
|
9
9
|
class GoLSP(BaseLSP):
|
|
10
10
|
"""Go LSP implementation using gopls."""
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
language = "go"
|
|
13
13
|
|
|
14
14
|
@staticmethod
|
|
15
15
|
def check() -> bool:
|
|
16
16
|
"""Check if gopls is installed."""
|
|
17
17
|
return shutil.which("gopls") is not None
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def __init__(self):
|
|
20
20
|
self.workspace_path = ""
|
|
21
21
|
self.gopls_process = None
|
|
22
22
|
self.request_id = 0
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
def initialize(self, workspace_path: str) -> bool:
|
|
25
25
|
try:
|
|
26
26
|
self.workspace_path = workspace_path
|
|
@@ -31,7 +31,7 @@ class GoLSP(BaseLSP):
|
|
|
31
31
|
stdout=subprocess.PIPE,
|
|
32
32
|
stderr=subprocess.PIPE
|
|
33
33
|
)
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
# Send initialize request
|
|
36
36
|
self._send_request("initialize", {
|
|
37
37
|
"processId": os.getpid(),
|
|
@@ -44,17 +44,17 @@ class GoLSP(BaseLSP):
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
})
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
return True
|
|
49
49
|
except Exception as e:
|
|
50
50
|
PrettyOutput.print(f"Go LSP 初始化失败: {str(e)}", OutputType.ERROR)
|
|
51
51
|
return False
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
def _send_request(self, method: str, params: Dict) -> Optional[Dict]:
|
|
54
54
|
"""Send JSON-RPC request to gopls."""
|
|
55
55
|
if not self.gopls_process:
|
|
56
56
|
return None
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
try:
|
|
59
59
|
self.request_id += 1
|
|
60
60
|
request = {
|
|
@@ -63,15 +63,15 @@ class GoLSP(BaseLSP):
|
|
|
63
63
|
"method": method,
|
|
64
64
|
"params": params
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
self.gopls_process.stdin.write(json.dumps(request).encode() + b"\n") # type: ignore
|
|
68
68
|
self.gopls_process.stdin.flush() # type: ignore
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
response = json.loads(self.gopls_process.stdout.readline().decode()) # type: ignore
|
|
71
71
|
return response.get("result")
|
|
72
72
|
except Exception:
|
|
73
73
|
return None
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
|
76
76
|
# Send didOpen notification to trigger diagnostics
|
|
77
77
|
self._send_request("textDocument/didOpen", {
|
|
@@ -82,7 +82,7 @@ class GoLSP(BaseLSP):
|
|
|
82
82
|
"text": open(file_path).read()
|
|
83
83
|
}
|
|
84
84
|
})
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
# Wait for diagnostic notification
|
|
87
87
|
try:
|
|
88
88
|
response = json.loads(self.gopls_process.stdout.readline().decode()) # type: ignore
|
|
@@ -91,8 +91,8 @@ class GoLSP(BaseLSP):
|
|
|
91
91
|
except Exception:
|
|
92
92
|
pass
|
|
93
93
|
return []
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
|
|
95
|
+
|
|
96
96
|
def shutdown(self):
|
|
97
97
|
if self.gopls_process:
|
|
98
98
|
try:
|
jarvis/jarvis_lsp/python.py
CHANGED
|
@@ -4,17 +4,17 @@ from jarvis.jarvis_lsp.base import BaseLSP
|
|
|
4
4
|
|
|
5
5
|
class PythonLSP(BaseLSP):
|
|
6
6
|
"""Python LSP implementation using jedi."""
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
language = "python"
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
def __init__(self):
|
|
11
11
|
self.workspace_path = ""
|
|
12
12
|
self.script_cache = {}
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
def initialize(self, workspace_path: str) -> bool:
|
|
15
15
|
self.workspace_path = workspace_path
|
|
16
16
|
return True
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
def _get_script(self, file_path: str):
|
|
19
19
|
if file_path not in self.script_cache:
|
|
20
20
|
try:
|
|
@@ -24,8 +24,8 @@ class PythonLSP(BaseLSP):
|
|
|
24
24
|
except Exception:
|
|
25
25
|
return None
|
|
26
26
|
return self.script_cache[file_path]
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
|
|
29
29
|
def _location_to_dict(self, location) -> Dict[str, Any]:
|
|
30
30
|
return {
|
|
31
31
|
"uri": location.module_path,
|
|
@@ -34,7 +34,7 @@ class PythonLSP(BaseLSP):
|
|
|
34
34
|
"end": {"line": location.line - 1, "character": location.column + len(location.name)}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
|
39
39
|
script = self._get_script(file_path)
|
|
40
40
|
if not script:
|
|
@@ -52,6 +52,6 @@ class PythonLSP(BaseLSP):
|
|
|
52
52
|
} for e in errors]
|
|
53
53
|
except Exception:
|
|
54
54
|
return []
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
def shutdown(self):
|
|
57
57
|
self.script_cache.clear()
|
jarvis/jarvis_lsp/registry.py
CHANGED
|
@@ -36,47 +36,47 @@ class LSPRegistry:
|
|
|
36
36
|
def check_lsp_implementation(lsp_class: Type[BaseLSP]) -> bool:
|
|
37
37
|
"""Check if the LSP class implements all necessary methods."""
|
|
38
38
|
missing_methods = []
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
for method_name, params in REQUIRED_METHODS:
|
|
41
41
|
if not hasattr(lsp_class, method_name):
|
|
42
42
|
missing_methods.append(method_name)
|
|
43
43
|
continue
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
method = getattr(lsp_class, method_name)
|
|
46
46
|
if not callable(method):
|
|
47
47
|
missing_methods.append(method_name)
|
|
48
48
|
continue
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
sig = inspect.signature(method)
|
|
51
51
|
method_params = [p for p in sig.parameters if p != 'self']
|
|
52
52
|
if len(method_params) != len(params):
|
|
53
53
|
missing_methods.append(f"{method_name}(parameter mismatch)")
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
if missing_methods:
|
|
56
56
|
PrettyOutput.print(
|
|
57
|
-
f"LSP {lsp_class.__name__} 缺少必要的方法: {', '.join(missing_methods)}",
|
|
57
|
+
f"LSP {lsp_class.__name__} 缺少必要的方法: {', '.join(missing_methods)}",
|
|
58
58
|
OutputType.WARNING
|
|
59
59
|
)
|
|
60
60
|
return False
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
return True
|
|
63
63
|
|
|
64
64
|
@staticmethod
|
|
65
65
|
def load_lsp_from_dir(directory: str) -> Dict[str, Type[BaseLSP]]:
|
|
66
66
|
"""Load LSP implementations from specified directory."""
|
|
67
67
|
lsp_servers = {}
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
if not os.path.exists(directory):
|
|
70
70
|
PrettyOutput.print(f"LSP 目录不存在: {directory}", OutputType.WARNING)
|
|
71
71
|
return lsp_servers
|
|
72
|
-
|
|
72
|
+
|
|
73
73
|
package_name = None
|
|
74
74
|
if directory == os.path.dirname(__file__):
|
|
75
75
|
package_name = "jarvis.jarvis_lsp"
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
if directory not in sys.path:
|
|
78
78
|
sys.path.append(directory)
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
for filename in os.listdir(directory):
|
|
81
81
|
if filename.endswith('.py') and not filename.startswith('__'):
|
|
82
82
|
module_name = filename[:-3]
|
|
@@ -85,10 +85,10 @@ class LSPRegistry:
|
|
|
85
85
|
module = importlib.import_module(f"{package_name}.{module_name}")
|
|
86
86
|
else:
|
|
87
87
|
module = importlib.import_module(module_name)
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
for _, obj in inspect.getmembers(module):
|
|
90
|
-
if (inspect.isclass(obj) and
|
|
91
|
-
issubclass(obj, BaseLSP) and
|
|
90
|
+
if (inspect.isclass(obj) and
|
|
91
|
+
issubclass(obj, BaseLSP) and
|
|
92
92
|
obj != BaseLSP and
|
|
93
93
|
hasattr(obj, 'language')):
|
|
94
94
|
if not LSPRegistry.check_lsp_implementation(obj):
|
|
@@ -104,7 +104,7 @@ class LSPRegistry:
|
|
|
104
104
|
break
|
|
105
105
|
except Exception as e:
|
|
106
106
|
PrettyOutput.print(f"加载 LSP {module_name} 失败: {str(e)}", OutputType.ERROR)
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
return lsp_servers
|
|
109
109
|
|
|
110
110
|
@staticmethod
|
|
@@ -113,17 +113,17 @@ class LSPRegistry:
|
|
|
113
113
|
if LSPRegistry.global_lsp_registry is None:
|
|
114
114
|
LSPRegistry.global_lsp_registry = LSPRegistry()
|
|
115
115
|
return LSPRegistry.global_lsp_registry
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
def __init__(self):
|
|
118
118
|
"""Initialize LSP registry."""
|
|
119
119
|
self.lsp_servers: Dict[str, Type[BaseLSP]] = {}
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
# Load from user LSP directory
|
|
122
122
|
lsp_dir = LSPRegistry.get_lsp_dir()
|
|
123
123
|
if lsp_dir and os.path.exists(lsp_dir):
|
|
124
124
|
for language, lsp_class in LSPRegistry.load_lsp_from_dir(lsp_dir).items():
|
|
125
125
|
self.register_lsp(language, lsp_class)
|
|
126
|
-
|
|
126
|
+
|
|
127
127
|
# Load from built-in LSP directory
|
|
128
128
|
lsp_dir = os.path.dirname(__file__)
|
|
129
129
|
if lsp_dir and os.path.exists(lsp_dir):
|
|
@@ -133,13 +133,13 @@ class LSPRegistry:
|
|
|
133
133
|
def register_lsp(self, language: str, lsp_class: Type[BaseLSP]):
|
|
134
134
|
"""Register LSP implementation for a language."""
|
|
135
135
|
self.lsp_servers[language] = lsp_class
|
|
136
|
-
|
|
136
|
+
|
|
137
137
|
def create_lsp(self, language: str) -> Optional[BaseLSP]:
|
|
138
138
|
"""Create LSP instance for specified language."""
|
|
139
139
|
if language not in self.lsp_servers:
|
|
140
140
|
PrettyOutput.print(f"没有找到 LSP 支持的语言: {language}", OutputType.WARNING)
|
|
141
141
|
return None
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
try:
|
|
144
144
|
lsp = self.lsp_servers[language]()
|
|
145
145
|
return lsp
|
|
@@ -150,7 +150,7 @@ class LSPRegistry:
|
|
|
150
150
|
def get_supported_languages(self) -> List[str]:
|
|
151
151
|
"""Get list of supported languages."""
|
|
152
152
|
return list(self.lsp_servers.keys())
|
|
153
|
-
|
|
153
|
+
|
|
154
154
|
@staticmethod
|
|
155
155
|
def get_text_at_position(file_path: str, line: int, start_character: int) -> str:
|
|
156
156
|
"""Get text at position."""
|
|
@@ -158,7 +158,7 @@ class LSPRegistry:
|
|
|
158
158
|
lines = file.readlines()
|
|
159
159
|
symbol = re.search(r'\b\w+\b', lines[line][start_character:])
|
|
160
160
|
return symbol.group() if symbol else ""
|
|
161
|
-
|
|
161
|
+
|
|
162
162
|
@staticmethod
|
|
163
163
|
def get_line_at_position(file_path: str, line: int) -> str:
|
|
164
164
|
"""Get line at position."""
|
jarvis/jarvis_lsp/rust.py
CHANGED
|
@@ -8,19 +8,19 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
|
8
8
|
|
|
9
9
|
class RustLSP(BaseLSP):
|
|
10
10
|
"""Rust LSP implementation using rust-analyzer."""
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
language = "rust"
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
@staticmethod
|
|
15
15
|
def check() -> bool:
|
|
16
16
|
"""Check if rust-analyzer is installed."""
|
|
17
17
|
return shutil.which("rust-analyzer") is not None
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def __init__(self):
|
|
20
20
|
self.workspace_path = ""
|
|
21
21
|
self.analyzer_process = None
|
|
22
22
|
self.request_id = 0
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
def initialize(self, workspace_path: str) -> bool:
|
|
25
25
|
try:
|
|
26
26
|
self.workspace_path = workspace_path
|
|
@@ -31,7 +31,7 @@ class RustLSP(BaseLSP):
|
|
|
31
31
|
stdout=subprocess.PIPE,
|
|
32
32
|
stderr=subprocess.PIPE
|
|
33
33
|
)
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
# Send initialize request
|
|
36
36
|
self._send_request("initialize", {
|
|
37
37
|
"processId": os.getpid(),
|
|
@@ -46,17 +46,17 @@ class RustLSP(BaseLSP):
|
|
|
46
46
|
},
|
|
47
47
|
"workspaceFolders": [{"uri": f"file://{workspace_path}", "name": "workspace"}]
|
|
48
48
|
})
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
return True
|
|
51
51
|
except Exception as e:
|
|
52
52
|
PrettyOutput.print(f"Rust LSP 初始化失败: {str(e)}", OutputType.ERROR)
|
|
53
53
|
return False
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
def _send_request(self, method: str, params: Dict) -> Optional[Dict]:
|
|
56
56
|
"""Send JSON-RPC request to rust-analyzer."""
|
|
57
57
|
if not self.analyzer_process:
|
|
58
58
|
return None
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
try:
|
|
61
61
|
self.request_id += 1
|
|
62
62
|
request = {
|
|
@@ -65,16 +65,16 @@ class RustLSP(BaseLSP):
|
|
|
65
65
|
"method": method,
|
|
66
66
|
"params": params
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
self.analyzer_process.stdin.write(json.dumps(request).encode() + b"\n") # type: ignore
|
|
70
70
|
self.analyzer_process.stdin.flush() # type: ignore
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
response = json.loads(self.analyzer_process.stdout.readline().decode()) # type: ignore
|
|
73
73
|
return response.get("result")
|
|
74
74
|
except Exception:
|
|
75
75
|
return None
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
|
|
77
|
+
|
|
78
78
|
def get_diagnostics(self, file_path: str) -> List[Dict[str, Any]]:
|
|
79
79
|
# Send didOpen notification to trigger diagnostics
|
|
80
80
|
self._send_request("textDocument/didOpen", {
|
|
@@ -85,7 +85,7 @@ class RustLSP(BaseLSP):
|
|
|
85
85
|
"text": open(file_path).read()
|
|
86
86
|
}
|
|
87
87
|
})
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
# Wait for diagnostic notification
|
|
90
90
|
try:
|
|
91
91
|
response = json.loads(self.analyzer_process.stdout.readline().decode()) # type: ignore
|
|
@@ -94,8 +94,8 @@ class RustLSP(BaseLSP):
|
|
|
94
94
|
except Exception:
|
|
95
95
|
pass
|
|
96
96
|
return []
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
|
|
98
|
+
|
|
99
99
|
def shutdown(self):
|
|
100
100
|
if self.analyzer_process:
|
|
101
101
|
try:
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
方法论导入导出命令行工具
|
|
3
|
+
|
|
4
|
+
功能:
|
|
5
|
+
- 导入方法论文件(合并策略)
|
|
6
|
+
- 导出当前方法论
|
|
7
|
+
- 列出所有方法论
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import hashlib
|
|
11
|
+
import os
|
|
12
|
+
import json
|
|
13
|
+
import argparse
|
|
14
|
+
from jarvis.jarvis_utils.methodology import (
|
|
15
|
+
_get_methodology_directory,
|
|
16
|
+
_load_all_methodologies
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
def import_methodology(input_file):
|
|
20
|
+
"""导入方法论文件(合并策略)"""
|
|
21
|
+
try:
|
|
22
|
+
# 加载现有方法论
|
|
23
|
+
existing_methodologies = _load_all_methodologies()
|
|
24
|
+
|
|
25
|
+
# 加载要导入的方法论
|
|
26
|
+
with open(input_file, "r", encoding="utf-8") as f:
|
|
27
|
+
import_data = json.load(f)
|
|
28
|
+
|
|
29
|
+
# 合并方法论(新数据会覆盖旧数据)
|
|
30
|
+
merged_data = {**existing_methodologies, **import_data}
|
|
31
|
+
|
|
32
|
+
# 保存合并后的方法论
|
|
33
|
+
methodology_dir = _get_methodology_directory()
|
|
34
|
+
for problem_type, content in merged_data.items():
|
|
35
|
+
safe_filename = hashlib.md5(problem_type.encode('utf-8')).hexdigest()
|
|
36
|
+
file_path = os.path.join(methodology_dir, f"{safe_filename}.json")
|
|
37
|
+
|
|
38
|
+
with open(file_path, "w", encoding="utf-8") as f:
|
|
39
|
+
json.dump({
|
|
40
|
+
"problem_type": problem_type,
|
|
41
|
+
"content": content
|
|
42
|
+
}, f, ensure_ascii=False, indent=2)
|
|
43
|
+
|
|
44
|
+
print(f"成功导入 {len(import_data)} 个方法论(总计 {len(merged_data)} 个)")
|
|
45
|
+
except (json.JSONDecodeError, OSError) as e:
|
|
46
|
+
print(f"导入失败: {str(e)}")
|
|
47
|
+
|
|
48
|
+
def export_methodology(output_file):
|
|
49
|
+
"""导出当前方法论到单个文件"""
|
|
50
|
+
try:
|
|
51
|
+
methodologies = _load_all_methodologies()
|
|
52
|
+
|
|
53
|
+
with open(output_file, "w", encoding="utf-8") as f:
|
|
54
|
+
json.dump(methodologies, f, ensure_ascii=False, indent=2)
|
|
55
|
+
|
|
56
|
+
print(f"成功导出 {len(methodologies)} 个方法论到 {output_file}")
|
|
57
|
+
except (OSError, TypeError) as e:
|
|
58
|
+
print(f"导出失败: {str(e)}")
|
|
59
|
+
|
|
60
|
+
def list_methodologies():
|
|
61
|
+
"""列出所有方法论"""
|
|
62
|
+
try:
|
|
63
|
+
methodologies = _load_all_methodologies()
|
|
64
|
+
|
|
65
|
+
if not methodologies:
|
|
66
|
+
print("没有找到方法论")
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
print("可用方法论:")
|
|
70
|
+
for i, (problem_type, _) in enumerate(methodologies.items(), 1):
|
|
71
|
+
print(f"{i}. {problem_type}")
|
|
72
|
+
except (OSError, json.JSONDecodeError) as e:
|
|
73
|
+
print(f"列出方法论失败: {str(e)}")
|
|
74
|
+
|
|
75
|
+
def main():
|
|
76
|
+
"""方法论管理工具主函数"""
|
|
77
|
+
parser = argparse.ArgumentParser(description="方法论管理工具")
|
|
78
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
79
|
+
|
|
80
|
+
# import命令
|
|
81
|
+
import_parser = subparsers.add_parser("import", help="导入方法论文件(合并策略)")
|
|
82
|
+
import_parser.add_argument("input_file", type=str, help="要导入的方法论文件路径")
|
|
83
|
+
|
|
84
|
+
# export命令
|
|
85
|
+
export_parser = subparsers.add_parser("export", help="导出当前方法论到单个文件")
|
|
86
|
+
export_parser.add_argument("output_file", type=str, help="导出文件路径")
|
|
87
|
+
|
|
88
|
+
# list命令
|
|
89
|
+
subparsers.add_parser("list", help="列出所有方法论")
|
|
90
|
+
|
|
91
|
+
args = parser.parse_args()
|
|
92
|
+
|
|
93
|
+
if args.command == "import":
|
|
94
|
+
import_methodology(args.input_file)
|
|
95
|
+
elif args.command == "export":
|
|
96
|
+
export_methodology(args.output_file)
|
|
97
|
+
elif args.command == "list":
|
|
98
|
+
list_methodologies()
|
|
99
|
+
|
|
100
|
+
if __name__ == "__main__":
|
|
101
|
+
main()
|
|
@@ -35,16 +35,16 @@ class MultiAgent(OutputHandler):
|
|
|
35
35
|
to: 智能体名称 # 目标智能体名称
|
|
36
36
|
content: |
|
|
37
37
|
# 消息主题
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
## 背景信息
|
|
40
40
|
[提供必要的上下文和背景]
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
## 具体需求
|
|
43
43
|
[明确表达期望完成的任务]
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
## 相关资源
|
|
46
46
|
[列出相关文档、数据或工具]
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
## 期望结果
|
|
49
49
|
[描述期望的输出格式和内容]
|
|
50
50
|
|
|
@@ -60,7 +60,7 @@ content: |
|
|
|
60
60
|
to: 智能体名称 # 目标智能体名称
|
|
61
61
|
content: |
|
|
62
62
|
# 消息主题
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
## 任务结果
|
|
65
65
|
[任务完成结果,用于反馈]
|
|
66
66
|
{ct("SEND_MESSAGE")}
|
|
@@ -74,22 +74,22 @@ content: |
|
|
|
74
74
|
return len(self._extract_send_msg(response)) > 0
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
def handle(self, response: str) -> Tuple[bool, Any]:
|
|
77
|
+
def handle(self, response: str, agent: Any) -> Tuple[bool, Any]:
|
|
78
78
|
send_messages = self._extract_send_msg(response)
|
|
79
79
|
if len(send_messages) > 1:
|
|
80
80
|
return False, f"Send multiple messages, please only send one message at a time."
|
|
81
81
|
if len(send_messages) == 0:
|
|
82
82
|
return False, ""
|
|
83
83
|
return True, send_messages[0]
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
def name(self) -> str:
|
|
86
86
|
return "SEND_MESSAGE"
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
|
|
88
|
+
|
|
89
89
|
@staticmethod
|
|
90
90
|
def _extract_send_msg(content: str) -> List[Dict]:
|
|
91
91
|
"""Extract send message from content.
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
Args:
|
|
94
94
|
content: The content containing send message
|
|
95
95
|
"""
|
|
@@ -138,4 +138,4 @@ content: {msg['content']}
|
|
|
138
138
|
last_agent = self.agents[msg['to']].name
|
|
139
139
|
msg = self.agents[msg['to']].run(prompt)
|
|
140
140
|
return ""
|
|
141
|
-
|
|
141
|
+
|
|
@@ -5,7 +5,7 @@ from jarvis.jarvis_utils.input import get_multiline_input
|
|
|
5
5
|
|
|
6
6
|
def main():
|
|
7
7
|
"""从YAML配置文件初始化并运行多智能体系统
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
Returns:
|
|
10
10
|
最终处理结果
|
|
11
11
|
"""
|
|
@@ -15,25 +15,25 @@ def main():
|
|
|
15
15
|
parser.add_argument("--config", "-c", required=True, help="YAML配置文件路径")
|
|
16
16
|
parser.add_argument("--input", "-i", help="用户输入(可选)")
|
|
17
17
|
args = parser.parse_args()
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
try:
|
|
20
20
|
with open(args.config, 'r', errors="ignore") as f:
|
|
21
21
|
config_data = yaml.safe_load(f)
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
# 获取agents配置
|
|
24
24
|
agents_config = config_data.get('agents', [])
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
main_agent_name = config_data.get('main_agent', '')
|
|
27
27
|
if not main_agent_name:
|
|
28
28
|
raise ValueError("必须指定main_agent作为主智能体")
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
# 创建并运行多智能体系统
|
|
31
31
|
multi_agent = MultiAgent(agents_config, main_agent_name)
|
|
32
32
|
user_input = args.input if args.input is not None else get_multiline_input("请输入内容(输入空行结束):")
|
|
33
33
|
if user_input == "":
|
|
34
34
|
return
|
|
35
35
|
return multi_agent.run(user_input)
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
except yaml.YAMLError as e:
|
|
38
38
|
raise ValueError(f"YAML配置文件解析错误: {str(e)}")
|
|
39
39
|
except Exception as e:
|