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_tools/registry.py
CHANGED
|
@@ -1,51 +1,91 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from pathlib import Path
|
|
3
|
+
import re
|
|
3
4
|
import sys
|
|
4
|
-
from typing import Any, Callable, Dict, List, Optional
|
|
5
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
5
6
|
|
|
7
|
+
import yaml
|
|
8
|
+
|
|
9
|
+
from jarvis.jarvis_agent.output_handler import OutputHandler
|
|
6
10
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
7
11
|
from jarvis.jarvis_tools.base import Tool
|
|
8
|
-
from jarvis.
|
|
12
|
+
from jarvis.jarvis_utils import OutputType, PrettyOutput, get_context_token_count, get_max_token_count
|
|
9
13
|
|
|
10
14
|
|
|
11
|
-
tool_call_help = """
|
|
15
|
+
tool_call_help = """
|
|
16
|
+
# 🛠️ Tool Usage System
|
|
17
|
+
You are using a tool execution system that requires precise formatting and strict rules.
|
|
12
18
|
|
|
19
|
+
# 📋 Tool Call Format
|
|
20
|
+
```yaml
|
|
13
21
|
<TOOL_CALL>
|
|
14
22
|
name: tool_name
|
|
15
23
|
arguments:
|
|
16
24
|
param1: value1
|
|
17
25
|
param2: value2
|
|
18
26
|
</TOOL_CALL>
|
|
27
|
+
```
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
29
|
+
# ❗ Critical Rules
|
|
30
|
+
1. ONE Tool Per Turn
|
|
31
|
+
- Execute only ONE tool at a time
|
|
32
|
+
- Wait for results before next action
|
|
33
|
+
|
|
34
|
+
2. Strict Format Adherence
|
|
35
|
+
- Follow exact format shown above
|
|
36
|
+
- Use proper YAML indentation
|
|
37
|
+
- Include all required parameters
|
|
38
|
+
|
|
39
|
+
3. Result Handling
|
|
40
|
+
- Wait for execution results
|
|
41
|
+
- Never assume outcomes
|
|
42
|
+
- Don't create fake responses
|
|
43
|
+
- Don't imagine dialogues
|
|
44
|
+
|
|
45
|
+
4. Information Management
|
|
46
|
+
- Ask user if info is insufficient
|
|
47
|
+
- Skip unnecessary steps
|
|
48
|
+
- Request guidance if stuck
|
|
49
|
+
- Don't proceed with incomplete info
|
|
50
|
+
|
|
51
|
+
# 📝 String Parameter Format
|
|
52
|
+
ALWAYS use | syntax for string parameters:
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
<TOOL_CALL>
|
|
56
|
+
name: execute_shell
|
|
57
|
+
arguments:
|
|
58
|
+
command: |
|
|
59
|
+
git status --porcelain
|
|
60
|
+
</TOOL_CALL>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
# 💡 Best Practices
|
|
64
|
+
- Start execution immediately when ready
|
|
65
|
+
- No need to ask for permission to begin
|
|
66
|
+
- Use proper string formatting
|
|
67
|
+
- Monitor progress and adjust
|
|
68
|
+
- Request help when stuck
|
|
69
|
+
|
|
70
|
+
# ⚠️ Common Mistakes to Avoid
|
|
71
|
+
- Multiple tool calls at once
|
|
72
|
+
- Missing | for string parameters
|
|
73
|
+
- Assuming tool results
|
|
74
|
+
- Creating fictional dialogues
|
|
75
|
+
- Proceeding without required info
|
|
45
76
|
"""
|
|
46
77
|
|
|
47
|
-
class ToolRegistry:
|
|
48
|
-
|
|
78
|
+
class ToolRegistry(OutputHandler):
|
|
79
|
+
|
|
80
|
+
def name(self) -> str:
|
|
81
|
+
return "TOOL_CALL"
|
|
82
|
+
|
|
83
|
+
def can_handle(self, response: str) -> bool:
|
|
84
|
+
if self._extract_tool_calls(response):
|
|
85
|
+
return True
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
def prompt(self) -> str:
|
|
49
89
|
"""Load tools"""
|
|
50
90
|
tools = self.get_all_tools()
|
|
51
91
|
if tools:
|
|
@@ -57,6 +97,16 @@ class ToolRegistry:
|
|
|
57
97
|
tools_prompt += tool_call_help
|
|
58
98
|
return tools_prompt
|
|
59
99
|
return ""
|
|
100
|
+
|
|
101
|
+
def handle(self, response: str) -> Tuple[bool, Any]:
|
|
102
|
+
tool_calls = self._extract_tool_calls(response)
|
|
103
|
+
if len(tool_calls) > 1:
|
|
104
|
+
PrettyOutput.print(f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([tool_call['name'] for tool_call in tool_calls])}", OutputType.WARNING)
|
|
105
|
+
return False, f"Call failed: Handle multiple tool calls, please ONLY handle one tool call at a time."
|
|
106
|
+
if len(tool_calls) == 0:
|
|
107
|
+
return False, ""
|
|
108
|
+
tool_call = tool_calls[0]
|
|
109
|
+
return False, self.handle_tool_calls(tool_call)
|
|
60
110
|
|
|
61
111
|
def __init__(self):
|
|
62
112
|
"""Initialize tool registry"""
|
|
@@ -169,6 +219,30 @@ class ToolRegistry:
|
|
|
169
219
|
except Exception as e:
|
|
170
220
|
PrettyOutput.print(f"从 {Path(file_path).name} 加载工具失败: {str(e)}", OutputType.ERROR)
|
|
171
221
|
return False
|
|
222
|
+
@staticmethod
|
|
223
|
+
def _extract_tool_calls(content: str) -> List[Dict]:
|
|
224
|
+
"""Extract tool calls from content.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
content: The content containing tool calls
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
List[Dict]: List of extracted tool calls with name and arguments
|
|
231
|
+
|
|
232
|
+
Raises:
|
|
233
|
+
Exception: If tool call is missing necessary fields
|
|
234
|
+
"""
|
|
235
|
+
# Split content into lines
|
|
236
|
+
data = re.findall(r'<TOOL_CALL>(.*?)</TOOL_CALL>', content, re.DOTALL)
|
|
237
|
+
ret = []
|
|
238
|
+
for item in data:
|
|
239
|
+
try:
|
|
240
|
+
msg = yaml.safe_load(item)
|
|
241
|
+
if 'name' in msg and 'arguments' in msg:
|
|
242
|
+
ret.append(msg)
|
|
243
|
+
except Exception as e:
|
|
244
|
+
continue
|
|
245
|
+
return ret
|
|
172
246
|
|
|
173
247
|
def register_tool(self, name: str, description: str, parameters: Dict, func: Callable):
|
|
174
248
|
"""Register a new tool"""
|
|
@@ -197,14 +271,66 @@ class ToolRegistry:
|
|
|
197
271
|
args = tool_call["arguments"]
|
|
198
272
|
|
|
199
273
|
tool_call_help = """
|
|
200
|
-
Tool Usage
|
|
274
|
+
# 🛠️ Tool Usage System
|
|
275
|
+
You are using a tool execution system that requires precise formatting and strict rules.
|
|
201
276
|
|
|
277
|
+
# 📋 Tool Call Format
|
|
278
|
+
```yaml
|
|
202
279
|
<TOOL_CALL>
|
|
203
280
|
name: tool_name
|
|
204
281
|
arguments:
|
|
205
282
|
param1: value1
|
|
206
283
|
param2: value2
|
|
207
284
|
</TOOL_CALL>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
# ❗ Critical Rules
|
|
288
|
+
1. ONE Tool Per Turn
|
|
289
|
+
- Execute only ONE tool at a time
|
|
290
|
+
- Wait for results before next action
|
|
291
|
+
|
|
292
|
+
2. Strict Format Adherence
|
|
293
|
+
- Follow exact format shown above
|
|
294
|
+
- Use proper YAML indentation
|
|
295
|
+
- Include all required parameters
|
|
296
|
+
|
|
297
|
+
3. Result Handling
|
|
298
|
+
- Wait for execution results
|
|
299
|
+
- Never assume outcomes
|
|
300
|
+
- Don't create fake responses
|
|
301
|
+
- Don't imagine dialogues
|
|
302
|
+
|
|
303
|
+
4. Information Management
|
|
304
|
+
- Ask user if info is insufficient
|
|
305
|
+
- Skip unnecessary steps
|
|
306
|
+
- Request guidance if stuck
|
|
307
|
+
- Don't proceed with incomplete info
|
|
308
|
+
|
|
309
|
+
# 📝 String Parameter Format
|
|
310
|
+
ALWAYS use | syntax for string parameters:
|
|
311
|
+
|
|
312
|
+
```yaml
|
|
313
|
+
<TOOL_CALL>
|
|
314
|
+
name: execute_shell
|
|
315
|
+
arguments:
|
|
316
|
+
command: |
|
|
317
|
+
git status --porcelain
|
|
318
|
+
</TOOL_CALL>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
# 💡 Best Practices
|
|
322
|
+
- Start execution immediately when ready
|
|
323
|
+
- No need to ask for permission to begin
|
|
324
|
+
- Use proper string formatting
|
|
325
|
+
- Monitor progress and adjust
|
|
326
|
+
- Request help when stuck
|
|
327
|
+
|
|
328
|
+
# ⚠️ Common Mistakes to Avoid
|
|
329
|
+
- Multiple tool calls at once
|
|
330
|
+
- Missing | for string parameters
|
|
331
|
+
- Assuming tool results
|
|
332
|
+
- Creating fictional dialogues
|
|
333
|
+
- Proceeding without required info
|
|
208
334
|
"""
|
|
209
335
|
|
|
210
336
|
if isinstance(args, str):
|
jarvis/jarvis_tools/search.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Dict, Any, List
|
|
2
2
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
3
|
-
from jarvis.
|
|
3
|
+
from jarvis.jarvis_utils import PrettyOutput, OutputType, get_context_token_count, get_max_token_count
|
|
4
4
|
from jarvis.jarvis_tools.read_webpage import WebpageTool
|
|
5
5
|
from playwright.sync_api import sync_playwright
|
|
6
6
|
from urllib.parse import quote
|
|
@@ -29,7 +29,8 @@ from rich.syntax import Syntax
|
|
|
29
29
|
|
|
30
30
|
from prompt_toolkit.completion import Completer, Completion, PathCompleter
|
|
31
31
|
from prompt_toolkit.document import Document
|
|
32
|
-
from fuzzywuzzy import
|
|
32
|
+
from fuzzywuzzy import process
|
|
33
|
+
from prompt_toolkit.key_binding import KeyBindings
|
|
33
34
|
|
|
34
35
|
# 初始化colorama
|
|
35
36
|
colorama.init()
|
|
@@ -271,8 +272,8 @@ class FileCompleter(Completer):
|
|
|
271
272
|
"""Custom completer for file paths with fuzzy matching."""
|
|
272
273
|
def __init__(self):
|
|
273
274
|
self.path_completer = PathCompleter()
|
|
274
|
-
self.max_suggestions = 10
|
|
275
|
-
self.min_score = 10
|
|
275
|
+
self.max_suggestions = 10
|
|
276
|
+
self.min_score = 10
|
|
276
277
|
|
|
277
278
|
def get_completions(self, document: Document, complete_event):
|
|
278
279
|
text = document.text_before_cursor
|
|
@@ -299,23 +300,33 @@ class FileCompleter(Completer):
|
|
|
299
300
|
# Get the text after the current @
|
|
300
301
|
file_path = text_after_at.strip()
|
|
301
302
|
|
|
302
|
-
#
|
|
303
|
+
# 计算需要删除的字符数(包括@符号)
|
|
304
|
+
replace_length = len(text_after_at) + 1 # +1 包含@符号
|
|
305
|
+
|
|
306
|
+
# Get all possible files using git ls-files only
|
|
303
307
|
all_files = []
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
308
|
+
try:
|
|
309
|
+
# Use git ls-files to get tracked files
|
|
310
|
+
import subprocess
|
|
311
|
+
result = subprocess.run(['git', 'ls-files'],
|
|
312
|
+
stdout=subprocess.PIPE,
|
|
313
|
+
stderr=subprocess.PIPE,
|
|
314
|
+
text=True)
|
|
315
|
+
if result.returncode == 0:
|
|
316
|
+
all_files = [line.strip() for line in result.stdout.splitlines() if line.strip()]
|
|
317
|
+
except Exception:
|
|
318
|
+
# If git command fails, just use an empty list
|
|
319
|
+
pass
|
|
310
320
|
|
|
311
321
|
# If no input after @, show all files
|
|
312
322
|
# Otherwise use fuzzy matching
|
|
313
323
|
if not file_path:
|
|
314
324
|
scored_files = [(path, 100) for path in all_files[:self.max_suggestions]]
|
|
315
325
|
else:
|
|
326
|
+
scored_files_data = process.extract(file_path, all_files, limit=self.max_suggestions)
|
|
316
327
|
scored_files = [
|
|
317
|
-
(
|
|
318
|
-
for
|
|
328
|
+
(m[0], m[1])
|
|
329
|
+
for m in scored_files_data
|
|
319
330
|
]
|
|
320
331
|
# Sort by score and take top results
|
|
321
332
|
scored_files.sort(key=lambda x: x[1], reverse=True)
|
|
@@ -324,66 +335,71 @@ class FileCompleter(Completer):
|
|
|
324
335
|
# Return completions for files
|
|
325
336
|
for path, score in scored_files:
|
|
326
337
|
if not file_path or score > self.min_score:
|
|
327
|
-
display_text = path
|
|
338
|
+
display_text = path # 显示时不带反引号
|
|
328
339
|
if file_path and score < 100:
|
|
329
340
|
display_text = f"{path} ({score}%)"
|
|
330
341
|
completion = Completion(
|
|
331
|
-
text=path,
|
|
332
|
-
start_position=-
|
|
342
|
+
text=f"`{path}`", # 添加反引号包裹路径
|
|
343
|
+
start_position=-replace_length,
|
|
333
344
|
display=display_text,
|
|
334
345
|
display_meta="File"
|
|
335
346
|
)
|
|
336
347
|
yield completion
|
|
337
348
|
|
|
338
349
|
def get_multiline_input(tip: str) -> str:
|
|
339
|
-
"""Get multi-line input
|
|
350
|
+
"""Get multi-line input with enhanced completion confirmation"""
|
|
351
|
+
# 单行输入说明
|
|
352
|
+
PrettyOutput.section("用户输入 - 使用 @ 触发文件补全,Tab 选择补全项,Ctrl+J 提交", OutputType.USER)
|
|
340
353
|
|
|
341
|
-
Args:
|
|
342
|
-
tip: The prompt tip to display
|
|
343
|
-
|
|
344
|
-
Returns:
|
|
345
|
-
str: The entered text
|
|
346
|
-
"""
|
|
347
354
|
print(f"{Fore.GREEN}{tip}{ColoramaStyle.RESET_ALL}")
|
|
348
355
|
|
|
349
|
-
#
|
|
356
|
+
# 自定义按键绑定
|
|
357
|
+
bindings = KeyBindings()
|
|
358
|
+
|
|
359
|
+
@bindings.add('enter')
|
|
360
|
+
def _(event):
|
|
361
|
+
# 当有补全菜单时,回车键确认补全
|
|
362
|
+
if event.current_buffer.complete_state:
|
|
363
|
+
event.current_buffer.apply_completion(event.current_buffer.complete_state.current_completion)
|
|
364
|
+
else:
|
|
365
|
+
# 没有补全菜单时插入换行
|
|
366
|
+
event.current_buffer.insert_text('\n')
|
|
367
|
+
|
|
368
|
+
@bindings.add('c-j') # 修改为支持的按键组合
|
|
369
|
+
def _(event):
|
|
370
|
+
# 使用 Ctrl+J 提交输入
|
|
371
|
+
event.current_buffer.validate_and_handle()
|
|
372
|
+
|
|
350
373
|
style = PromptStyle.from_dict({
|
|
351
374
|
'prompt': 'ansicyan',
|
|
352
375
|
})
|
|
353
|
-
|
|
354
|
-
lines = []
|
|
376
|
+
|
|
355
377
|
try:
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
break # End multi-line input
|
|
379
|
-
|
|
380
|
-
lines.append(line)
|
|
381
|
-
|
|
378
|
+
session = PromptSession(
|
|
379
|
+
history=None,
|
|
380
|
+
completer=FileCompleter(),
|
|
381
|
+
key_bindings=bindings,
|
|
382
|
+
complete_while_typing=True,
|
|
383
|
+
multiline=True, # 启用原生多行支持
|
|
384
|
+
vi_mode=False,
|
|
385
|
+
mouse_support=False
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
prompt = FormattedText([
|
|
389
|
+
('class:prompt', '>>> ')
|
|
390
|
+
])
|
|
391
|
+
|
|
392
|
+
# 单次获取多行输入
|
|
393
|
+
text = session.prompt(
|
|
394
|
+
prompt,
|
|
395
|
+
style=style,
|
|
396
|
+
).strip()
|
|
397
|
+
|
|
398
|
+
return text
|
|
399
|
+
|
|
382
400
|
except KeyboardInterrupt:
|
|
383
401
|
PrettyOutput.print("输入已取消", OutputType.INFO)
|
|
384
402
|
return ""
|
|
385
|
-
|
|
386
|
-
return "\n".join(lines)
|
|
387
403
|
|
|
388
404
|
def init_env():
|
|
389
405
|
"""Load environment variables from ~/.jarvis/env"""
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
jarvis/__init__.py,sha256=5w1BCkqWjNXnQYjmLPW7k0NeGNQ1LZvOLbVCFhky-Ss,51
|
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=g5ig3AdJeR4ANY5hKpmtFr843vgTlxb5WoSc-6FBFkM,21618
|
|
3
|
+
jarvis/jarvis_agent/output_handler.py,sha256=kJeFTjjSu0K_2p0wyhq2veSZuhRXoaFC_8wVaoBKX0w,401
|
|
4
|
+
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
jarvis/jarvis_code_agent/code_agent.py,sha256=D8og7lZ5j1eKNNz-kY2E5YM-MsiuFzJvCuJZc7Kz3J8,7630
|
|
6
|
+
jarvis/jarvis_code_agent/file_select.py,sha256=uxNA0ODy7NHMDNnCS9tFhttQ-omILUya7OjX3WuhSfo,8850
|
|
7
|
+
jarvis/jarvis_code_agent/patch.py,sha256=i4AZYoxwv0igeC5oe9ls5mwYVNdcnL-yzOkcshKC-JM,6355
|
|
8
|
+
jarvis/jarvis_code_agent/relevant_files.py,sha256=u9wae9sn-XLaUoSK69-LRLomHWcE-K1y7W10BFdmQVE,3402
|
|
9
|
+
jarvis/jarvis_codebase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
jarvis/jarvis_codebase/main.py,sha256=6JPaAkRUtQpmp4eFtsdCsiuRxWgI6hx9VE2b-J8a3JA,39791
|
|
11
|
+
jarvis/jarvis_dev/main.py,sha256=C8uLge20ZO9smGLUAvHjQlsWBOMI1HQ-WSSDBbdGGRk,21284
|
|
12
|
+
jarvis/jarvis_lsp/base.py,sha256=_7pdbMKjdtYBW0DsRbjIodDHM3J7df-YgXHejN_WIrU,4490
|
|
13
|
+
jarvis/jarvis_lsp/cpp.py,sha256=sYQHEl0FoVC5Iw2pJvvGKpeNLD95XjNuTOINvdZLgME,4986
|
|
14
|
+
jarvis/jarvis_lsp/go.py,sha256=3soEuID2XV65zaxyR70RxNsvtm02l9PEZ46F_nsDdqY,5311
|
|
15
|
+
jarvis/jarvis_lsp/python.py,sha256=_Vo2pPwVh_vAsyS0XowXMbT4Syd78naPEZj586bi004,4747
|
|
16
|
+
jarvis/jarvis_lsp/registry.py,sha256=x7OFlW10AWQ_tWEbHWkdpngoFHTP3t1vSyGxVVLk46w,9933
|
|
17
|
+
jarvis/jarvis_lsp/rust.py,sha256=ZvUoOZm9GWLl3kobfByBuTGrQ8aM2dLuNxS_NHr1aQQ,5542
|
|
18
|
+
jarvis/jarvis_multi_agent/__init__.py,sha256=Z6QaRZrqUUa6r6Pe_KZi34Ymle5amQe1N-AINxiOi1c,6011
|
|
19
|
+
jarvis/jarvis_platform/__init__.py,sha256=mrOt67nselz_H1gX9wdAO4y2DY5WPXzABqJbr5Des8k,63
|
|
20
|
+
jarvis/jarvis_platform/ai8.py,sha256=AO42OVzrwQMDY74TR2B4gtrsfeRVxJRf5OmHBM3cVQY,11948
|
|
21
|
+
jarvis/jarvis_platform/base.py,sha256=8iYNCe7PGSs9sDG66jeNDr2TYzWUYBiGVvKgHTDsFLg,2641
|
|
22
|
+
jarvis/jarvis_platform/kimi.py,sha256=WCRyG7jnqnpHNu6M9_pGFE_RBVKqYDtd_F1EPdT_FKU,15761
|
|
23
|
+
jarvis/jarvis_platform/ollama.py,sha256=TsBEg8crPmBiLvMRDtXYVa2AIdeog36MmW2tn5j9x8U,5613
|
|
24
|
+
jarvis/jarvis_platform/openai.py,sha256=rHzc20Frd5LzS0Wm97FxglSai65UKkY2ju8rg6q-gOg,4445
|
|
25
|
+
jarvis/jarvis_platform/oyi.py,sha256=3yuWHEGtGV--6IuFCCc1R2F1Y-p21xy4Vk-P5pQRAys,14994
|
|
26
|
+
jarvis/jarvis_platform/registry.py,sha256=SmBcf86h6uf4TB7cut-Bhb9Ivj5z2wAg1pWkcJLi_80,8508
|
|
27
|
+
jarvis/jarvis_platform_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
jarvis/jarvis_platform_manager/main.py,sha256=Ja0f-PiYxABIj-Ioh9NNZuqy0dB2Jk7dhrObgzgXApw,20958
|
|
29
|
+
jarvis/jarvis_platform_manager/openai_test.py,sha256=BAoZgOJ431gjjbbdgiX-ARfI0aLXK_cRLAQQJzQI6MI,5200
|
|
30
|
+
jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
jarvis/jarvis_rag/main.py,sha256=2Nq5d5DBXdZ35_KEeHkdKJPFzxKgxt9bkwp1PMHpLzI,31754
|
|
32
|
+
jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
+
jarvis/jarvis_smart_shell/main.py,sha256=ZD_rqV-2S3xA1jW1TPEzM4PHLBYOjZFtgJZxHpZZ0TE,4476
|
|
34
|
+
jarvis/jarvis_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
+
jarvis/jarvis_tools/ask_codebase.py,sha256=MF7zeBqVDa7T45JxDR9mePA92kzZm5bQ9op8o5Qo9lM,3003
|
|
36
|
+
jarvis/jarvis_tools/ask_user.py,sha256=tIyiKk9F8xchjQ3Yh5fMQjhpflQTuh75HTuXMftGxZY,1827
|
|
37
|
+
jarvis/jarvis_tools/base.py,sha256=c0DMoDDPxmsqUYJR989zgUs7nIYRY6GWBrAdusIZKjc,656
|
|
38
|
+
jarvis/jarvis_tools/chdir.py,sha256=06GAtMqoi5fT1FXD2HUUlHKosVtz-Z8KI13lpEFQw3g,1820
|
|
39
|
+
jarvis/jarvis_tools/code_review.py,sha256=DFnw-li4afcpHdfDC2TX_PHSNn7GxEHbtagCAkLQ-9U,8598
|
|
40
|
+
jarvis/jarvis_tools/create_code_agent.py,sha256=4tJLcKk_e1AOyN2wgOeAWVB9N4aa7GsusUNdaYmAYww,3906
|
|
41
|
+
jarvis/jarvis_tools/create_sub_agent.py,sha256=ldpNn5LczybExvt9Sz4t1ybetLX-dTJIAF5f_oH-Z3M,2869
|
|
42
|
+
jarvis/jarvis_tools/execute_shell.py,sha256=MwgVyI1O1wshU9yR-DvSWIgoSQpVjtH9JpjVQvSrKF0,2566
|
|
43
|
+
jarvis/jarvis_tools/file_operation.py,sha256=8CAWozKfsRx_TzCmRPcNSj-bRo3K69IEDmmN8IWMlmg,5647
|
|
44
|
+
jarvis/jarvis_tools/git_commiter.py,sha256=oq_jh6YkB-cZi2XRhu139seZeF7Vubwx04cvpugjmt4,2732
|
|
45
|
+
jarvis/jarvis_tools/lsp_find_definition.py,sha256=xV8YeN1RJfwd2F3gE6OnDeTwl-AnCmrxueHocbXkQOc,4800
|
|
46
|
+
jarvis/jarvis_tools/lsp_find_references.py,sha256=FohlJeLfTxcMUASfbjOT93hQGtI2WeyTpMGwRwShW_I,4043
|
|
47
|
+
jarvis/jarvis_tools/lsp_get_diagnostics.py,sha256=bEvbDk8TnKg9TTFFxMrYOJm5TBDgz5gO04WJFQUwQQE,4490
|
|
48
|
+
jarvis/jarvis_tools/lsp_get_document_symbols.py,sha256=dspL6r9HYnXL5TpARSApFY3IQLm2kcYVNVWCff2xoXI,3080
|
|
49
|
+
jarvis/jarvis_tools/lsp_prepare_rename.py,sha256=RxUyIef4awtp-jgupcD1LcPlno9P3mOE8AS3_Fm71Ys,4832
|
|
50
|
+
jarvis/jarvis_tools/lsp_validate_edit.py,sha256=M0iglK2QbnIEFv0RYK6o2iAYnv259jB6EU7To-rc51E,5247
|
|
51
|
+
jarvis/jarvis_tools/methodology.py,sha256=JvHV6rHhC6fbPuSqC6UHFaGEE39d4g7zFLodR72wM0g,5758
|
|
52
|
+
jarvis/jarvis_tools/rag.py,sha256=ZhmvwVUHBFsttDRdVncc-S-a-XVOy5jbdNd7Vk4uTlk,4942
|
|
53
|
+
jarvis/jarvis_tools/read_code.py,sha256=rt5m-bcXY0W-WLrGgr5xG08KxB1nNGD5UD0TSj7v7lg,6826
|
|
54
|
+
jarvis/jarvis_tools/read_webpage.py,sha256=7QamwBi5s7lD-jTcjD0wsBvkmWPRC9-K-0JkGgeTpvs,3063
|
|
55
|
+
jarvis/jarvis_tools/registry.py,sha256=y3cVCT8dsAnWuT8QyDccqkyCtc3IMkccZZwVOndNMH0,14883
|
|
56
|
+
jarvis/jarvis_tools/search.py,sha256=NHrFpAqg6dtws_9wLJvIZimjeJ-kekETi0Bg0AWMG08,11437
|
|
57
|
+
jarvis/jarvis_tools/select_code_files.py,sha256=242K79SiNF_gY7fpThY3xoi2ihfgJdjB27X1jKkeXK0,1889
|
|
58
|
+
jarvis/jarvis_tools/tool_generator.py,sha256=jdniHyKcEyF9KyouudrCoZBH3czZmQXc3ns0_trZ3yU,6332
|
|
59
|
+
jarvis/jarvis_utils/__init__.py,sha256=2GbATVP6NXe8obg2YYArNRAeSj0X4-GCULZrMiHh3fw,29885
|
|
60
|
+
jarvis_ai_assistant-0.1.117.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
|
61
|
+
jarvis_ai_assistant-0.1.117.dist-info/METADATA,sha256=uTPQoN_2eEdKrJ3V7CRgW3imgk7P3nt6uN4mG_Yvb4A,13701
|
|
62
|
+
jarvis_ai_assistant-0.1.117.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
|
63
|
+
jarvis_ai_assistant-0.1.117.dist-info/entry_points.txt,sha256=YgRAus5Rz4xVwB6DxWKokQd0zoKIjyRdyvmp8J5CI0w,528
|
|
64
|
+
jarvis_ai_assistant-0.1.117.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
65
|
+
jarvis_ai_assistant-0.1.117.dist-info/RECORD,,
|
jarvis/multi_agent.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from typing import Dict, List, Optional
|
|
4
|
-
|
|
5
|
-
from jarvis.agent import Agent
|
|
6
|
-
from jarvis.utils import OutputType, PrettyOutput
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class AgentConfig:
|
|
10
|
-
def __init__(self, **config):
|
|
11
|
-
self.system_prompt = config.get('system_prompt', '')
|
|
12
|
-
self.name = config.get('name', 'Jarvis')
|
|
13
|
-
self.description = config.get('description', '')
|
|
14
|
-
self.is_sub_agent = config.get('is_sub_agent', False)
|
|
15
|
-
self.tool_registry = config.get('tool_registry', [])
|
|
16
|
-
self.platform = config.get('platform')
|
|
17
|
-
self.model_name = config.get('model_name')
|
|
18
|
-
self.summary_prompt = config.get('summary_prompt')
|
|
19
|
-
self.auto_complete = config.get('auto_complete', False)
|
|
20
|
-
self.output_handler_before_tool = config.get('output_handler_before_tool')
|
|
21
|
-
self.output_handler_after_tool = config.get('output_handler_after_tool')
|
|
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:
|
|
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 init_agents(self):
|
|
34
|
-
for agent_config in self.agents_config:
|
|
35
|
-
agent = Agent(system_prompt=agent_config.system_prompt,
|
|
36
|
-
name=agent_config.name,
|
|
37
|
-
description=agent_config.description,
|
|
38
|
-
model_name=agent_config.model_name,
|
|
39
|
-
platform=agent_config.platform,
|
|
40
|
-
max_context_length=agent_config.max_context_length,
|
|
41
|
-
support_send_msg=True,
|
|
42
|
-
execute_tool_confirm=agent_config.execute_tool_confirm,
|
|
43
|
-
input_handler=agent_config.input_handler,
|
|
44
|
-
output_handler_before_tool=agent_config.output_handler_before_tool,
|
|
45
|
-
output_handler_after_tool=agent_config.output_handler_after_tool,
|
|
46
|
-
use_methodology=False,
|
|
47
|
-
record_methodology=False,
|
|
48
|
-
need_summary=False,
|
|
49
|
-
auto_complete=agent_config.auto_complete,
|
|
50
|
-
summary_prompt=agent_config.summary_prompt,
|
|
51
|
-
is_sub_agent=agent_config.is_sub_agent,
|
|
52
|
-
tool_registry=agent_config.tool_registry,
|
|
53
|
-
)
|
|
54
|
-
agent.system_prompt += "You can send message to following agents: " + "\n".join([f"{c.name}: {c.description}" for c in self.agents_config])
|
|
55
|
-
self.agents[agent_config.name] = agent
|
|
56
|
-
|
|
57
|
-
def run(self, user_input: str, file_list: Optional[List[str]] = None) -> str:
|
|
58
|
-
last_agent = self.main_agent_name
|
|
59
|
-
msg = self.agents[self.main_agent_name].run(user_input, file_list)
|
|
60
|
-
while msg:
|
|
61
|
-
if isinstance(msg, str):
|
|
62
|
-
return msg
|
|
63
|
-
elif isinstance(msg, Dict):
|
|
64
|
-
prompt = f"""
|
|
65
|
-
Please handle this message:
|
|
66
|
-
from: {last_agent}
|
|
67
|
-
content: {msg['content']}
|
|
68
|
-
"""
|
|
69
|
-
if msg['to'] not in self.agents:
|
|
70
|
-
PrettyOutput.print(f"没有找到{msg['to']},重试...", OutputType.WARNING)
|
|
71
|
-
msg = self.agents[last_agent].run(f"The agent {msg['to']} is not found, agent list: {self.agents.keys()}")
|
|
72
|
-
continue
|
|
73
|
-
PrettyOutput.print(f"{last_agent} 发送消息给 {msg['to']}...", OutputType.INFO)
|
|
74
|
-
last_agent = self.agents[msg['to']]
|
|
75
|
-
msg = self.agents[msg['to']].run(prompt)
|
|
76
|
-
return ""
|
jarvis/utils/date_utils.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
|
|
3
|
-
class DateValidator:
|
|
4
|
-
@staticmethod
|
|
5
|
-
def validate_iso_date(date_str: str) -> bool:
|
|
6
|
-
try:
|
|
7
|
-
datetime.fromisoformat(date_str)
|
|
8
|
-
return True
|
|
9
|
-
except ValueError:
|
|
10
|
-
return False
|
|
11
|
-
|
|
12
|
-
@staticmethod
|
|
13
|
-
def validate_date_range(start: str, end: str) -> bool:
|
|
14
|
-
try:
|
|
15
|
-
start_dt = datetime.fromisoformat(start)
|
|
16
|
-
end_dt = datetime.fromisoformat(end)
|
|
17
|
-
return start_dt <= end_dt
|
|
18
|
-
except ValueError:
|
|
19
|
-
return False
|