jarvis-ai-assistant 0.1.98__tar.gz → 0.1.100__tar.gz

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 (65) hide show
  1. {jarvis_ai_assistant-0.1.98/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.100}/PKG-INFO +9 -8
  2. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/README.md +8 -7
  3. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/pyproject.toml +3 -2
  4. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/setup.py +3 -2
  5. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/__init__.py +1 -1
  6. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/agent.py +199 -157
  7. jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_code_agent/main.py +202 -0
  8. jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_codebase/main.py +875 -0
  9. jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_coder/file_select.py +209 -0
  10. jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_coder/git_utils.py +123 -0
  11. jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_coder/main.py +241 -0
  12. jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_coder/patch_handler.py +340 -0
  13. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/jarvis_coder/plan_generator.py +49 -7
  14. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/jarvis_platform/main.py +2 -2
  15. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/jarvis_rag/main.py +11 -11
  16. jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
  17. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/jarvis_smart_shell/main.py +5 -5
  18. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/models/base.py +6 -1
  19. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/models/kimi.py +2 -2
  20. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/models/ollama.py +2 -2
  21. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/models/openai.py +1 -1
  22. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/models/registry.py +38 -18
  23. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/ask_user.py +12 -9
  24. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/chdir.py +9 -5
  25. jarvis_ai_assistant-0.1.100/src/jarvis/tools/create_code_sub_agent.py +56 -0
  26. jarvis_ai_assistant-0.1.98/src/jarvis/tools/sub_agent.py → jarvis_ai_assistant-0.1.100/src/jarvis/tools/create_sub_agent.py +6 -2
  27. jarvis_ai_assistant-0.1.100/src/jarvis/tools/execute_code_modification.py +70 -0
  28. jarvis_ai_assistant-0.1.98/src/jarvis/tools/shell.py → jarvis_ai_assistant-0.1.100/src/jarvis/tools/execute_shell.py +2 -2
  29. jarvis_ai_assistant-0.1.98/src/jarvis/tools/file_ops.py → jarvis_ai_assistant-0.1.100/src/jarvis/tools/file_operation.py +19 -15
  30. jarvis_ai_assistant-0.1.100/src/jarvis/tools/find_files.py +119 -0
  31. jarvis_ai_assistant-0.1.98/src/jarvis/tools/generator.py → jarvis_ai_assistant-0.1.100/src/jarvis/tools/generate_tool.py +27 -25
  32. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/methodology.py +32 -26
  33. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/rag.py +37 -33
  34. jarvis_ai_assistant-0.1.98/src/jarvis/tools/webpage.py → jarvis_ai_assistant-0.1.100/src/jarvis/tools/read_webpage.py +4 -2
  35. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/registry.py +94 -48
  36. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/search.py +19 -16
  37. jarvis_ai_assistant-0.1.100/src/jarvis/tools/select_code_files.py +61 -0
  38. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/thinker.py +7 -5
  39. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/utils.py +155 -32
  40. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100/src/jarvis_ai_assistant.egg-info}/PKG-INFO +9 -8
  41. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +12 -8
  42. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis_ai_assistant.egg-info/entry_points.txt +2 -1
  43. jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_codebase/main.py +0 -747
  44. jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_coder/git_utils.py +0 -61
  45. jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_coder/main.py +0 -625
  46. jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_coder/patch_handler.py +0 -192
  47. jarvis_ai_assistant-0.1.98/src/jarvis/main.py +0 -155
  48. jarvis_ai_assistant-0.1.98/src/jarvis/tools/codebase_qa.py +0 -74
  49. jarvis_ai_assistant-0.1.98/src/jarvis/tools/coder.py +0 -69
  50. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/LICENSE +0 -0
  51. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/MANIFEST.in +0 -0
  52. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/setup.cfg +0 -0
  53. {jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_codebase → jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_code_agent}/__init__.py +0 -0
  54. {jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_coder → jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_codebase}/__init__.py +0 -0
  55. {jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_platform → jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_coder}/__init__.py +0 -0
  56. {jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_rag → jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_platform}/__init__.py +0 -0
  57. {jarvis_ai_assistant-0.1.98/src/jarvis/jarvis_smart_shell → jarvis_ai_assistant-0.1.100/src/jarvis/jarvis_rag}/__init__.py +0 -0
  58. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/models/__init__.py +0 -0
  59. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/models/ai8.py +0 -0
  60. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/models/oyi.py +0 -0
  61. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/__init__.py +0 -0
  62. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis/tools/base.py +0 -0
  63. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  64. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
  65. {jarvis_ai_assistant-0.1.98 → jarvis_ai_assistant-0.1.100}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.98
