jarvis-ai-assistant 0.1.98__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.
- jarvis/__init__.py +1 -1
- jarvis/agent.py +199 -157
- jarvis/jarvis_code_agent/__init__.py +0 -0
- jarvis/jarvis_code_agent/main.py +203 -0
- jarvis/jarvis_codebase/main.py +412 -284
- jarvis/jarvis_coder/file_select.py +209 -0
- jarvis/jarvis_coder/git_utils.py +64 -2
- jarvis/jarvis_coder/main.py +11 -389
- jarvis/jarvis_coder/patch_handler.py +84 -14
- jarvis/jarvis_coder/plan_generator.py +49 -7
- jarvis/jarvis_rag/main.py +9 -9
- jarvis/jarvis_smart_shell/main.py +5 -7
- jarvis/models/base.py +6 -1
- jarvis/models/ollama.py +2 -2
- jarvis/models/registry.py +3 -6
- jarvis/tools/ask_user.py +6 -6
- jarvis/tools/codebase_qa.py +5 -7
- jarvis/tools/create_code_sub_agent.py +55 -0
- jarvis/tools/{sub_agent.py → create_sub_agent.py} +4 -1
- jarvis/tools/execute_code_modification.py +72 -0
- jarvis/tools/{file_ops.py → file_operation.py} +13 -14
- jarvis/tools/find_related_files.py +86 -0
- jarvis/tools/methodology.py +25 -25
- jarvis/tools/rag.py +32 -32
- jarvis/tools/registry.py +72 -36
- jarvis/tools/search.py +1 -1
- jarvis/tools/select_code_files.py +64 -0
- jarvis/utils.py +153 -49
- {jarvis_ai_assistant-0.1.98.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/METADATA +1 -1
- jarvis_ai_assistant-0.1.99.dist-info/RECORD +52 -0
- {jarvis_ai_assistant-0.1.98.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/entry_points.txt +2 -1
- jarvis/main.py +0 -155
- jarvis/tools/coder.py +0 -69
- jarvis_ai_assistant-0.1.98.dist-info/RECORD +0 -47
- /jarvis/tools/{shell.py → execute_shell.py} +0 -0
- /jarvis/tools/{generator.py → generate_tool.py} +0 -0
- /jarvis/tools/{webpage.py → read_webpage.py} +0 -0
- {jarvis_ai_assistant-0.1.98.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.98.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.98.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 =
|
|
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 -
|
|
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-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
#
|
|
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 ""
|
|
@@ -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,,
|
{jarvis_ai_assistant-0.1.98.dist-info → jarvis_ai_assistant-0.1.99.dist-info}/entry_points.txt
RENAMED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
[console_scripts]
|
|
2
|
-
jarvis = jarvis.
|
|
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=LaazWaS94sRO9a8aOdOMwKl05JkbI63DYYlhGFXw32M,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=91Kv7Q4SFNXj-SJ5L-5Bv5UQVXEPnR7LCLXPNygGViA,2334
|
|
9
|
-
jarvis/jarvis_coder/main.py,sha256=Rjjq8pBhKaSpsjPJ-qbehYq_7wLjmeeZUjlXGgamuhI,25853
|
|
10
|
-
jarvis/jarvis_coder/patch_handler.py,sha256=YOTG-OZa-J6Zhp7IzSTCLQn90vyN3eSbOQyqzT7LZiE,9768
|
|
11
|
-
jarvis/jarvis_coder/plan_generator.py,sha256=nAaBFwPPI5Lu89hsZRYad0m_hTELnRQZ2plSx6VJU3Q,4585
|
|
12
|
-
jarvis/jarvis_platform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
jarvis/jarvis_platform/main.py,sha256=Hb40MmN4We9oY8BHzLyrNTm-p7Mg50s2nqLaLxflC48,4981
|
|
14
|
-
jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
jarvis/jarvis_rag/main.py,sha256=z6D-2nNVptp7YGHhU4O8gSfFsEXhNkPvj6ZMJztQuuU,33490
|
|
16
|
-
jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
jarvis/jarvis_smart_shell/main.py,sha256=MOTSlE09YqwV4smWjHTGLKPf--hFMWfGrgD1LMb1FGU,3988
|
|
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.98.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
|
43
|
-
jarvis_ai_assistant-0.1.98.dist-info/METADATA,sha256=-s5OHAXkUGAVfb8oL5VJLIC2NUQRk2Vn0WoSaHVaxX0,12766
|
|
44
|
-
jarvis_ai_assistant-0.1.98.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
45
|
-
jarvis_ai_assistant-0.1.98.dist-info/entry_points.txt,sha256=1D14s9v6rwpNzVD0muwe0tCKffJDEvLRBlEShbSFSbQ,331
|
|
46
|
-
jarvis_ai_assistant-0.1.98.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
47
|
-
jarvis_ai_assistant-0.1.98.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|