jarvis-ai-assistant 0.1.101__py3-none-any.whl → 0.1.103__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 (54) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +140 -140
  3. jarvis/jarvis_code_agent/code_agent.py +234 -0
  4. jarvis/{jarvis_coder → jarvis_code_agent}/file_select.py +16 -17
  5. jarvis/jarvis_code_agent/patch.py +118 -0
  6. jarvis/jarvis_code_agent/relevant_files.py +66 -0
  7. jarvis/jarvis_codebase/main.py +32 -29
  8. jarvis/jarvis_platform/main.py +5 -3
  9. jarvis/jarvis_rag/main.py +11 -15
  10. jarvis/jarvis_smart_shell/main.py +2 -2
  11. jarvis/models/ai8.py +1 -0
  12. jarvis/models/kimi.py +36 -30
  13. jarvis/models/ollama.py +17 -11
  14. jarvis/models/openai.py +15 -12
  15. jarvis/models/oyi.py +22 -7
  16. jarvis/models/registry.py +1 -25
  17. jarvis/tools/__init__.py +0 -6
  18. jarvis/tools/ask_codebase.py +99 -0
  19. jarvis/tools/ask_user.py +1 -9
  20. jarvis/tools/chdir.py +1 -1
  21. jarvis/tools/code_review.py +163 -0
  22. jarvis/tools/create_code_sub_agent.py +19 -45
  23. jarvis/tools/create_code_test_agent.py +115 -0
  24. jarvis/tools/create_ctags_agent.py +176 -0
  25. jarvis/tools/create_sub_agent.py +2 -2
  26. jarvis/tools/execute_shell.py +2 -2
  27. jarvis/tools/file_operation.py +2 -2
  28. jarvis/tools/find_in_codebase.py +108 -0
  29. jarvis/tools/git_commiter.py +68 -0
  30. jarvis/tools/methodology.py +3 -3
  31. jarvis/tools/rag.py +6 -3
  32. jarvis/tools/read_code.py +147 -0
  33. jarvis/tools/read_webpage.py +1 -1
  34. jarvis/tools/registry.py +92 -68
  35. jarvis/tools/search.py +8 -6
  36. jarvis/tools/select_code_files.py +4 -4
  37. jarvis/utils.py +270 -95
  38. {jarvis_ai_assistant-0.1.101.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/METADATA +9 -5
  39. jarvis_ai_assistant-0.1.103.dist-info/RECORD +51 -0
  40. {jarvis_ai_assistant-0.1.101.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/entry_points.txt +4 -2
  41. jarvis/jarvis_code_agent/main.py +0 -202
  42. jarvis/jarvis_coder/__init__.py +0 -0
  43. jarvis/jarvis_coder/git_utils.py +0 -123
  44. jarvis/jarvis_coder/main.py +0 -241
  45. jarvis/jarvis_coder/patch_handler.py +0 -340
  46. jarvis/jarvis_coder/plan_generator.py +0 -145
  47. jarvis/tools/execute_code_modification.py +0 -70
  48. jarvis/tools/find_files.py +0 -119
  49. jarvis/tools/generate_tool.py +0 -174
  50. jarvis/tools/thinker.py +0 -151
  51. jarvis_ai_assistant-0.1.101.dist-info/RECORD +0 -51
  52. {jarvis_ai_assistant-0.1.101.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/LICENSE +0 -0
  53. {jarvis_ai_assistant-0.1.101.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/WHEEL +0 -0
  54. {jarvis_ai_assistant-0.1.101.dist-info → jarvis_ai_assistant-0.1.103.dist-info}/top_level.txt +0 -0
jarvis/utils.py CHANGED
@@ -1,7 +1,5 @@
1
- from ast import List, Str
2
1
  import hashlib
3
2
  from pathlib import Path
4
- import sys
5
3
  import time
6
4
  import os
7
5
  from enum import Enum
@@ -18,20 +16,53 @@ from transformers import AutoModelForSequenceClassification, AutoTokenizer
18
16
  import torch
19
17
  import yaml
20
18
  import faiss
19
+ from pygments.lexers import guess_lexer
20
+ from pygments.util import ClassNotFound
21
+
22
+ from rich.console import Console
23
+ from rich.theme import Theme
24
+ from rich.panel import Panel
25
+ from rich.text import Text
26
+ from rich.traceback import install as install_rich_traceback
27
+ from rich.syntax import Syntax
28
+
29
+ from prompt_toolkit.completion import Completer, Completion, PathCompleter
30
+ from prompt_toolkit.document import Document
31
+ from fuzzywuzzy import fuzz
21
32
 
22
33
  # 初始化colorama
23
34
  colorama.init()
24
35
 
25
36
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
26
- os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
27
37
 
28
38
  current_agent = []
29
39
 
40
+ # Install rich traceback handler
41
+ install_rich_traceback()
42
+
43
+ # Create console with custom theme
44
+ custom_theme = Theme({
45
+ "info": "yellow",
46
+ "warning": "yellow",
47
+ "error": "red",
48
+ "success": "green",
49
+ "system": "cyan",
50
+ "code": "green",
51
+ "result": "blue",
52
+ "planning": "magenta",
53
+ "progress": "white",
54
+ "debug": "blue",
55
+ "user": "green",
56
+ "tool": "yellow",
57
+ })
58
+
59
+ console = Console(theme=custom_theme)
60
+
30
61
  def add_agent(agent_name: str):
31
62
  current_agent.append(agent_name)
32
63
 
33
- def get_current_agent():
34
- return current_agent[-1] if current_agent else "No Agent"
64
+ def get_agent_list():
65
+ return ']['.join(current_agent) if current_agent else "No Agent"
35
66
 
36
67
  def delete_current_agent():
37
68
  current_agent.pop()
@@ -51,25 +82,9 @@ class OutputType(Enum):
51
82
  TOOL = "tool" # Tool call
52
83
 
53
84
  class PrettyOutput:
54
- """美化输出类"""
55
-
56
- # 颜色方案 - 只使用前景色
57
- COLORS = {
58
- OutputType.SYSTEM: Fore.CYAN, # Cyan - AI assistant
59
- OutputType.CODE: Fore.GREEN, # Green - Code
60
- OutputType.RESULT: Fore.BLUE, # Blue - Result
61
- OutputType.ERROR: Fore.RED, # Red - Error
62
- OutputType.INFO: Fore.YELLOW, # Yellow - Prompt
63
- OutputType.PLANNING: Fore.MAGENTA, # Magenta - Planning
64
- OutputType.PROGRESS: Fore.WHITE, # White - Progress
65
- OutputType.SUCCESS: Fore.GREEN, # Green - Success
66
- OutputType.WARNING: Fore.YELLOW, # Yellow - Warning
67
- OutputType.DEBUG: Fore.BLUE, # Blue - Debug
68
- OutputType.USER: Fore.GREEN, # Green - User
69
- OutputType.TOOL: Fore.YELLOW, # Yellow - Tool
70
- }
85
+ """Pretty output using rich"""
71
86
 
72
- # 图标方案
87
+ # Icons for different output types
73
88
  ICONS = {
74
89
  OutputType.SYSTEM: "🤖", # Robot - AI assistant
75
90
  OutputType.CODE: "📝", # Notebook - Code
@@ -84,67 +99,106 @@ class PrettyOutput:
84
99
  OutputType.USER: "👤", # User - User
85
100
  OutputType.TOOL: "🔧", # Wrench - Tool
86
101
  }
87
-
88
- # 前缀方案
89
- PREFIXES = {
90
- OutputType.SYSTEM: "Assistant",
91
- OutputType.CODE: "Code",
92
- OutputType.RESULT: "Result",
93
- OutputType.ERROR: "Error",
94
- OutputType.INFO: "Info",
95
- OutputType.PLANNING: "Plan",
96
- OutputType.PROGRESS: "Progress",
97
- OutputType.SUCCESS: "Success",
98
- OutputType.WARNING: "Warning",
99
- OutputType.DEBUG: "Debug",
100
- OutputType.USER: "User",
101
- OutputType.TOOL: "Tool",
102
+
103
+ # Common language mapping dictionary
104
+ _lang_map = {
105
+ 'Python': 'python',
106
+ 'JavaScript': 'javascript',
107
+ 'TypeScript': 'typescript',
108
+ 'Java': 'java',
109
+ 'C++': 'cpp',
110
+ 'C#': 'csharp',
111
+ 'Ruby': 'ruby',
112
+ 'PHP': 'php',
113
+ 'Go': 'go',
114
+ 'Rust': 'rust',
115
+ 'Bash': 'bash',
116
+ 'HTML': 'html',
117
+ 'CSS': 'css',
118
+ 'SQL': 'sql',
119
+ 'R': 'r',
120
+ 'Kotlin': 'kotlin',
121
+ 'Swift': 'swift',
122
+ 'Scala': 'scala',
123
+ 'Perl': 'perl',
124
+ 'Lua': 'lua',
125
+ 'YAML': 'yaml',
126
+ 'JSON': 'json',
127
+ 'XML': 'xml',
128
+ 'Markdown': 'markdown',
129
+ 'Text': 'text',
130
+ 'Shell': 'bash',
131
+ 'Dockerfile': 'dockerfile',
132
+ 'Makefile': 'makefile',
133
+ 'INI': 'ini',
134
+ 'TOML': 'toml',
102
135
  }
103
136
 
104
137
  @staticmethod
105
- def format(text: str, output_type: OutputType, timestamp: bool = True) -> str:
106
- """Format output text"""
107
- color = PrettyOutput.COLORS.get(output_type, "")
108
- icon = PrettyOutput.ICONS.get(output_type, "")
109
- prefix = PrettyOutput.PREFIXES.get(output_type, "")
110
-
111
- # 添加时间戳 - 使用白色
112
- time_str = f"{Fore.BLUE}[{get_current_agent()}]{ColoramaStyle.RESET_ALL}{Fore.WHITE}[{datetime.now().strftime('%H:%M:%S')}]{ColoramaStyle.RESET_ALL} " if timestamp else ""
138
+ def _detect_language(text: str, default_lang: str = 'markdown') -> str:
139
+ """Helper method to detect language and map it to syntax highlighting name"""
140
+ try:
141
+ lexer = guess_lexer(text)
142
+ detected_lang = lexer.name
143
+ return PrettyOutput._lang_map.get(detected_lang, default_lang)
144
+ except ClassNotFound:
145
+ return default_lang
146
+ except Exception:
147
+ return default_lang
148
+
149
+ @staticmethod
150
+ def format(text: str, output_type: OutputType, timestamp: bool = True) -> Text:
151
+ """Format output text using rich Text"""
152
+ # Create rich Text object
153
+ formatted = Text()
113
154
 
114
- # 格式化输出
115
- formatted_text = f"{time_str}{color}{icon} {prefix}: {text}{ColoramaStyle.RESET_ALL}"
155
+ # Add timestamp and agent info
156
+ if timestamp:
157
+ formatted.append(f"[{datetime.now().strftime('%H:%M:%S')}] ", style="white")
158
+ formatted.append(f"[{get_agent_list()}]", style="blue")
159
+ # Add icon
160
+ icon = PrettyOutput.ICONS.get(output_type, "")
161
+ formatted.append(f"{icon} ", style=output_type.value)
116
162
 
117
- return formatted_text
163
+ return formatted
118
164
 
119
165
  @staticmethod
120
166
  def print(text: str, output_type: OutputType, timestamp: bool = True):
121
- """Print formatted output"""
122
- print(PrettyOutput.format(text, output_type, timestamp))
167
+ """Print formatted output using rich console"""
168
+ # Get formatted header
169
+ lang = PrettyOutput._detect_language(text, default_lang='markdown')
170
+ header = PrettyOutput.format("", output_type, timestamp)
171
+
172
+ content = Syntax(text, lang, theme="monokai")
173
+
174
+ # Print panel with appropriate border style
175
+ border_style = "red" if output_type == OutputType.ERROR else output_type.value
176
+ console.print(Panel(content, border_style=border_style, title=header, title_align="left", highlight=True))
177
+
178
+ # Print stack trace for errors
123
179
  if output_type == OutputType.ERROR:
124
- import traceback
125
- PrettyOutput.print(f"Error trace: {traceback.format_exc()}", OutputType.INFO)
180
+ console.print_exception()
126
181
 
127
182
  @staticmethod
128
183
  def section(title: str, output_type: OutputType = OutputType.INFO):
129
- """Print paragraph title with separator"""
130
- width = 100
131
- color = PrettyOutput.COLORS.get(output_type, "")
132
- print(f"\n{color}" + "=" * width + f"{ColoramaStyle.RESET_ALL}")
133
- PrettyOutput.print(title.center(width - 25), output_type, timestamp=False)
134
- print(f"{color}" + "=" * width + f"{ColoramaStyle.RESET_ALL}\n")
184
+ """Print section title in a panel"""
185
+ panel = Panel(
186
+ Text(title, style=output_type.value, justify="center"),
187
+ border_style=output_type.value
188
+ )
189
+ console.print()
190
+ console.print(panel)
191
+ console.print()
135
192
 
136
193
  @staticmethod
137
194
  def print_stream(text: str):
138
- """Print stream output, no line break"""
139
- color = PrettyOutput.COLORS.get(OutputType.SYSTEM, "")
140
- sys.stdout.write(f"{color}{text}{ColoramaStyle.RESET_ALL}")
141
- sys.stdout.flush()
195
+ """Print stream output without line break"""
196
+ console.print(text, style="system", end="")
142
197
 
143
198
  @staticmethod
144
199
  def print_stream_end():
145
- """Stream output end, print line break"""
146
- sys.stdout.write("\n")
147
- sys.stdout.flush()
200
+ """End stream output with line break"""
201
+ console.print()
148
202
 
149
203
  def get_single_line_input(tip: str) -> str:
150
204
  """Get single line input, support direction key, history function, etc."""
@@ -154,14 +208,87 @@ def get_single_line_input(tip: str) -> str:
154
208
  })
155
209
  return session.prompt(f"{tip}", style=style)
156
210
 
211
+ def make_choice_input(tip: str, choices: list) -> str:
212
+ """Get choice input, support direction key, history function, etc."""
213
+ session = PromptSession(history=None)
214
+ style = PromptStyle.from_dict({
215
+ 'prompt': 'ansicyan',
216
+ })
217
+ return session.prompt(f"{tip}", style=style)
218
+
219
+ class FileCompleter(Completer):
220
+ """Custom completer for file paths with fuzzy matching."""
221
+ def __init__(self):
222
+ self.path_completer = PathCompleter()
223
+
224
+ def get_completions(self, document: Document, complete_event):
225
+ text = document.text_before_cursor
226
+ cursor_pos = document.cursor_position
227
+
228
+ # Find all @ positions in text
229
+ at_positions = [i for i, char in enumerate(text) if char == '@']
230
+
231
+ if not at_positions:
232
+ return
233
+
234
+ # Get the last @ position
235
+ current_at_pos = at_positions[-1]
236
+
237
+ # If cursor is not after the last @, don't complete
238
+ if cursor_pos <= current_at_pos:
239
+ return
240
+
241
+ # Check if there's a space after @
242
+ text_after_at = text[current_at_pos + 1:cursor_pos]
243
+ if ' ' in text_after_at:
244
+ return
245
+
246
+ # Get the text after the current @
247
+ file_path = text_after_at.strip()
248
+
249
+ # Get all possible files from current directory
250
+ all_files = []
251
+ for root, _, files in os.walk('.'):
252
+ for f in files:
253
+ path = os.path.join(root, f)
254
+ # Remove ./ from the beginning
255
+ path = path[2:] if path.startswith('./') else path
256
+ all_files.append(path)
257
+
258
+ # If no input after @, show all files
259
+ # Otherwise use fuzzy matching
260
+ if not file_path:
261
+ scored_files = [(path, 100) for path in all_files]
262
+ else:
263
+ scored_files = [
264
+ (path, fuzz.ratio(file_path.lower(), path.lower()))
265
+ for path in all_files
266
+ ]
267
+ scored_files.sort(key=lambda x: x[1], reverse=True)
268
+
269
+ # Return completions for files
270
+ for path, score in scored_files:
271
+ if not file_path or score > 30: # Show all if no input, otherwise filter by score
272
+ completion = Completion(
273
+ text=path,
274
+ start_position=-len(file_path),
275
+ display=f"{path}" if not file_path else f"{path} ({score}%)",
276
+ display_meta="File"
277
+ )
278
+ yield completion
279
+
157
280
  def get_multiline_input(tip: str) -> str:
158
- """Get multi-line input, support direction key, history function, etc."""
159
- print(f"{Fore.GREEN}{tip}{ColoramaStyle.RESET_ALL}")
281
+ """Get multi-line input, support direction key, history function, and file completion.
160
282
 
161
- # 创建输入会话,启用历史记录
162
- session = PromptSession(history=None) # 使用默认历史记录
283
+ Args:
284
+ tip: The prompt tip to display
285
+
286
+ Returns:
287
+ str: The entered text
288
+ """
289
+ print(f"{Fore.GREEN}{tip}{ColoramaStyle.RESET_ALL}")
163
290
 
164
- # 定义提示符样式
291
+ # Define prompt style
165
292
  style = PromptStyle.from_dict({
166
293
  'prompt': 'ansicyan',
167
294
  })
@@ -169,28 +296,34 @@ def get_multiline_input(tip: str) -> str:
169
296
  lines = []
170
297
  try:
171
298
  while True:
172
- # 设置提示符
299
+ # Set prompt
173
300
  prompt = FormattedText([
174
301
  ('class:prompt', '... ' if lines else '>>> ')
175
302
  ])
176
303
 
177
- # 获取输入
304
+ # Create new session with new completer for each line
305
+ session = PromptSession(
306
+ history=None, # Use default history
307
+ completer=FileCompleter() # New completer instance for each line
308
+ )
309
+
310
+ # Get input with completion support
178
311
  line = session.prompt(
179
312
  prompt,
180
313
  style=style,
181
314
  ).strip()
182
315
 
183
- # 空行处理
316
+ # Handle empty line
184
317
  if not line:
185
- if not lines: # 第一行就输入空行
318
+ if not lines: # First line is empty
186
319
  return ""
187
- break # 结束多行输入
320
+ break # End multi-line input
188
321
 
189
322
  lines.append(line)
190
323
 
191
324
  except KeyboardInterrupt:
192
- PrettyOutput.print("\nInput cancelled", OutputType.INFO)
193
- return "__interrupt__"
325
+ PrettyOutput.print("Input cancelled", OutputType.INFO)
326
+ return ""
194
327
 
195
328
  return "\n".join(lines)
196
329
 
@@ -244,6 +377,13 @@ def find_git_root(dir="."):
244
377
  os.chdir(curr_dir)
245
378
  return ret
246
379
 
380
+ def has_uncommitted_changes():
381
+ # Check working directory changes
382
+ working_changes = os.popen("git diff --exit-code").read().strip() != ""
383
+ # Check staged changes
384
+ staged_changes = os.popen("git diff --cached --exit-code").read().strip() != ""
385
+ return working_changes or staged_changes
386
+
247
387
  def load_embedding_model():
248
388
  model_name = "BAAI/bge-m3"
249
389
  cache_dir = os.path.expanduser("~/.cache/huggingface/hub")
@@ -257,13 +397,11 @@ def load_embedding_model():
257
397
  local_files_only=True
258
398
  )
259
399
  except Exception as e:
260
- PrettyOutput.print(f"Failed to load embedding model: {str(e)}", OutputType.ERROR)
261
- os.system(f'huggingface-cli download --repo-type model --local-dir {cache_dir} {model_name}')
262
400
  # Load model
263
401
  embedding_model = SentenceTransformer(
264
402
  model_name,
265
403
  cache_folder=cache_dir,
266
- local_files_only=True
404
+ local_files_only=False
267
405
  )
268
406
 
269
407
  return embedding_model
@@ -288,18 +426,16 @@ def load_rerank_model():
288
426
  local_files_only=True
289
427
  )
290
428
  except Exception as e:
291
- PrettyOutput.print(f"Failed to load reranking model: {str(e)}", OutputType.ERROR)
292
- os.system(f'huggingface-cli download --repo-type model --local-dir {cache_dir} {model_name}')
293
429
  # Load model and tokenizer
294
430
  tokenizer = AutoTokenizer.from_pretrained(
295
431
  model_name,
296
432
  cache_dir=cache_dir,
297
- local_files_only=True
433
+ local_files_only=False
298
434
  )
299
435
  model = AutoModelForSequenceClassification.from_pretrained(
300
436
  model_name,
301
437
  cache_dir=cache_dir,
302
- local_files_only=True
438
+ local_files_only=False
303
439
  )
304
440
 
305
441
  # Use GPU if available
@@ -339,6 +475,10 @@ def get_file_md5(filepath: str)->str:
339
475
  return hashlib.md5(open(filepath, "rb").read(100*1024*1024)).hexdigest()
340
476
 
341
477
 
478
+ def dont_use_local_model():
479
+ return os.getenv('JARVIS_DONT_USE_LOCAL_MODEL', 'false') == 'true'
480
+
481
+
342
482
  def _create_methodology_embedding(embedding_model: Any, methodology_text: str) -> np.ndarray:
343
483
  """Create embedding vector for methodology text"""
344
484
  try:
@@ -363,11 +503,20 @@ def load_methodology(user_input: str) -> str:
363
503
  user_jarvis_methodology = os.path.expanduser("~/.jarvis/methodology")
364
504
  if not os.path.exists(user_jarvis_methodology):
365
505
  return ""
506
+
507
+ def make_methodology_prompt(data: Dict) -> str:
508
+ ret = """This is the standard methodology for handling previous problems, if the current task is similar, you can refer to it, if not,just ignore it:\n"""
509
+ for key, value in data.items():
510
+ ret += f"Problem: {key}\nMethodology: {value}\n"
511
+ return ret
366
512
 
367
513
  try:
368
514
  with open(user_jarvis_methodology, "r", encoding="utf-8") as f:
369
515
  data = yaml.safe_load(f)
370
516
 
517
+ if dont_use_local_model():
518
+ return make_methodology_prompt(data)
519
+
371
520
  # Reset data structure
372
521
  methodology_data = []
373
522
  vectors = []
@@ -382,7 +531,6 @@ def load_methodology(user_input: str) -> str:
382
531
 
383
532
  # Create embedding vector for each methodology
384
533
  for i, (key, value) in enumerate(data.items()):
385
- PrettyOutput.print(f"Vectorizing methodology: {key} ...", OutputType.INFO)
386
534
  methodology_text = f"{key}\n{value}"
387
535
  embedding = _create_methodology_embedding(embedding_model, methodology_text)
388
536
  vectors.append(embedding)
@@ -398,32 +546,59 @@ def load_methodology(user_input: str) -> str:
398
546
  methodology_index = faiss.IndexIDMap(hnsw_index)
399
547
  methodology_index.add_with_ids(vectors_array, np.array(ids)) # type: ignore
400
548
  query_embedding = _create_methodology_embedding(embedding_model, user_input)
401
- k = min(5, len(methodology_data))
549
+ k = min(3, len(methodology_data))
402
550
  PrettyOutput.print(f"Retrieving methodology...", OutputType.INFO)
403
551
  distances, indices = methodology_index.search(
404
552
  query_embedding.reshape(1, -1), k
405
553
  ) # type: ignore
406
554
 
407
555
  relevant_methodologies = {}
556
+ output_lines = []
408
557
  for dist, idx in zip(distances[0], indices[0]):
409
558
  if idx >= 0:
410
559
  similarity = 1.0 / (1.0 + float(dist))
411
560
  methodology = methodology_data[idx]
412
- PrettyOutput.print(
413
- f"Methodology '{methodology['key']}' similarity: {similarity:.3f}",
414
- OutputType.INFO
561
+ output_lines.append(
562
+ f"Methodology '{methodology['key']}' similarity: {similarity:.3f}"
415
563
  )
416
564
  if similarity >= 0.5:
417
565
  relevant_methodologies[methodology["key"]] = methodology["value"]
566
+
567
+ if output_lines:
568
+ PrettyOutput.print("\n".join(output_lines), OutputType.INFO)
418
569
 
419
570
  if relevant_methodologies:
420
- return f"""This is the standard methodology for handling previous problems, if the current task is similar, you can refer to it:
421
- {relevant_methodologies}
422
- """
423
- return ""
571
+ return make_methodology_prompt(relevant_methodologies)
572
+ return make_methodology_prompt(data)
424
573
 
425
574
  except Exception as e:
426
575
  PrettyOutput.print(f"Error loading methodology: {str(e)}", OutputType.ERROR)
427
576
  import traceback
428
577
  PrettyOutput.print(f"Error trace: {traceback.format_exc()}", OutputType.INFO)
429
- return ""
578
+ return ""
579
+
580
+ def is_auto_complete() -> bool:
581
+ return os.getenv('JARVIS_AUTO_COMPLETE', 'false') == 'true'
582
+
583
+ def is_disable_codebase() -> bool:
584
+ return os.getenv('JARVIS_DISABLE_CODEBASE', 'false') == 'true'
585
+
586
+ def user_confirm(tip: str, default: bool = True) -> bool:
587
+ """Prompt the user for confirmation.
588
+
589
+ Args:
590
+ tip: The message to show to the user
591
+ default: The default response if user hits enter
592
+
593
+ Returns:
594
+ bool: True if user confirmed, False otherwise
595
+ """
596
+ suffix = "[Y/n]" if default else "[y/N]"
597
+ ret = get_single_line_input(f"{tip} {suffix}: ")
598
+ return default if ret == "" else ret.lower() == "y"
599
+
600
+ def get_file_line_count(filename: str) -> int:
601
+ try:
602
+ return len(open(filename, "r", encoding="utf-8").readlines())
603
+ except Exception as e:
604
+ return 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.101
3
+ Version: 0.1.103
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
@@ -45,7 +45,7 @@ Requires-Dist: colorama>=0.4.6
45
45
  Requires-Dist: prompt_toolkit>=3.0.0
46
46
  Requires-Dist: openai>=1.20.0
47
47
  Requires-Dist: playwright>=1.41.1
48
- Requires-Dist: numpy>=1.24.0
48
+ Requires-Dist: numpy>=1.17.4
49
49
  Requires-Dist: faiss-cpu>=1.8.0
50
50
  Requires-Dist: sentence-transformers>=2.2.2
51
51
  Requires-Dist: bs4>=0.0.1
@@ -55,6 +55,10 @@ Requires-Dist: tiktoken>=0.3.0
55
55
  Requires-Dist: tqdm>=4.65.0
56
56
  Requires-Dist: docx>=0.2.4
57
57
  Requires-Dist: yaspin>=2.5.0
58
+ Requires-Dist: rich>=13.3.1
59
+ Requires-Dist: pygments>=2.15.0
60
+ Requires-Dist: fuzzywuzzy>=0.18.0
61
+ Requires-Dist: python-Levenshtein>=0.26.1
58
62
  Provides-Extra: dev
59
63
  Requires-Dist: pytest; extra == "dev"
60
64
  Requires-Dist: black; extra == "dev"
@@ -157,13 +161,13 @@ jarvis
157
161
  ### Codebase Search
158
162
  ```bash
159
163
  # Generate codebase index
160
- jarvis-codebase --generate
164
+ jarvis-codebase generate
161
165
 
162
166
  # Search similar code
163
- jarvis-codebase --search "your search query"
167
+ jarvis-codebase search "your search query"
164
168
 
165
169
  # Ask questions about codebase
166
- jarvis-codebase --ask "your question"
170
+ jarvis-codebase ask "your question"
167
171
  ```
168
172
 
169
173
  ### Document Analysis (RAG)
@@ -0,0 +1,51 @@
1
+ jarvis/__init__.py,sha256=A2vW7Ac_EmnSRhUOBJFq0qUWC2iJ1qwVxHAT5sJhxnk,51
2
+ jarvis/agent.py,sha256=6r5_pv3sumUrUCd2ntWVGg7yp1KTA3JCzz2IKH582k0,20010
3
+ jarvis/utils.py,sha256=FiWpRM0RjSJyDRimhvU2xa5SIUI70rxWq4ItSeMOCfw,20715
4
+ jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ jarvis/jarvis_code_agent/code_agent.py,sha256=8dIiFPZiWOEyIBDWUrqAdtn9g7eFrvvcCGPx5S56Ngc,6757
6
+ jarvis/jarvis_code_agent/file_select.py,sha256=59s_w1E0ihY1RxBZ1kyXNyQVTHjmjO8L9mg2FtjrsyQ,8192
7
+ jarvis/jarvis_code_agent/patch.py,sha256=du06gKWwmKcDPEtZmQJCOZbotNMKVtS-bz-8MYT78b0,4044
8
+ jarvis/jarvis_code_agent/relevant_files.py,sha256=8rL-hfdelJhWSt6MJKaxmQmFXf-WY-O8L18Ntw9dpnE,2686
9
+ jarvis/jarvis_codebase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ jarvis/jarvis_codebase/main.py,sha256=Q_kVOjtL_AgSVkVUUYBNNKqA386GVxpnx0FXj1omUOc,36739
11
+ jarvis/jarvis_platform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ jarvis/jarvis_platform/main.py,sha256=waLMHQmdecph_mZuPXWjpkmqibJFYHnCHroL9gL0nh0,4959
13
+ jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ jarvis/jarvis_rag/main.py,sha256=4St9VkaqK9zOq7AgurLB02nEj1_SvZAiFWhS3i_FcBY,33167
15
+ jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ jarvis/jarvis_smart_shell/main.py,sha256=yWsD9Td81sr8I1pkimlDxucDPaLWb95NuCo4LCGnT7M,3947
17
+ jarvis/models/__init__.py,sha256=mrOt67nselz_H1gX9wdAO4y2DY5WPXzABqJbr5Des8k,63
18
+ jarvis/models/ai8.py,sha256=QwpcdvOAixFC4BOI2AsWC9290WqcrLj6lQOiT0A3Id4,11994
19
+ jarvis/models/base.py,sha256=nQ-rsJL1Z-gMev3TPoY7tYdwxhCJY8LG6_gtJ-maiW0,2181
20
+ jarvis/models/kimi.py,sha256=2x60DVjX0ph2fJjKj_NICeb0q4qVBihuc_laCpH94eo,15759
21
+ jarvis/models/ollama.py,sha256=WiUYkstaqFjiawXfuJs2GQUa3l3Y2ZWqhnKDBcF7rUQ,5672
22
+ jarvis/models/openai.py,sha256=SAbVIvFO4q6bRl8zlDaH5bKbrP0T_zd1WzlbkPCvkwg,4121
23
+ jarvis/models/oyi.py,sha256=nNBe-A0cOZ6vuGrnrUjeuC3N3oYRQeFazTUpFrAmx2w,15080
24
+ jarvis/models/registry.py,sha256=nDYyGzT2uGSxbEbqp1JhuXa7bXeiMaX4hPAFAg74eyA,8683
25
+ jarvis/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ jarvis/tools/ask_codebase.py,sha256=cYMQd2Ba0Ka_Kpt9dAJrbcPhaXvfY_-A8S6i0UxtY3w,2975
27
+ jarvis/tools/ask_user.py,sha256=k0PcMqvCkf_W9kMWnFsgcFefVf1A5DhpM6WVXFMdhdQ,1823
28
+ jarvis/tools/base.py,sha256=c0DMoDDPxmsqUYJR989zgUs7nIYRY6GWBrAdusIZKjc,656
29
+ jarvis/tools/chdir.py,sha256=3aGvpvWO6Fj9RdjWXanjeNBDZ7kz3TO8_Zo8DurENDk,2934
30
+ jarvis/tools/code_review.py,sha256=Reck765EIfhx8mteaJPw9IRnBkEzGS8INcQ0vVoKUw8,4939
31
+ jarvis/tools/create_code_sub_agent.py,sha256=_G2HUWyik5FFCV1JU8JqF_mutcW6n6WWCvkhb5LGrL0,765
32
+ jarvis/tools/create_code_test_agent.py,sha256=SqdIpymoDUX7L6hh5vqnZLyeVwW-QmLfytU-xkG7Gag,3462
33
+ jarvis/tools/create_ctags_agent.py,sha256=P-vqqUxh33R6kuMy8b5s3bANh1cVmkHpvz0vV5DNbXE,5184
34
+ jarvis/tools/create_sub_agent.py,sha256=0lZDtYRFjr9C9xtBKV-sxWfhK0TX-cxAHj3Zez76A4s,2853
35
+ jarvis/tools/execute_shell.py,sha256=bawfof8bUg3f9bjyCSifLa9bU-hkNoNOuos22uZffdg,2564
36
+ jarvis/tools/file_operation.py,sha256=-1U_J5SEuBjRylzEl7wvCfjspNv6aA49UvFHLNQ3bJU,4098
37
+ jarvis/tools/find_in_codebase.py,sha256=u-T6mEWv6JyE74fYZBjVlxXsqUnkf0BtgwVUy-SX4XI,3321
38
+ jarvis/tools/git_commiter.py,sha256=BcapUhKymAV5Ofi-Cjg4nvYiAj4u5yBaOfsIr0iEp0c,2536
39
+ jarvis/tools/methodology.py,sha256=yZldtjPZpNq8eGJ6IbhwHB0v3cFUtfPd14r7LDCo5IU,5622
40
+ jarvis/tools/rag.py,sha256=m8s-7dCPFhUrdTHvKj3HulNSsoOssBN7kqqn9n1l3Zw,4943
41
+ jarvis/tools/read_code.py,sha256=_ObjMWirIYOdZi-D9KSRTd_4tg-5WwKLOn5ilrTF77I,4834
42
+ jarvis/tools/read_webpage.py,sha256=JCReSXhkDHDkQ606sZYIKG1Itlprjpmu1sSbF-Ed-jI,2478
43
+ jarvis/tools/registry.py,sha256=81Q_x9BJV6SIfPWURq4uzXxP2JCiFeaGbGM1IO5FSy4,11658
44
+ jarvis/tools/search.py,sha256=IciWpdKoa03Kl5J1SdblI2VhkUBoIRuLHHM2X4KlMWE,9209
45
+ jarvis/tools/select_code_files.py,sha256=bjJGwCNw0Ue_8jW60K1gcy1rUgKqoHihicu5SS58WNk,1890
46
+ jarvis_ai_assistant-0.1.103.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
47
+ jarvis_ai_assistant-0.1.103.dist-info/METADATA,sha256=Tr5iXpTFgFd9Z-iSNzIi1B0nB4HA6NfY2l5k4QRKgs8,12913
48
+ jarvis_ai_assistant-0.1.103.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
49
+ jarvis_ai_assistant-0.1.103.dist-info/entry_points.txt,sha256=jHc8XiYoVNlzKcvV5mA-uYvlDRUTO_74_glpb5vvvUg,494
50
+ jarvis_ai_assistant-0.1.103.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
51
+ jarvis_ai_assistant-0.1.103.dist-info/RECORD,,
@@ -1,8 +1,10 @@
1
1
  [console_scripts]
2
2
  jarvis = jarvis.agent:main
3
- jarvis-code-agent = jarvis.jarvis_code_agent.main:main
3
+ jarvis-code-agent = jarvis.jarvis_code_agent.code_agent:main
4
4
  jarvis-codebase = jarvis.jarvis_codebase.main:main
5
- jarvis-coder = jarvis.jarvis_coder.main:main
5
+ jarvis-ctags = jarvis.tools.create_ctags_agent:main
6
+ jarvis-gh = jarvis.jarvis_github.main:main
7
+ jarvis-git-commit = jarvis.tools.git_commiter:main
6
8
  jarvis-platform = jarvis.jarvis_platform.main:main
7
9
  jarvis-rag = jarvis.jarvis_rag.main:main
8
10
  jarvis-smart-shell = jarvis.jarvis_smart_shell.main:main