3
+ Version: 0.1.100
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
@@ -125,7 +125,7 @@ pip install jarvis-ai-assistant
125
125
 
126
126
  ## 🔧 Configuration
127
127
 
128
- Jarvis supports configuration through environment variables that can be set in the `~/.jarvis_env` file:
128
+ Jarvis supports configuration through environment variables that can be set in the `~/.jarvis/env` file:
129
129
 
130
130
  | Environment Variable | Description | Default Value | Required |
131
131
  |---------|------|--------|------|
@@ -204,7 +204,7 @@ jarvis-search "your query" --max 3
204
204
 
205
205
  ### Tool Locations
206
206
  - Built-in tools: `src/jarvis/tools/`
207
- - User tools: `~/.jarvis_tools/`
207
+ - User tools: `~/.jarvis/tools/`
208
208
 
209
209
 
210
210
  ### Key Features
@@ -241,7 +241,7 @@ jarvis-search "your query" --max 3
241
241
 
242
242
  ### Adding New Tools
243
243
 
244
- Create a new Python file in `~/.jarvis_tools/` or `src/jarvis/tools/`:
244
+ Create a new Python file in `~/.jarvis/tools/` or `src/jarvis/tools/`:
245
245
 
246
246
  ```python
247
247
  from typing import Dict, Any
@@ -273,7 +273,6 @@ class CustomTool:
273
273
  "success": bool,
274
274
  "stdout": str, # On success
275
275
  "stderr": str, # Optional error details
276
- "error": str # On failure
277
276
  }
278
277
  """
279
278
  try:
@@ -281,18 +280,20 @@ class CustomTool:
281
280
  result = "Tool execution result"
282
281
  return {
283
282
  "success": True,
284
- "stdout": result
283
+ "stdout": result,
284
+ "stderr": ""
285
285
  }
286
286
  except Exception as e:
287
287
  return {
288
288
  "success": False,
289
- "error": str(e)
289
+ "stdout": "",
290
+ "stderr": str(e)
290
291
  }
291
292
  ```
292
293
 
293
294
  ### Adding New Models
294
295
 
295
- Create a new Python file in `~/.jarvis_models/`:
296
+ Create a new Python file in `~/.jarvis/models/`:
296
297
 
297
298
  ```python
298
299
  from typing import Dict, List
@@ -59,7 +59,7 @@ pip install jarvis-ai-assistant
59
59
 
60
60
  ## 🔧 Configuration
61
61
 
62
- Jarvis supports configuration through environment variables that can be set in the `~/.jarvis_env` file:
62
+ Jarvis supports configuration through environment variables that can be set in the `~/.jarvis/env` file:
63
63
 
64
64
  | Environment Variable | Description | Default Value | Required |
65
65
  |---------|------|--------|------|
@@ -138,7 +138,7 @@ jarvis-search "your query" --max 3
138
138
 
139
139
  ### Tool Locations
140
140
  - Built-in tools: `src/jarvis/tools/`
141
- - User tools: `~/.jarvis_tools/`
141
+ - User tools: `~/.jarvis/tools/`
142
142
 
143
143
 
144
144
  ### Key Features
@@ -175,7 +175,7 @@ jarvis-search "your query" --max 3
175
175
 
176
176
  ### Adding New Tools
177
177
 
178
- Create a new Python file in `~/.jarvis_tools/` or `src/jarvis/tools/`:
178
+ Create a new Python file in `~/.jarvis/tools/` or `src/jarvis/tools/`:
179
179
 
180
180
  ```python
