jarvis-ai-assistant 0.1.97__py3-none-any.whl → 0.1.99__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 (41) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +199 -157
  3. jarvis/jarvis_code_agent/__init__.py +0 -0
  4. jarvis/jarvis_code_agent/main.py +203 -0
  5. jarvis/jarvis_codebase/main.py +412 -284
  6. jarvis/jarvis_coder/file_select.py +209 -0
  7. jarvis/jarvis_coder/git_utils.py +81 -19
  8. jarvis/jarvis_coder/main.py +68 -446
  9. jarvis/jarvis_coder/patch_handler.py +117 -47
  10. jarvis/jarvis_coder/plan_generator.py +69 -27
  11. jarvis/jarvis_platform/main.py +38 -38
  12. jarvis/jarvis_rag/main.py +189 -189
  13. jarvis/jarvis_smart_shell/main.py +22 -24
  14. jarvis/models/base.py +6 -1
  15. jarvis/models/ollama.py +2 -2
  16. jarvis/models/registry.py +3 -6
  17. jarvis/tools/ask_user.py +6 -6
  18. jarvis/tools/codebase_qa.py +5 -7
  19. jarvis/tools/create_code_sub_agent.py +55 -0
  20. jarvis/tools/{sub_agent.py → create_sub_agent.py} +4 -1
  21. jarvis/tools/execute_code_modification.py +72 -0
  22. jarvis/tools/{file_ops.py → file_operation.py} +13 -14
  23. jarvis/tools/find_related_files.py +86 -0
  24. jarvis/tools/methodology.py +25 -25
  25. jarvis/tools/rag.py +32 -32
  26. jarvis/tools/registry.py +72 -36
  27. jarvis/tools/search.py +1 -1
  28. jarvis/tools/select_code_files.py +64 -0
  29. jarvis/utils.py +153 -49
  30. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/METADATA +1 -1
  31. jarvis_ai_assistant-0.1.99.dist-info/RECORD +52 -0
  32. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/entry_points.txt +2 -1
  33. jarvis/main.py +0 -155
  34. jarvis/tools/coder.py +0 -69
  35. jarvis_ai_assistant-0.1.97.dist-info/RECORD +0 -47
  36. /jarvis/tools/{shell.py → execute_shell.py} +0 -0
  37. /jarvis/tools/{generator.py → generate_tool.py} +0 -0
  38. /jarvis/tools/{webpage.py → read_webpage.py} +0 -0
  39. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/LICENSE +0 -0
  40. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/WHEEL +0 -0
  41. {jarvis_ai_assistant-0.1.97.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/top_level.txt +0 -0
jarvis/utils.py CHANGED
@@ -6,20 +6,35 @@ import time
6
6
  import os
7
7
  from enum import Enum
8
8
  from datetime import datetime
9
+ from typing import Any, Dict
9
10
  import colorama
10
11
  from colorama import Fore, Style as ColoramaStyle
12
+ import numpy as np
11
13
  from prompt_toolkit import PromptSession
12
14
  from prompt_toolkit.styles import Style as PromptStyle
13
15
  from prompt_toolkit.formatted_text import FormattedText
14
16
  from sentence_transformers import SentenceTransformer
15
17
  from transformers import AutoModelForSequenceClassification, AutoTokenizer
16
18
  import torch
19
+ import yaml
20
+ import faiss
17
21
 
18
22
  # 初始化colorama
19
23
  colorama.init()
20
24
 
21
- os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
22
25
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
26
+ os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
27
+
28
+ current_agent = []
29
+
30
+ def add_agent(agent_name: str):
31
+ current_agent.append(agent_name)
32
+
33
+ def get_current_agent():
34
+ return current_agent[-1] if current_agent else "No Agent"
35
+
36
+ def delete_current_agent():
37
+ current_agent.pop()
23
38
 
24
39
  class OutputType(Enum):
25
40
  SYSTEM = "system" # AI assistant message
@@ -94,7 +109,7 @@ class PrettyOutput:
94
109
  prefix = PrettyOutput.PREFIXES.get(output_type, "")
95
110
 
96
111
  # 添加时间戳 - 使用白色
97
- time_str = f"{Fore.WHITE}[{datetime.now().strftime('%H:%M:%S')}]{ColoramaStyle.RESET_ALL} " if timestamp else ""
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 ""
98
113
 
99
114
  # 格式化输出
100
115
  formatted_text = f"{time_str}{color}{icon} {prefix}: {text}{ColoramaStyle.RESET_ALL}"
@@ -112,10 +127,10 @@ class PrettyOutput:
112
127
  @staticmethod
113
128
  def section(title: str, output_type: OutputType = OutputType.INFO):
114
129
  """Print paragraph title with separator"""
115
- width = 60
130
+ width = 100
116
131
  color = PrettyOutput.COLORS.get(output_type, "")
117
132
  print(f"\n{color}" + "=" * width + f"{ColoramaStyle.RESET_ALL}")
118
- PrettyOutput.print(title.center(width - 10), output_type, timestamp=True)
133
+ PrettyOutput.print(title.center(width - 25), output_type, timestamp=False)
119
134
  print(f"{color}" + "=" * width + f"{ColoramaStyle.RESET_ALL}\n")
120
135
 
121
136
  @staticmethod
@@ -131,6 +146,14 @@ class PrettyOutput:
131
146
  sys.stdout.write("\n")
132
147
  sys.stdout.flush()
133
148
 
149
+ def get_single_line_input(tip: str) -> str:
150
+ """Get single line input, support direction key, history function, etc."""
151
+ session = PromptSession(history=None)
152
+ style = PromptStyle.from_dict({
153
+ 'prompt': 'ansicyan',
154
+ })
155
+ return session.prompt(f"{tip}", style=style)
156
+
134
157
  def get_multiline_input(tip: str) -> str:
135
158
  """Get multi-line input, support direction key, history function, etc."""
136
159
  print(f"{Fore.GREEN}{tip}{ColoramaStyle.RESET_ALL}")
@@ -217,59 +240,50 @@ def find_git_root(dir="."):
217
240
  return ret
218
241
 
219
242
  def load_embedding_model():
220
- model_name = "BAAI/bge-large-zh-v1.5"
221
- PrettyOutput.print(f"Loading embedding model: {model_name}...", OutputType.INFO)
222
- try:
223
- # 首先尝试离线加载
224
- embedding_model = SentenceTransformer(
225
- model_name,
226
- cache_folder=os.path.expanduser("~/.cache/huggingface/hub"),
227
- local_files_only=True
228
- )
229
- PrettyOutput.print("Successfully loaded model using local cache", OutputType.SUCCESS)
230
- except Exception as local_error:
231
- PrettyOutput.print(f"Failed to load locally, trying to download online: {str(local_error)}", OutputType.WARNING)
232
- # 如果离线加载失败,尝试在线下载
233
- embedding_model = SentenceTransformer(
234
- model_name,
235
- cache_folder=os.path.expanduser("~/.cache/huggingface/hub")
236
- )
237
- PrettyOutput.print("Successfully downloaded and loaded model", OutputType.SUCCESS)
243
+ model_name = "BAAI/bge-m3"
244
+ cache_dir = os.path.expanduser("~/.cache/huggingface/hub")
245
+ model_dir = os.path.join(cache_dir, "models--" + model_name.replace("/", "--"))
246
+
247
+ # Check if model exists
248
+ if not os.path.exists(model_dir):
249
+ PrettyOutput.print("Model not found locally, downloading using huggingface-cli...", OutputType.INFO)
250
+ os.system(f'huggingface-cli download --repo-type model --local-dir {cache_dir} {model_name}' + f' --token {os.getenv("HF_TOKEN")}' if os.getenv("HF_TOKEN") else "")
251
+
252
+ # Load model
253
+ embedding_model = SentenceTransformer(
254
+ model_name,
255
+ cache_folder=cache_dir,
256
+ local_files_only=True
257
+ )
238
258
 
239
259
  return embedding_model
240
260
 
241
261
  def load_rerank_model():
242
262
  """Load reranking model"""
243
263
  model_name = "BAAI/bge-reranker-v2-m3"
264
+ cache_dir = os.path.expanduser("~/.cache/huggingface/hub")
265
+ model_dir = os.path.join(cache_dir, "models--" + model_name.replace("/", "--"))
266
+
244
267
  PrettyOutput.print(f"Loading reranking model: {model_name}...", OutputType.INFO)
245
268
 
246
- try:
247
- # 首先尝试离线加载
248
- tokenizer = AutoTokenizer.from_pretrained(
249
- model_name,
250
- local_files_only=True,
251
- cache_dir=os.path.expanduser("~/.cache/huggingface/hub")
252
- )
253
- model = AutoModelForSequenceClassification.from_pretrained(
254
- model_name,
255
- local_files_only=True,
256
- cache_dir=os.path.expanduser("~/.cache/huggingface/hub")
257
- )
258
- PrettyOutput.print("Successfully loaded model using local cache", OutputType.SUCCESS)
259
- except Exception as local_error:
260
- PrettyOutput.print(f"Failed to load locally, trying to download online: {str(local_error)}", OutputType.WARNING)
261
- # 如果离线加载失败,尝试在线下载
262
- tokenizer = AutoTokenizer.from_pretrained(
263
- model_name,
264
- cache_dir=os.path.expanduser("~/.cache/huggingface/hub")
265
- )
266
- model = AutoModelForSequenceClassification.from_pretrained(
267
- model_name,
268
- cache_dir=os.path.expanduser("~/.cache/huggingface/hub")
269
- )
270
- PrettyOutput.print("Successfully downloaded and loaded model", OutputType.SUCCESS)
269
+ # Check if model exists
270
+ if not os.path.exists(model_dir):
271
+ PrettyOutput.print("Model not found locally, downloading using huggingface-cli...", OutputType.INFO)
272
+ os.system(f'huggingface-cli download --repo-type model --local-dir {cache_dir} {model_name}' + f' --token {os.getenv("HF_TOKEN")}' if os.getenv("HF_TOKEN") else "")
273
+
274
+ # Load model and tokenizer
275
+ tokenizer = AutoTokenizer.from_pretrained(
276
+ model_name,
277
+ cache_dir=cache_dir,
278
+ local_files_only=True
279
+ )
280
+ model = AutoModelForSequenceClassification.from_pretrained(
281
+ model_name,
282
+ cache_dir=cache_dir,
283
+ local_files_only=True
284
+ )
271
285
 
272
- # 如果有 GPU 就使用 GPU
286
+ # Use GPU if available
273
287
  if torch.cuda.is_available():
274
288
  model = model.cuda()
275
289
  model.eval()
@@ -303,4 +317,94 @@ def get_thread_count():
303
317
  return int(os.getenv('JARVIS_THREAD_COUNT', '1'))
304
318
 
305
319
  def get_file_md5(filepath: str)->str:
306
- return hashlib.md5(open(filepath, "rb").read(100*1024*1024)).hexdigest()
320
+ return hashlib.md5(open(filepath, "rb").read(100*1024*1024)).hexdigest()
321
+
322
+
323
+ def _create_methodology_embedding(embedding_model: Any, methodology_text: str) -> np.ndarray:
324
+ """Create embedding vector for methodology text"""
325
+ try:
326
+ # Truncate long text
327
+ max_length = 512
328
+ text = ' '.join(methodology_text.split()[:max_length])
329
+
330
+ # 使用sentence_transformers模型获取嵌入向量
331
+ embedding = embedding_model.encode([text],
332
+ convert_to_tensor=True,
333
+ normalize_embeddings=True)
334
+ vector = np.array(embedding.cpu().numpy(), dtype=np.float32)
335
+ return vector[0] # Return first vector, because we only encoded one text
336
+ except Exception as e:
337
+ PrettyOutput.print(f"Failed to create methodology embedding vector: {str(e)}", OutputType.ERROR)
338
+ return np.zeros(1536, dtype=np.float32)
339
+
340
+
341
+ def load_methodology(user_input: str) -> str:
342
+ """Load methodology and build vector index"""
343
+ PrettyOutput.print("Loading methodology...", OutputType.PROGRESS)
344
+ user_jarvis_methodology = os.path.expanduser("~/.jarvis_methodology")
345
+ if not os.path.exists(user_jarvis_methodology):
346
+ return ""
347
+
348
+ try:
349
+ with open(user_jarvis_methodology, "r", encoding="utf-8") as f:
350
+ data = yaml.safe_load(f)
351
+
352
+ # Reset data structure
353
+ methodology_data = []
354
+ vectors = []
355
+ ids = []
356
+
357
+ # Get embedding model
358
+ embedding_model = load_embedding_model()
359
+
360
+ # Create test embedding to get correct dimension
361
+ test_embedding = _create_methodology_embedding(embedding_model, "test")
362
+ embedding_dimension = len(test_embedding)
363
+
364
+ # Create embedding vector for each methodology
365
+ for i, (key, value) in enumerate(data.items()):
366
+ PrettyOutput.print(f"Vectorizing methodology: {key} ...", OutputType.INFO)
367
+ methodology_text = f"{key}\n{value}"
368
+ embedding = _create_methodology_embedding(embedding_model, methodology_text)
369
+ vectors.append(embedding)
370
+ ids.append(i)
371
+ methodology_data.append({"key": key, "value": value})
372
+
373
+ if vectors:
374
+ vectors_array = np.vstack(vectors)
375
+ # Use correct dimension from test embedding
376
+ hnsw_index = faiss.IndexHNSWFlat(embedding_dimension, 16)
377
+ hnsw_index.hnsw.efConstruction = 40
378
+ hnsw_index.hnsw.efSearch = 16
379
+ methodology_index = faiss.IndexIDMap(hnsw_index)
380
+ methodology_index.add_with_ids(vectors_array, np.array(ids)) # type: ignore
381
+ query_embedding = _create_methodology_embedding(embedding_model, user_input)
382
+ k = min(5, len(methodology_data))
383
+ PrettyOutput.print(f"Retrieving methodology...", OutputType.INFO)
384
+ distances, indices = methodology_index.search(
385
+ query_embedding.reshape(1, -1), k
386
+ ) # type: ignore
387
+
388
+ relevant_methodologies = {}
389
+ for dist, idx in zip(distances[0], indices[0]):
390
+ if idx >= 0:
391
+ similarity = 1.0 / (1.0 + float(dist))
392
+ methodology = methodology_data[idx]
393
+ PrettyOutput.print(
394
+ f"Methodology '{methodology['key']}' similarity: {similarity:.3f}",
395
+ OutputType.INFO
396
+ )
397
+ if similarity >= 0.5:
398
+ relevant_methodologies[methodology["key"]] = methodology["value"]
399
+
400
+ if relevant_methodologies:
401
+ return f"""This is the standard methodology for handling previous problems, if the current task is similar, you can refer to it:
402
+ {relevant_methodologies}
403
+ """
404
+ return ""
405
+
406
+ except Exception as e:
407
+ PrettyOutput.print(f"Error loading methodology: {str(e)}", OutputType.ERROR)
408
+ import traceback
409
+ PrettyOutput.print(f"Error trace: {traceback.format_exc()}", OutputType.INFO)
410
+ return ""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.97
3
+ Version: 0.1.99
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,52 @@
1
+ jarvis/__init__.py,sha256=U2J1Jkr2YHJwfc3OfDOe-JfIpiajjVBplRfsmc4xL8U,50
2
+ jarvis/agent.py,sha256=EwufsNRQPYLnQ5HsZkjsw9-tOtc3GCn9h73kuZoNg3k,20780
3
+ jarvis/utils.py,sha256=WtIZrwed5q0KvDWTxS6Y4K_m9svZROvOxyehJ7u1OSc,15495
4
+ jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ jarvis/jarvis_code_agent/main.py,sha256=7mCwsvBDtnI-VohCy1ng6jEpSQL9G5Xztml11PgjRvs,6307
6
+ jarvis/jarvis_codebase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ jarvis/jarvis_codebase/main.py,sha256=lvIWXmdl16WHVhroSFFxr00uHnpv5e9dEDOjz9ibH9A,36874
8
+ jarvis/jarvis_coder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ jarvis/jarvis_coder/file_select.py,sha256=BobNj5Kirr6jSwy59LOghC3o8Uff1CwTXNtlTO-idEo,8475
10
+ jarvis/jarvis_coder/git_utils.py,sha256=0xKgUzfKy8Pk4wEIBmTggPpRafiHWtPD1SfZOapZnj8,5029
11
+ jarvis/jarvis_coder/main.py,sha256=b8p-FrQe23bM2_H3sY3A3Y6J332DM6ojSi6yoi_K77E,8879
12
+ jarvis/jarvis_coder/patch_handler.py,sha256=pMKgwHOc7U0rFKj3-MZNlshzq_im4kZw4QV2yrvUr-s,13061
13
+ jarvis/jarvis_coder/plan_generator.py,sha256=x-FalwoRg79h-fvDgFQ8Cl-I8zJ7x2qcXsEUnRip9GA,6186
14
+ jarvis/jarvis_platform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ jarvis/jarvis_platform/main.py,sha256=Hb40MmN4We9oY8BHzLyrNTm-p7Mg50s2nqLaLxflC48,4981
16
+ jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ jarvis/jarvis_rag/main.py,sha256=qi_JokG5ZZOFZ7R1V8aoIjst_knGyA1-lwJcRVvBX6A,33625
18
+ jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ jarvis/jarvis_smart_shell/main.py,sha256=pAtNXLDAubNRLXAVz5oDw0BVI4juk9PX4Jbuyl7omQQ,4014
20
+ jarvis/models/__init__.py,sha256=mrOt67nselz_H1gX9wdAO4y2DY5WPXzABqJbr5Des8k,63
21
+ jarvis/models/ai8.py,sha256=ZRNO3aRjmICRjCXl-_F9pTNQTY4j1tUd-WJoJpb9n4Y,11958
22
+ jarvis/models/base.py,sha256=nQ-rsJL1Z-gMev3TPoY7tYdwxhCJY8LG6_gtJ-maiW0,2181
23
+ jarvis/models/kimi.py,sha256=wLXEA-17yLVvMRn-SAMGwQ_gx6mBaGhlSsP8F5pfoL0,16391
24
+ jarvis/models/ollama.py,sha256=LzEA4kbkw1KflQ1T__hkmXu4--6xUPho2NTnj_ZQe6k,5761
25
+ jarvis/models/openai.py,sha256=tAvz2Pne7woDXUppD7Ina461mVQCxy0vG5cwv5MHpLg,4404
26
+ jarvis/models/oyi.py,sha256=iA8E5vzN9VIt-rlzpT5wmbyl7umVU1_y5yo_5gz3DXc,14534
27
+ jarvis/models/registry.py,sha256=5z75vdBoudH2oJRESHzV3SOFX0JZaefpcWsrUNpmaJM,8814
28
+ jarvis/tools/__init__.py,sha256=7Rqyj5hBAv5cWDVr5T9ZTZASO7ssBHeQNm2_4ZARdkA,72
29
+ jarvis/tools/ask_user.py,sha256=2hEaR-L7pjYLVXFC5-zAu2us7B7OHTLvwssfKX2i3co,2006
30
+ jarvis/tools/base.py,sha256=c0DMoDDPxmsqUYJR989zgUs7nIYRY6GWBrAdusIZKjc,656
31
+ jarvis/tools/chdir.py,sha256=YMrzj6V3JHxX94e8adz97x1_E5aWjUoEwkhDM4T2DEs,2793
32
+ jarvis/tools/codebase_qa.py,sha256=CpxL2RtPcdkrtaoKO5rU6YhWoZ6WdmGrD6P3pYDSkbA,2364
33
+ jarvis/tools/create_code_sub_agent.py,sha256=aWxeF-4PM_bKS9TYk3iqQOZbMRnG6E469XdRGHG0dNw,1687
34
+ jarvis/tools/create_sub_agent.py,sha256=4Uim7UGgStw7nhVz9i1S_nzSC__jUwxpCh80ZsLT2TA,2776
35
+ jarvis/tools/execute_code_modification.py,sha256=yRBoayavmnUCP1GKgiOI2NjZK3HMcufZ_ed4L9ecvKE,2572
36
+ jarvis/tools/execute_shell.py,sha256=6XIDzdTf67PDIObUZqLtHvhnlOLSyuV_GlfFwQJsSaU,2580
37
+ jarvis/tools/file_operation.py,sha256=e37kkZKop75hUMh9MJjYNz2MbLir6J5iDFiXA_VzVWg,3899
38
+ jarvis/tools/find_related_files.py,sha256=Q7O1qkNK1i7rGXrQjyJk2QIPPQNYUPFTHJTEbysntyw,3242
39
+ jarvis/tools/generate_tool.py,sha256=5iw8-uLwMcwSzQ2DouoWYa4WYm_7ZmYfdJBU50z9SUE,6040
40
+ jarvis/tools/methodology.py,sha256=wzkVbxetg_rvK_wDqPvgVQ9yeCwSkwEoQ5EsN0uB7G8,5377
41
+ jarvis/tools/rag.py,sha256=gzut7Yk6vhYeT94GFBE6YMwTj5tvKEzlU9McY6fOdK8,4742
42
+ jarvis/tools/read_webpage.py,sha256=_ts9ioSFR2wcMwjId_aV-jqSWpbiydU_beJQyn_aAv4,2405
43
+ jarvis/tools/registry.py,sha256=-JSgZ-6Tp0xmADRLiX-lrlh14uob_TCe0r3gN0mpGyo,10583
44
+ jarvis/tools/search.py,sha256=BIcp92A2iP0lj3EOh7RoIK2KsWIpd53txeM9x3IA8kg,9080
45
+ jarvis/tools/select_code_files.py,sha256=lHX93It0FjAonzIhpg5CO27Zx9O8v_zDoW3040qQsUA,2107
46
+ jarvis/tools/thinker.py,sha256=VFq0z9geAtGsRCbd8S73Rk7afAuGm3KQp6t5nayUJVg,4800
47
+ jarvis_ai_assistant-0.1.99.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
48
+ jarvis_ai_assistant-0.1.99.dist-info/METADATA,sha256=o8sh7rX00sPwv35yMUB-hq5iSxB9nY8sfHj-i1cgBxM,12766
49
+ jarvis_ai_assistant-0.1.99.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
50
+ jarvis_ai_assistant-0.1.99.dist-info/entry_points.txt,sha256=x0jA_mYRc7hBVdLuOFQBYQjpXjf8NPrAn0C54DJ9t2I,387
51
+ jarvis_ai_assistant-0.1.99.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
52
+ jarvis_ai_assistant-0.1.99.dist-info/RECORD,,
@@ -1,5 +1,6 @@
1
1
  [console_scripts]
2
- jarvis = jarvis.main:main
2
+ jarvis = jarvis.agent:main
3
+ jarvis-code-agent = jarvis.jarvis_code_agent.main:main
3
4
  jarvis-codebase = jarvis.jarvis_codebase.main:main
4
5
  jarvis-coder = jarvis.jarvis_coder.main:main
5
6
  jarvis-platform = jarvis.jarvis_platform.main:main
jarvis/main.py DELETED
@@ -1,155 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Command line interface for Jarvis."""
3
-
4
- import argparse
5
- import yaml
6
- import os
7
- import sys
8
- from pathlib import Path
9
- from prompt_toolkit import prompt
10
-
11
- from jarvis.models.registry import PlatformRegistry
12
-
13
- # Add parent directory to Python path to support imports
14
- sys.path.insert(0, str(Path(__file__).parent.parent))
15
-
16
- from jarvis.agent import Agent
17
- from jarvis.tools import ToolRegistry
18
- from jarvis.utils import PrettyOutput, OutputType, get_multiline_input, load_env_from_file
19
-
20
-
21
- def load_tasks() -> dict:
22
- """Load tasks from .jarvis files in user home and current directory."""
23
- tasks = {}
24
-
25
- # Check .jarvis in user directory
26
- user_jarvis = os.path.expanduser("~/.jarvis")
27
- if os.path.exists(user_jarvis):
28
- try:
29
- with open(user_jarvis, "r", encoding="utf-8") as f:
30
- user_tasks = yaml.safe_load(f)
31
-
32
- if isinstance(user_tasks, dict):
33
- # Validate and add user directory tasks
34
- for name, desc in user_tasks.items():
35
- if desc: # Ensure description is not empty
36
- tasks[str(name)] = str(desc)
37
- else:
38
- PrettyOutput.print("Warning: ~/.jarvis file should contain a dictionary of task_name: task_description", OutputType.ERROR)
39
- except Exception as e:
40
- PrettyOutput.print(f"Error loading ~/.jarvis file: {str(e)}", OutputType.ERROR)
41
-
42
- # Check .jarvis in current directory
43
- if os.path.exists(".jarvis"):
44
- try:
45
- with open(".jarvis", "r", encoding="utf-8") as f:
46
- local_tasks = yaml.safe_load(f)
47
-
48
- if isinstance(local_tasks, dict):
49
- # Validate and add current directory tasks, overwrite user directory tasks if there is a name conflict
50
- for name, desc in local_tasks.items():
51
- if desc: # Ensure description is not empty
52
- tasks[str(name)] = str(desc)
53
- else:
54
- PrettyOutput.print("Warning: .jarvis file should contain a dictionary of task_name: task_description", OutputType.ERROR)
55
- except Exception as e:
56
- PrettyOutput.print(f"Error loading .jarvis file: {str(e)}", OutputType.ERROR)
57
-
58
- # Read methodology
59
- method_path = os.path.expanduser("~/.jarvis_methodology")
60
- if os.path.exists(method_path):
61
- with open(method_path, "r", encoding="utf-8") as f:
62
- methodology = yaml.safe_load(f)
63
- if isinstance(methodology, dict):
64
- for name, desc in methodology.items():
65
- tasks[f"Run Methodology: {str(name)}\n {str(desc)}" ] = str(desc)
66
-
67
- return tasks
68
-
69
- def select_task(tasks: dict) -> str:
70
- """Let user select a task from the list or skip. Returns task description if selected."""
71
- if not tasks:
72
- return ""
73
-
74
- # Convert tasks to list for ordered display
75
- task_names = list(tasks.keys())
76
-
77
- PrettyOutput.print("\nAvailable tasks:", OutputType.INFO)
78
- for i, name in enumerate(task_names, 1):
79
- PrettyOutput.print(f"[{i}] {name}", OutputType.INFO)
80
- PrettyOutput.print("[0] Skip predefined tasks", OutputType.INFO)
81
-
82
-
83
- while True:
84
- try:
85
- choice = prompt(
86
- "\nPlease select a task number (0 to skip): ",
87
- ).strip()
88
-
89
- if not choice:
90
- return ""
91
-
92
- choice = int(choice)
93
- if choice == 0:
94
- return ""
95
- elif 1 <= choice <= len(task_names):
96
- selected_name = task_names[choice - 1]
97
- return tasks[selected_name] # Return the task description
98
- else:
99
- PrettyOutput.print("Invalid choice. Please select a number from the list.", OutputType.ERROR)
100
-
101
- except KeyboardInterrupt:
102
- return "" # Return empty on Ctrl+C
103
- except EOFError:
104
- return "" # Return empty on Ctrl+D
105
- except Exception as e:
106
- PrettyOutput.print(f"Failed to select task: {str(e)}", OutputType.ERROR)
107
- continue
108
-
109
- def main():
110
- """Jarvis main entry point"""
111
- # Add argument parser
112
- load_env_from_file()
113
- parser = argparse.ArgumentParser(description='Jarvis AI assistant')
114
- parser.add_argument('-f', '--files', nargs='*', help='List of files to process')
115
- parser.add_argument('--keep-history', action='store_true', help='Keep chat history (do not delete session)')
116
- args = parser.parse_args()
117
-
118
- try:
119
- # 获取全局模型实例
120
- agent = Agent()
121
-
122
- # 如果用户传入了模型参数,则更换当前模型为用户指定的模型
123
-
124
- # Welcome information
125
- PrettyOutput.print(f"Jarvis initialized - With {agent.model.name()}", OutputType.SYSTEM)
126
- if args.keep_history:
127
- PrettyOutput.print("History preservation mode enabled", OutputType.INFO)
128
-
129
- # 加载预定义任务
130
- tasks = load_tasks()
131
- if tasks:
132
- selected_task = select_task(tasks)
133
- if selected_task:
134
- PrettyOutput.print(f"\nExecute task: {selected_task}", OutputType.INFO)
135
- agent.run(selected_task, args.files)
136
- return 0
137
-
138
- # 如果没有选择预定义任务,进入交互模式
139
- while True:
140
- try:
141
- user_input = get_multiline_input("Please enter your task (input empty line to exit):")
142
- if not user_input or user_input == "__interrupt__":
143
- break
144
- agent.run(user_input, args.files)
145
- except Exception as e:
146
- PrettyOutput.print(f"Error: {str(e)}", OutputType.ERROR)
147
-
148
- except Exception as e:
149
- PrettyOutput.print(f"Initialization error: {str(e)}", OutputType.ERROR)
150
- return 1
151
-
152
- return 0
153
-
154
- if __name__ == "__main__":
155
- exit(main())
jarvis/tools/coder.py DELETED
@@ -1,69 +0,0 @@
1
- import os
2
- from typing import Dict, Any, Optional
3
- from jarvis.jarvis_coder.main import JarvisCoder
4
- from jarvis.utils import PrettyOutput, OutputType
5
-
6
- class CoderTool:
7
- """代码修改工具"""
8
-
9
- name = "coder"
10
- description = "Analyze and modify existing code for implementing new features, fixing bugs, refactoring code, etc. Can understand code context and perform precise code edits."
11
- parameters = {
12
- "feature": {
13
- "type": "string",
14
- "description": "Description of the feature to implement or content to modify, e.g., 'add logging functionality', 'fix memory leak', 'optimize performance', etc.",
15
- "required": True
16
- },
17
- "dir": {
18
- "type": "string",
19
- "description": "Project root directory, defaults to current directory",
20
- "required": False
21
- },
22
- "language": {
23
- "type": "string",
24
- "description": "Main programming language of the project, defaults to python",
25
- "required": False
26
- }
27
- }
28
-
29
- def __init__(self):
30
- self._coder = None
31
-
32
-
33
- def _init_coder(self, dir: Optional[str] = None, language: Optional[str] = "python") -> None:
34
- """初始化JarvisCoder实例"""
35
- if not self._coder:
36
- import os
37
- work_dir = dir or os.getcwd()
38
- self._coder = JarvisCoder(work_dir, language)
39
-
40
- def execute(self, args: Dict) -> Dict[str, Any]:
41
- """执行代码修改
42
-
43
- Args:
44
- feature: 要实现的功能描述
45
- dir: 可选,项目根目录
46
- language: 可选,编程语言
47
-
48
- Returns:
49
- Dict[str, Any]: 执行结果
50
- """
51
- feature = args.get("feature")
52
- dir = args.get("dir")
53
- language = args.get("language", "python")
54
-
55
- try:
56
- self.current_dir = os.getcwd()
57
- self._init_coder(dir, language)
58
- result = self._coder.execute(str(feature)) # type: ignore
59
- return result
60
- except Exception as e:
61
- PrettyOutput.print(f"代码修改失败: {str(e)}", OutputType.ERROR)
62
- return {
63
- "success": False,
64
- "stdout": "",
65
- "stderr": f"执行失败: {str(e)}",
66
- "error": e
67
- }
68
- finally:
69
- os.chdir(self.current_dir)
@@ -1,47 +0,0 @@
1
- jarvis/__init__.py,sha256=H5VVLl_TbloHsL4Uo5ZiI3kdTZALf6RmT-dv6Xy76a8,50
2
- jarvis/agent.py,sha256=9dfXBYO2QPYpiIXJixgoc1-CKHBDQcBlhskWrb0ZNYc,19636
3
- jarvis/main.py,sha256=mV_rW268R2CWnwDLUqmCqVOzEZBodwJoTzPiz979QF8,5919
4
- jarvis/utils.py,sha256=nqmOuQtmoIsc67iQNuWADwbXf2D3cbGjXan5VXLaTYk,11373
5
- jarvis/jarvis_codebase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- jarvis/jarvis_codebase/main.py,sha256=8A4VwK_MjAknT6ANj5Ptgf3wDD6e8rFOQVcU4gcVvH8,31183
7
- jarvis/jarvis_coder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- jarvis/jarvis_coder/git_utils.py,sha256=Rm0odJSbI3KGo8rTAAv1YsuudgjROlbHl7UBVOcxK3c,2237
9
- jarvis/jarvis_coder/main.py,sha256=l8q4xEvxSlha0kHJ3GarDCeu3mIu1un6OFeWALbQAqY,25144
10
- jarvis/jarvis_coder/patch_handler.py,sha256=FJy8NxECVExBudBlbOchoBKaLJQyG8z-KorjNkXUig0,9649
11
- jarvis/jarvis_coder/plan_generator.py,sha256=ODBeCT7pSv-SA0l22q8nAOwn2Usqr1TKHci8zMVpwmk,4474
12
- jarvis/jarvis_platform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- jarvis/jarvis_platform/main.py,sha256=R0b51en28HaMpqc2jxP4xnOUXYIQa4GBUs0vC_acD34,4882
14
- jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- jarvis/jarvis_rag/main.py,sha256=gVHdF_WyzJEoOgda6xVe-P9R2iAIRNf_vj6xZ1WPvrw,32766
16
- jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- jarvis/jarvis_smart_shell/main.py,sha256=nTIErwnib9z8a67f5k3PqlhTvbXffo4BVpAANXWekos,3895
18
- jarvis/models/__init__.py,sha256=mrOt67nselz_H1gX9wdAO4y2DY5WPXzABqJbr5Des8k,63
19
- jarvis/models/ai8.py,sha256=ZRNO3aRjmICRjCXl-_F9pTNQTY4j1tUd-WJoJpb9n4Y,11958
20
- jarvis/models/base.py,sha256=5QQAghMmVsg7jXvQN9ZzVoqCmMR0jb9bKgAVR3eOjQ8,2005
21
- jarvis/models/kimi.py,sha256=wLXEA-17yLVvMRn-SAMGwQ_gx6mBaGhlSsP8F5pfoL0,16391
22
- jarvis/models/ollama.py,sha256=E8JDe378yMreglSVN5c_9lHAGBbuzHcYG05v07mS2BI,5724
23
- jarvis/models/openai.py,sha256=tAvz2Pne7woDXUppD7Ina461mVQCxy0vG5cwv5MHpLg,4404
24
- jarvis/models/oyi.py,sha256=iA8E5vzN9VIt-rlzpT5wmbyl7umVU1_y5yo_5gz3DXc,14534
25
- jarvis/models/registry.py,sha256=wswPmR8gzsyFnJ6TcTh58Py4uj6N0vApblyuXI7NeOQ,9062
26
- jarvis/tools/__init__.py,sha256=7Rqyj5hBAv5cWDVr5T9ZTZASO7ssBHeQNm2_4ZARdkA,72
27
- jarvis/tools/ask_user.py,sha256=u1opLhuHUmqz7bvlpj44x0vgMlKrTzFuFqc6YFaajW0,1953
28
- jarvis/tools/base.py,sha256=c0DMoDDPxmsqUYJR989zgUs7nIYRY6GWBrAdusIZKjc,656
29
- jarvis/tools/chdir.py,sha256=YMrzj6V3JHxX94e8adz97x1_E5aWjUoEwkhDM4T2DEs,2793
30
- jarvis/tools/codebase_qa.py,sha256=AJEJYnmw3ro5PEqUQGbNEpqY7YwwjXvYpEzmZheMptk,2446
31
- jarvis/tools/coder.py,sha256=HKBIbDwkpK05Zh4-ZDhmkB4x0HL-wNZL8T_ojwCk7KM,2383
32
- jarvis/tools/file_ops.py,sha256=lRoKl6d53wT3-sun_JqGLY6MO4RiXfxJL3ybP-chzTQ,3845
33
- jarvis/tools/generator.py,sha256=5iw8-uLwMcwSzQ2DouoWYa4WYm_7ZmYfdJBU50z9SUE,6040
34
- jarvis/tools/methodology.py,sha256=zsEr-i5mifJH1BXg0JgrmPaToTBcbjGdm_aM88vVmug,5199
35
- jarvis/tools/rag.py,sha256=zUrAJNis_HmTDCfSztmulqYt4ulaYHRb6fd-EMXRO9c,4528
36
- jarvis/tools/registry.py,sha256=-Qwt_2wcahN2XBwRtziZgm6eVF18jOvtLwgXgwre1nA,9471
37
- jarvis/tools/search.py,sha256=qbSfHJ5RHx8cHSdcmOfTFMQCNg6IxztKH5Vg4FtVTdE,9075
38
- jarvis/tools/shell.py,sha256=6XIDzdTf67PDIObUZqLtHvhnlOLSyuV_GlfFwQJsSaU,2580
39
- jarvis/tools/sub_agent.py,sha256=7YPY3qUocH7RjE3MDKFGlXKlAMIQv3-ufPRzlNXwo7w,2676
40
- jarvis/tools/thinker.py,sha256=VFq0z9geAtGsRCbd8S73Rk7afAuGm3KQp6t5nayUJVg,4800
41
- jarvis/tools/webpage.py,sha256=_ts9ioSFR2wcMwjId_aV-jqSWpbiydU_beJQyn_aAv4,2405
42
- jarvis_ai_assistant-0.1.97.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
43
- jarvis_ai_assistant-0.1.97.dist-info/METADATA,sha256=23tqwSyUw2Nx2F6Q3VPuQBjAfi76ae2B6cafd2ZgboA,12766
44
- jarvis_ai_assistant-0.1.97.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
45
- jarvis_ai_assistant-0.1.97.dist-info/entry_points.txt,sha256=1D14s9v6rwpNzVD0muwe0tCKffJDEvLRBlEShbSFSbQ,331
46
- jarvis_ai_assistant-0.1.97.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
47
- jarvis_ai_assistant-0.1.97.dist-info/RECORD,,
File without changes
File without changes
File without changes