jarvis-ai-assistant 0.1.115__py3-none-any.whl → 0.1.117__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (51) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/{agent.py → jarvis_agent/__init__.py} +122 -203
  3. jarvis/jarvis_agent/output_handler.py +23 -0
  4. jarvis/jarvis_code_agent/code_agent.py +113 -100
  5. jarvis/jarvis_code_agent/file_select.py +28 -7
  6. jarvis/jarvis_code_agent/patch.py +80 -2
  7. jarvis/jarvis_code_agent/relevant_files.py +82 -42
  8. jarvis/jarvis_codebase/main.py +53 -25
  9. jarvis/jarvis_dev/main.py +719 -547
  10. jarvis/jarvis_lsp/cpp.py +1 -1
  11. jarvis/jarvis_lsp/go.py +1 -1
  12. jarvis/jarvis_lsp/registry.py +1 -1
  13. jarvis/jarvis_lsp/rust.py +1 -1
  14. jarvis/jarvis_multi_agent/__init__.py +170 -0
  15. jarvis/jarvis_platform/ai8.py +2 -2
  16. jarvis/jarvis_platform/base.py +14 -4
  17. jarvis/jarvis_platform/kimi.py +2 -2
  18. jarvis/jarvis_platform/ollama.py +1 -1
  19. jarvis/jarvis_platform/openai.py +1 -1
  20. jarvis/jarvis_platform/oyi.py +1 -1
  21. jarvis/jarvis_platform/registry.py +1 -1
  22. jarvis/jarvis_platform_manager/main.py +422 -6
  23. jarvis/jarvis_platform_manager/openai_test.py +139 -0
  24. jarvis/jarvis_rag/main.py +57 -20
  25. jarvis/jarvis_smart_shell/main.py +55 -29
  26. jarvis/jarvis_tools/ask_codebase.py +1 -1
  27. jarvis/jarvis_tools/ask_user.py +1 -1
  28. jarvis/jarvis_tools/chdir.py +1 -1
  29. jarvis/jarvis_tools/code_review.py +3 -3
  30. jarvis/jarvis_tools/create_code_agent.py +1 -1
  31. jarvis/jarvis_tools/create_sub_agent.py +2 -2
  32. jarvis/jarvis_tools/execute_shell.py +1 -1
  33. jarvis/jarvis_tools/file_operation.py +16 -14
  34. jarvis/jarvis_tools/git_commiter.py +2 -2
  35. jarvis/jarvis_tools/methodology.py +1 -1
  36. jarvis/jarvis_tools/rag.py +1 -1
  37. jarvis/jarvis_tools/read_code.py +19 -8
  38. jarvis/jarvis_tools/read_webpage.py +1 -1
  39. jarvis/jarvis_tools/registry.py +157 -31
  40. jarvis/jarvis_tools/search.py +1 -1
  41. jarvis/jarvis_tools/select_code_files.py +1 -1
  42. jarvis/{utils.py → jarvis_utils/__init__.py} +69 -53
  43. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/METADATA +1 -1
  44. jarvis_ai_assistant-0.1.117.dist-info/RECORD +65 -0
  45. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/WHEEL +1 -1
  46. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/entry_points.txt +1 -1
  47. jarvis/multi_agent.py +0 -76
  48. jarvis/utils/date_utils.py +0 -19
  49. jarvis_ai_assistant-0.1.115.dist-info/RECORD +0 -64
  50. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/LICENSE +0 -0
  51. {jarvis_ai_assistant-0.1.115.dist-info → jarvis_ai_assistant-0.1.117.dist-info}/top_level.txt +0 -0
@@ -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.utils import OutputType, PrettyOutput, get_context_token_count, get_max_token_count
12
+ from jarvis.jarvis_utils import OutputType, PrettyOutput, get_context_token_count, get_max_token_count
9
13
 
10
14
 
11
- tool_call_help = """## Tool Usage Format
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
- STRICT RULES:
21
- - EXECUTE ONLY ONE TOOL AT EVERY TURN
22
- - TOOL EXECUTION MUST STRICTLY FOLLOW THE TOOL USAGE FORMAT
23
- - WAIT FOR USER TO PROVIDE EXECUTION RESULTS
24
- - DON'T ASSUME OR IMAGINE RESULTS
25
- - DON'T CREATE FAKE DIALOGUES
26
- - IF CURRENT INFORMATION IS INSUFFICIENT, YOU MAY ASK THE USER FOR MORE INFORMATION
27
- - NOT ALL PROBLEM-SOLVING STEPS ARE MANDATORY, SKIP AS APPROPRIATE
28
- - Request user guidance when multiple iterations show no progress
29
- - ALWAYS use | syntax for string parameters to prevent parsing errors
30
- Example:
31
- <TOOL_CALL>
32
- name: execute_shell
33
- arguments:
34
- command: |
35
- git status --porcelain
36
- </TOOL_CALL>
37
- <TOOL_CALL>
38
- name: execute_shell
39
- arguments:
40
- command: |
41
- git commit -m "fix bug"
42
- </TOOL_CALL>
43
-
44
- - If you can start executing the task, please start directly without asking the user if you can begin.
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
- def load_tools(self) -> str:
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 Format:
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):
@@ -1,6 +1,6 @@
1
1
  from typing import Dict, Any, List
2
2
  from jarvis.jarvis_platform.registry import PlatformRegistry
3
- from jarvis.utils import PrettyOutput, OutputType, get_context_token_count, get_max_token_count
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
@@ -1,6 +1,6 @@
1
1
  from typing import Dict, Any
2
2
 
3
- from jarvis.utils import OutputType, PrettyOutput
3
+ from jarvis.jarvis_utils import OutputType, PrettyOutput
4
4
  from jarvis.jarvis_code_agent.file_select import select_files
5
5
 
6
6
 
@@ -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 fuzz
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
- # Get all possible files from current directory
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
- for root, _, files in os.walk('.'):
305
- for f in files:
306
- path = os.path.join(root, f)
307
- # Remove ./ from the beginning
308
- path = path[2:] if path.startswith('./') else path
309
- all_files.append(path)
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
- (path, fuzz.ratio(file_path.lower(), path.lower()))
318
- for path in all_files
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=-len(file_path),
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, support direction key, history function, and file completion.
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
- # Define prompt style
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
- while True:
357
- # Set prompt
358
- prompt = FormattedText([
359
- ('class:prompt', '... ' if lines else '>>> ')
360
- ])
361
-
362
- # Create new session with new completer for each line
363
- session = PromptSession(
364
- history=None, # Use default history
365
- completer=FileCompleter() # New completer instance for each line
366
- )
367
-
368
- # Get input with completion support
369
- line = session.prompt(
370
- prompt,
371
- style=style,
372
- ).strip()
373
-
374
- # Handle empty line
375
- if not line:
376
- if not lines: # First line is empty
377
- return ""
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"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.115
3
+ Version: 0.1.117
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,5 +1,5 @@
1
1
  [console_scripts]
2
- jarvis = jarvis.agent:main
2
+ jarvis = jarvis.jarvis_agent:main
3
3
  jarvis-code-agent = jarvis.jarvis_code_agent.code_agent:main
4
4
  jarvis-code-review = jarvis.jarvis_tools.code_review:main
5
5
  jarvis-codebase = jarvis.jarvis_codebase.main:main
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 ""
@@ -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