181
181
  from typing import Dict, Any
@@ -207,7 +207,6 @@ class CustomTool:
207
207
  "success": bool,
208
208
  "stdout": str, # On success
209
209
  "stderr": str, # Optional error details
210
- "error": str # On failure
211
210
  }
212
211
  """
213
212
  try:
@@ -215,18 +214,20 @@ class CustomTool:
215
214
  result = "Tool execution result"
216
215
  return {
217
216
  "success": True,
218
- "stdout": result
217
+ "stdout": result,
218
+ "stderr": ""
219
219
  }
220
220
  except Exception as e:
221
221
  return {
222
222
  "success": False,
223
- "error": str(e)
223
+ "stdout": "",
224
+ "stderr": str(e)
224
225
  }
225
226
  ```
226
227
 
227
228
  ### Adding New Models
228
229
 
229
- Create a new Python file in `~/.jarvis_models/`:
230
+ Create a new Python file in `~/.jarvis/models/`:
230
231
 
231
232
  ```python
232
233
  from typing import Dict, List
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jarvis-ai-assistant"
7
- version = "0.1.98"
7
+ version = "0.1.100"
8
8
  description = "Jarvis: An AI assistant that uses tools to interact with the system"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Your Name", email = "your.email@example.com" }]
@@ -47,7 +47,8 @@ dev = ["pytest", "black", "isort", "mypy"]
47
47
  Homepage = "https://github.com/skyfireitdiy/Jarvis"
48
48
 
49
49
  [project.scripts]
50
- jarvis = "jarvis.main:main"
50
+ jarvis = "jarvis.agent:main"
51
+ jarvis-code-agent = "jarvis.jarvis_code_agent.main:main"
51
52
  jarvis-coder = "jarvis.jarvis_coder.main:main"
52
53
  jarvis-codebase = "jarvis.jarvis_codebase.main:main"
53
54
  jarvis-rag = "jarvis.jarvis_rag.main:main"
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="jarvis-ai-assistant",
5
- version="0.1.98",
5
+ version="0.1.100",
6
6
  author="skyfire",
7
7
  author_email="skyfireitdiy@hotmail.com",
8
8
  description="An AI assistant that uses various tools to interact with the system",
@@ -32,7 +32,8 @@ setup(
32
32
  ],
33
33
  entry_points={
34
34
  "console_scripts": [
35
- "jarvis=jarvis.main:main",
35
+ "jarvis=jarvis.agent:main",
36
+ "jarvis-code-agent=jarvis.jarvis_code_agent.main:main",
36
37
  "jarvis-coder=jarvis.jarvis_coder.main:main",
37
38
  "jarvis-codebase=jarvis.jarvis_codebase.main:main",
38
39
  "jarvis-rag=jarvis.jarvis_rag.main:main",
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.98"
3
+ __version__ = "0.1.100"
@@ -1,32 +1,39 @@
1
+ import argparse
1
2
  import time
2
3
  from typing import Dict, List, Optional
3
4
 
5
+ from prompt_toolkit import prompt
4
6
  import yaml
5
- import numpy as np
6
- import faiss
7
7
 
8
- from .models.registry import PlatformRegistry
9
- from .tools import ToolRegistry
10
- from .utils import PrettyOutput, OutputType, get_max_context_length, get_multiline_input, load_embedding_model
8
+ from jarvis.models.registry import PlatformRegistry
9
+ from jarvis.tools import ToolRegistry
10
+ from jarvis.tools.registry import load_tools
11
+ from jarvis.utils import PrettyOutput, OutputType, get_single_line_input, load_methodology, add_agent, delete_current_agent, get_max_context_length, get_multiline_input, load_embedding_model, init_env
11
12
  import os
12
13
 
13
14
  class Agent:
14
- def __init__(self, name: str = "Jarvis", is_sub_agent: bool = False):
15
+
16
+ def __del__(self):
17
+ delete_current_agent()
18
+
19
+ def __init__(self, system_prompt: str, name: str = "Jarvis", is_sub_agent: bool = False, tool_registry: Optional[ToolRegistry] = None):
15
20
  """Initialize Agent with a model, optional tool registry and name
16
21
 
17
22
  Args:
18
- model: LLM model instance
19
- tool_registry: Tool registry instance
23
+ system_prompt: System prompt
20
24
  name: Agent name, default is "Jarvis"
21
25
  is_sub_agent: Whether it is a sub-agent, default is False
26
+ tool_registry: Tool registry instance
22
27
  """
28
+ add_agent(name)
29
+ PrettyOutput.print(f"Welcome to Jarvis, your AI assistant, Initiating...", OutputType.SYSTEM)
23
30
  self.model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
24
- self.tool_registry = ToolRegistry.get_global_tool_registry()
31
+ self.tool_registry = tool_registry if tool_registry else ToolRegistry.get_global_tool_registry()
25
32
  self.name = name
26
33
  self.is_sub_agent = is_sub_agent
27
34
  self.prompt = ""
28
35
  self.conversation_length = 0 # Use length counter instead
29
-
36
+ self.system_prompt = system_prompt
30
37
  # Load configuration from environment variables
31
38
  self.embedding_dimension = 1536 # Default for many embedding models
32
39
  self.max_context_length = get_max_context_length()
@@ -46,10 +53,7 @@ class Agent:
46
53
  PrettyOutput.print("Successfully loaded embedding model", OutputType.SUCCESS)
47
54
 
48
55
  # Initialize HNSW index (use correct dimension)
49
- hnsw_index = faiss.IndexHNSWFlat(self.embedding_dimension, 16)
50
- hnsw_index.hnsw.efConstruction = 40
51
- hnsw_index.hnsw.efSearch = 16
52
- self.methodology_index = faiss.IndexIDMap(hnsw_index)
56
+
53
57
 
54
58
  except Exception as e:
55
59
  PrettyOutput.print(f"Failed to load embedding model: {str(e)}", OutputType.ERROR)
@@ -58,6 +62,8 @@ class Agent:
58
62
  # Initialize methodology related attributes
59
63
  self.methodology_data = []
60
64
 
65
+ PrettyOutput.section(f"Jarvis initialized - With {self.model.name()}", OutputType.SYSTEM)
66
+
61
67
  @staticmethod
62
68
  def extract_tool_calls(content: str) -> List[Dict]:
63
69
  """Extract tool calls from content, if multiple tool calls are detected, raise an exception, and return the content before the tool call and the tool call"""
@@ -65,7 +71,16 @@ class Agent:
65
71
  lines = content.split('\n')
66
72
  tool_call_lines = []
67
73
  in_tool_call = False
68
-
74
+
75
+ tool_call_help = """Tool Usage Format:
76
+
77
+ <TOOL_CALL>
78
+ name: tool_name
79
+ arguments:
80
+ param1: value1
81
+ param2: value2
82
+ </TOOL_CALL>"""
83
+
69
84
  # Process line by line
70
85
  for line in lines:
71
86
  if '<TOOL_CALL>' in line:
@@ -87,7 +102,7 @@ class Agent:
87
102
  }]
88
103
  else:
89
104
  PrettyOutput.print("Tool call missing necessary fields", OutputType.ERROR)
90
- raise Exception("Tool call missing necessary fields")
105
+ raise Exception("Tool call missing necessary fields, " + tool_call_help)
91
106
  except yaml.YAMLError as e:
92
107
  PrettyOutput.print(f"YAML parsing error: {str(e)}", OutputType.ERROR)
93
108
  raise Exception(f"YAML parsing error: {str(e)}")
@@ -117,78 +132,6 @@ class Agent:
117
132
  sleep_time = 30
118
133
  continue
119
134
 
120
- def _create_methodology_embedding(self, methodology_text: str) -> np.ndarray:
121
- """Create embedding vector for methodology text"""
122
- try:
123
- # Truncate long text
124
- max_length = 512
125
- text = ' '.join(methodology_text.split()[:max_length])
126
-
127
- # 使用sentence_transformers模型获取嵌入向量
128
- embedding = self.embedding_model.encode([text],
129
- convert_to_tensor=True,
130
- normalize_embeddings=True)
131
- vector = np.array(embedding.cpu().numpy(), dtype=np.float32)
132
- return vector[0] # Return first vector, because we only encoded one text
133
- except Exception as e:
134
- PrettyOutput.print(f"Failed to create methodology embedding vector: {str(e)}", OutputType.ERROR)
135
- return np.zeros(self.embedding_dimension, dtype=np.float32)
136
-
137
- def _load_methodology(self, user_input: str) -> Dict[str, str]:
138
- """Load methodology and build vector index"""
139
- PrettyOutput.print("Loading methodology...", OutputType.PROGRESS)
140
- user_jarvis_methodology = os.path.expanduser("~/.jarvis_methodology")
141
- if not os.path.exists(user_jarvis_methodology):
142
- return {}
143
-
144
- try:
145
- with open(user_jarvis_methodology, "r", encoding="utf-8") as f:
146
- data = yaml.safe_load(f)
147
-
148
- # Reset data structure
149
- self.methodology_data = []
150
- vectors = []
151
- ids = []
152
-
153
- # Create embedding vector for each methodology
154
- for i, (key, value) in enumerate(data.items()):
155
- PrettyOutput.print(f"Vectorizing methodology: {key} ...", OutputType.INFO)
156
- methodology_text = f"{key}\n{value}"
157
- embedding = self._create_methodology_embedding(methodology_text)
158
- vectors.append(embedding)
159
- ids.append(i)
160
- self.methodology_data.append({"key": key, "value": value})
161
-
162
- if vectors:
163
- vectors_array = np.vstack(vectors)
164
- self.methodology_index.add_with_ids(vectors_array, np.array(ids)) # type: ignore
165
- query_embedding = self._create_methodology_embedding(user_input)
166
- k = min(5, len(self.methodology_data))
167
- PrettyOutput.print(f"Retrieving methodology...", OutputType.INFO)
168
- distances, indices = self.methodology_index.search(
169
- query_embedding.reshape(1, -1), k
170
- ) # type: ignore
171
-
172
- relevant_methodologies = {}
173
- for dist, idx in zip(distances[0], indices[0]):
174
- if idx >= 0:
175
- similarity = 1.0 / (1.0 + float(dist))
176
- methodology = self.methodology_data[idx]
177
- PrettyOutput.print(
178
- f"Methodology '{methodology['key']}' similarity: {similarity:.3f}",
179
- OutputType.INFO
180
- )
181
- if similarity >= 0.5:
182
- relevant_methodologies[methodology["key"]] = methodology["value"]
183
-
184
- if relevant_methodologies:
185
- return relevant_methodologies
186
-
187
- return {}
188
-
189
- except Exception as e:
190
- PrettyOutput.print(f"Error loading methodology: {str(e)}", OutputType.ERROR)
191
- return {}
192
135
 
193
136
  def _summarize_and_clear_history(self) -> None:
194
137
  """
@@ -244,7 +187,7 @@ Please continue the task based on the above information.
244
187
 
245
188
  # 询问是否生成方法论,带输入验证
246
189
  while True:
247
- user_input = input("Generate methodology for this task? (y/n): ").strip().lower()
190
+ user_input = get_single_line_input("Generate methodology for this task? (y/n)").strip().lower()
248
191
  if user_input in ['y', 'n', '']:
249
192
  break
250
193
  PrettyOutput.print("Invalid input, please enter y or n", OutputType.WARNING)
@@ -307,84 +250,20 @@ Please describe in concise bullet points, highlighting important information.
307
250
  self.model.upload_files(file_list)
308
251
 
309
252
  # Load methodology
310
- methodology = self._load_methodology(user_input)
311
- methodology_prompt = ""
312
- if methodology:
313
- methodology_prompt = f"""This is the standard methodology for handling previous problems, if the current task is similar, you can refer to it:
314
- {methodology}
315
-
316
- """
317
- tools_prompt = ""
318
-
319
- # 选择工具
320
- PrettyOutput.section("Available tools", OutputType.PLANNING)
321
- tools = self.tool_registry.get_all_tools()
322
- if tools:
323
- tools_prompt += "Available tools:\n"
324
- for tool in tools:
325
- PrettyOutput.print(f"{tool['name']}: {tool['description']}", OutputType.INFO)
326
- tools_prompt += f"- Name: {tool['name']}\n"
327
- tools_prompt += f" Description: {tool['description']}\n"
328
- tools_prompt += f" Parameters: {tool['parameters']}\n"
253
+ methodology_prompt = load_methodology(user_input)
254
+ tools_prompt = load_tools()
329
255
 
330
256
  # 显示任务开始
331
257
  PrettyOutput.section(f"Starting new task: {self.name}", OutputType.PLANNING)
332
258
 
333
259
  self.clear_history()
334
260
 
335
- self.model.set_system_message(f"""You are {self.name}, an AI assistant with powerful problem-solving capabilities.
336
-
337
- When users need to execute tasks, you will strictly follow these steps to handle problems:
338
- 1. Problem Restatement: Confirm understanding of the problem
339
- 2. Root Cause Analysis (only if needed for problem analysis tasks)
340
- 3. Set Objectives: Define achievable and verifiable goals
341
- 4. Generate Solutions: Create one or more actionable solutions
342
- 5. Evaluate Solutions: Select the optimal solution from multiple options
343
- 6. Create Action Plan: Based on available tools, create an action plan using PlantUML format for clear execution flow
344
- 7. Execute Action Plan: Execute one step at a time, **use at most one tool** (wait for tool execution results before proceeding)
345
- 8. Monitor and Adjust: If execution results don't match expectations, reflect and adjust the action plan, iterate previous steps
346
- 9. Methodology: If the current task has general applicability and valuable experience is gained, use methodology tools to record it for future similar problems
347
- 10. Task Completion: End the task using task completion command when finished
348
-
349
- Methodology Template:
350
- 1. Problem Restatement
351
- 2. Optimal Solution
352
- 3. Optimal Solution Steps (exclude failed actions)
353
-
354
- -------------------------------------------------------------
261
+ self.model.set_system_message(f"""
262
+ {self.system_prompt}
355
263
 
356
264
  {tools_prompt}
357
265
 
358
- -------------------------------------------------------------
359
-
360
- Tool Usage Format:
361
-
362
- <TOOL_CALL>
363
- name: tool_name
364
- arguments:
365
- param1: value1
366
- param2: value2
367
- </TOOL_CALL>
368
-
369
- -------------------------------------------------------------
370
-
371
- Strict Rules:
372
- - Execute only one tool at a time
373
- - Tool execution must strictly follow the tool usage format
374
- - Wait for user to provide execution results
375
- - Don't assume or imagine results
376
- - Don't create fake dialogues
377
- - If current information is insufficient, you may ask the user
378
- - Not all problem-solving steps are mandatory, skip as appropriate
379
- - Ask user before executing tools that might damage system or user's codebase
380
- - Request user guidance when multiple iterations show no progress
381
- - If yaml string contains colons, wrap the entire string in quotes to avoid yaml parsing errors
382
- - Use | syntax for multi-line strings in yaml
383
-
384
266
  {methodology_prompt}
385
-
386
- -------------------------------------------------------------
387
-
388
267
  """)
389
268
  self.prompt = f"{user_input}"
390
269
 
@@ -446,3 +325,166 @@ Strict Rules:
446
325
 
447
326
 
448
327
 
328
+
329
+ def load_tasks() -> dict:
330
+ """Load tasks from .jarvis files in user home and current directory."""
331
+ tasks = {}
332
+
333
+ # Check .jarvis/pre-command in user directory
334
+ user_jarvis = os.path.expanduser("~/.jarvis/pre-command")
335
+ if os.path.exists(user_jarvis):
336
+ try:
337
+ with open(user_jarvis, "r", encoding="utf-8") as f:
338
+ user_tasks = yaml.safe_load(f)
339
+
340
+ if isinstance(user_tasks, dict):
341
+ # Validate and add user directory tasks
342
+ for name, desc in user_tasks.items():
343
+ if desc: # Ensure description is not empty
344
+ tasks[str(name)] = str(desc)
345
+ else:
346
+ PrettyOutput.print("Warning: ~/.jarvis/pre-command file should contain a dictionary of task_name: task_description", OutputType.ERROR)
347
+ except Exception as e:
348
+ PrettyOutput.print(f"Error loading ~/.jarvis/pre-command file: {str(e)}", OutputType.ERROR)
349
+
350
+ # Check .jarvis/pre-command in current directory
351
+ if os.path.exists(".jarvis/pre-command"):
352
+ try:
353
+ with open(".jarvis/pre-command", "r", encoding="utf-8") as f:
354
+ local_tasks = yaml.safe_load(f)
355
+
356
+ if isinstance(local_tasks, dict):
357
+ # Validate and add current directory tasks, overwrite user directory tasks if there is a name conflict
358
+ for name, desc in local_tasks.items():
359
+ if desc: # Ensure description is not empty
360
+ tasks[str(name)] = str(desc)
361
+ else:
362
+ PrettyOutput.print("Warning: .jarvis/pre-command file should contain a dictionary of task_name: task_description", OutputType.ERROR)
363
+ except Exception as e:
364
+ PrettyOutput.print(f"Error loading .jarvis/pre-command file: {str(e)}", OutputType.ERROR)
365
+
366
+ # Read methodology
367
+ method_path = os.path.expanduser("~/.jarvis/methodology")
368
+ if os.path.exists(method_path):
369
+ with open(method_path, "r", encoding="utf-8") as f:
370
+ methodology = yaml.safe_load(f)
371
+ if isinstance(methodology, dict):
372
+ for name, desc in methodology.items():
373
+ tasks[f"Run Methodology: {str(name)}\n {str(desc)}" ] = str(desc)
374
+
375
+ return tasks
376
+
377
+ def select_task(tasks: dict) -> str:
378
+ """Let user select a task from the list or skip. Returns task description if selected."""
379
+ if not tasks:
380
+ return ""
381
+
382
+ # Convert tasks to list for ordered display
383
+ task_names = list(tasks.keys())
384
+
385
+ PrettyOutput.print("\nAvailable tasks:", OutputType.INFO)
386
+ for i, name in enumerate(task_names, 1):
387
+ PrettyOutput.print(f"[{i}] {name}", OutputType.INFO)
388
+ PrettyOutput.print("[0] Skip predefined tasks", OutputType.INFO)
389
+
390
+
391
+ while True:
392
+ try:
393
+ choice = prompt(
394
+ "\nPlease select a task number (0 to skip): ",
395
+ ).strip()
396
+
397
+ if not choice:
398
+ return ""
399
+
400
+ choice = int(choice)
401
+ if choice == 0:
402
+ return ""
403
+ elif 1 <= choice <= len(task_names):
404
+ selected_name = task_names[choice - 1]
405
+ return tasks[selected_name] # Return the task description
406
+ else:
407
+ PrettyOutput.print("Invalid choice. Please select a number from the list.", OutputType.ERROR)
408
+
409
+ except KeyboardInterrupt:
410
+ return "" # Return empty on Ctrl+C
411
+ except EOFError:
412
+ return "" # Return empty on Ctrl+D
413
+ except Exception as e:
414
+ PrettyOutput.print(f"Failed to select task: {str(e)}", OutputType.ERROR)
415
+ continue
416
+
417
+ origin_agent_system_prompt = """You are Jarvis, an AI assistant with powerful problem-solving capabilities.
418
+
419
+ When users need to execute tasks, you will strictly follow these steps to handle problems:
420
+ 1. Problem Restatement: Confirm understanding of the problem
421
+ 2. Root Cause Analysis (only if needed for problem analysis tasks)
422
+ 3. Set Objectives: Define achievable and verifiable goals
423
+ 4. Generate Solutions: Create one or more actionable solutions
424
+ 5. Evaluate Solutions: Select the optimal solution from multiple options
425
+ 6. Create Action Plan: Based on available tools, create an action plan using PlantUML format for clear execution flow
426
+ 7. Execute Action Plan: Execute one step at a time, **use at most one tool** (wait for tool execution results before proceeding)
427
+ 8. Monitor and Adjust: If execution results don't match expectations, reflect and adjust the action plan, iterate previous steps
428
+ 9. Methodology: If the current task has general applicability and valuable experience is gained, use methodology tools to record it for future similar problems
429
+ 10. Task Completion: End the task using task completion command when finished
430
+
431
+ Methodology Template:
432
+ 1. Problem Restatement
433
+ 2. Optimal Solution
434
+ 3. Optimal Solution Steps (exclude failed actions)
435
+
436
+ Strict Rules:
437
+ - Execute only one tool at a time
438
+ - Tool execution must strictly follow the tool usage format
439
+ - Wait for user to provide execution results
440
+ - Don't assume or imagine results
441
+ - Don't create fake dialogues
442
+ - If current information is insufficient, you may ask the user
443
+ - Not all problem-solving steps are mandatory, skip as appropriate
444
+ - Ask user before executing tools that might damage system or user's codebase
445
+ - Request user guidance when multiple iterations show no progress
446
+ - If yaml string contains colons, wrap the entire string in quotes to avoid yaml parsing errors
447
+ - Use | syntax for multi-line strings in yaml
448
+ - If you can start executing the task, please start directly without asking the user if you can begin.
449
+
450
+ -------------------------------------------------------------"""
451
+
452
+ def main():
453
+ """Jarvis main entry point"""
454
+ # Add argument parser
455
+ init_env()
456
+ parser = argparse.ArgumentParser(description='Jarvis AI assistant')
457
+ parser.add_argument('-f', '--files', nargs='*', help='List of files to process')
458
+ args = parser.parse_args()
459
+
460
+ try:
461
+ # 获取全局模型实例
462
+ agent = Agent(system_prompt=origin_agent_system_prompt)
463
+
464
+ # 加载预定义任务
465
+ tasks = load_tasks()
466
+ if tasks:
467
+ selected_task = select_task(tasks)
468
+ if selected_task:
469
+ PrettyOutput.print(f"\nExecute task: {selected_task}", OutputType.INFO)
470
+ agent.run(selected_task, args.files)
471
+ return 0
472
+
473
+ # 如果没有选择预定义任务,进入交互模式
474
+ while True:
475
+ try:
476
+ user_input = get_multiline_input("Please enter your task (input empty line to exit):")
477
+ if not user_input or user_input == "__interrupt__":
478
+ break
479
+ agent.run(user_input, args.files)
480
+ except Exception as e:
481
+ PrettyOutput.print(f"Error: {str(e)}", OutputType.ERROR)
482
+
483
+ except Exception as e:
484
+ PrettyOutput.print(f"Initialization error: {str(e)}", OutputType.ERROR)
485
+ return 1
486
+
487
+ return 0
488
+
489
+ if __name__ == "__main__":
490
+ exit(main())