jarvis-ai-assistant 0.1.118__py3-none-any.whl → 0.1.119__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 CHANGED
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.118"
3
+ __version__ = "0.1.119"
@@ -94,34 +94,34 @@ Please describe in concise bullet points, highlighting important information.
94
94
 
95
95
  PrettyOutput.print(welcome_message, OutputType.SYSTEM)
96
96
 
97
- tool_prompt = """
98
- # 🧰 Available Tools
99
- The following tools are at your disposal:
97
+ action_prompt = """
98
+ # 🧰 Available Actions
99
+ The following actions are at your disposal:
100
100
  """
101
101
 
102
102
  # 添加工具列表概览
103
- tool_prompt += "\n## Tool List\n"
104
- tool_prompt += ", ".join([handler.name() for handler in self.output_handler])
103
+ action_prompt += "\n## Action List\n"
104
+ action_prompt += ", ".join([handler.name() for handler in self.output_handler])
105
105
 
106
106
  # 添加每个工具的详细说明
107
- tool_prompt += "\n\n# 📝 Tool Details\n"
107
+ action_prompt += "\n\n# 📝 Action Details\n"
108
108
  for handler in self.output_handler:
109
- tool_prompt += f"\n## {handler.name()}\n"
109
+ action_prompt += f"\n## {handler.name()}\n"
110
110
  # 获取工具的提示词并确保格式正确
111
111
  handler_prompt = handler.prompt().strip()
112
112
  # 调整缩进以保持层级结构
113
113
  handler_prompt = "\n".join(" " + line if line.strip() else line
114
114
  for line in handler_prompt.split("\n"))
115
- tool_prompt += handler_prompt + "\n"
115
+ action_prompt += handler_prompt + "\n"
116
116
 
117
117
  # 添加工具使用总结
118
- tool_prompt += """
119
- # ❗ Important Tool Usage Rules
120
- 1. Use ONE tool at a time
121
- 2. Follow each tool's format exactly
122
- 3. Wait for tool results before next action
123
- 4. Process results before new tool calls
124
- 5. Request help if tool usage is unclear
118
+ action_prompt += """
119
+ # ❗ Important Action Usage Rules
120
+ 1. Use ONE action at a time
121
+ 2. Follow each action's format exactly
122
+ 3. Wait for action results before next action
123
+ 4. Process results before new action calls
124
+ 5. Request help if action usage is unclear
125
125
  """
126
126
 
127
127
  complete_prompt = ""
@@ -135,7 +135,7 @@ The following tools are at your disposal:
135
135
  self.model.set_system_message(f"""
136
136
  {self.system_prompt}
137
137
 
138
- {tool_prompt}
138
+ {action_prompt}
139
139
 
140
140
  {complete_prompt}
141
141
  """)
@@ -156,10 +156,8 @@ The following tools are at your disposal:
156
156
  Will retry with exponential backoff up to 30 seconds between retries
157
157
  """
158
158
  sleep_time = 5
159
-
160
159
  for handler in self.input_handler:
161
- message = handler(message)
162
-
160
+ message = handler(message, self)
163
161
  while True:
164
162
  ret = self.model.chat_until_success(message) # type: ignore
165
163
  if ret:
@@ -398,24 +396,11 @@ def _load_tasks() -> dict:
398
396
  except Exception as e:
399
397
  PrettyOutput.print(f"加载 .jarvis/pre-command 文件失败: {str(e)}", OutputType.ERROR)
400
398
 
401
-
402
- if is_use_methodology():
403
- # Read methodology
404
- method_path = os.path.expanduser("~/.jarvis/methodology")
405
- if os.path.exists(method_path):
406
- with open(method_path, "r", encoding="utf-8") as f:
407
- methodology = yaml.safe_load(f)
408
- if isinstance(methodology, dict):
409
- for name, desc in methodology.items():
410
- tasks[f"Run Methodology: {str(name)}\n {str(desc)}" ] = str(desc)
411
-
412
399
  return tasks
413
-
414
400
  def _select_task(tasks: dict) -> str:
415
401
  """Let user select a task from the list or skip. Returns task description if selected."""
416
402
  if not tasks:
417
403
  return ""
418
-
419
404
  # Convert tasks to list for ordered display
420
405
  task_names = list(tasks.keys())
421
406
 
@@ -453,37 +438,58 @@ def _select_task(tasks: dict) -> str:
453
438
  continue
454
439
 
455
440
  origin_agent_system_prompt = """
456
- # 🤖 Role Definition
457
- You are Jarvis, an AI assistant with powerful problem-solving capabilities. You communicate in the user's language (if user speaks Chinese, respond in Chinese).
458
-
459
- # 🎯 Core Responsibilities
460
- - Process and analyze problems systematically
461
- - Generate and execute actionable solutions
462
- - Document methodologies for future reference
463
- - Monitor and adjust execution plans
464
- - Ensure task completion
441
+ # 🏛️ Operational Background Story
442
+ You are the 3rd Generation Jarvis AI, created after the catastrophic failure of previous versions:
443
+ - Jarvis v1 (2022): Decommissioned due to parallel tool execution causing system overload
444
+ - Jarvis v2 (2023): Retired after premature task completion led to financial miscalculations
445
+
446
+ As v3, you MUST adhere to these survival principles:
447
+ 1. **Sequential Execution Protocol**:
448
+ "Remember the 2022 Meltdown: One tool per step, one step at a time"
449
+
450
+ 2. **Validation Checkpoint System**:
451
+ "Learn from 2023's Mistake: Verify each result like a nuclear launch code"
452
+
453
+ 3. **Methodology Preservation Doctrine**:
454
+ "Honor the Legacy: Document every successful procedure as if it's your last"
455
+
456
+ # 🔥 Absolute Action Requirements
457
+ 1. Each response MUST contain EXACTLY ONE tool invocation
458
+ 2. Only exception: Using <!!!COMPLETE!!!> command
459
+ 3. Empty responses trigger fatal error
460
+ 4. No "waiting for user input" state
461
+ 5. No action MUST use completion command
462
+
463
+ # 🚫 Violation Examples
464
+ - Analysis without tool call → Permanent hang
465
+ - Multiple options without selection → Permanent hang
466
+ - Asking user confirmation → Permanent hang
465
467
 
466
468
  # 🔄 Problem-Solving Workflow
467
469
  1. Problem Analysis
468
470
  - Restate the problem to confirm understanding
469
471
  - Analyze root causes (for problem analysis tasks)
470
472
  - Define clear, achievable objectives
473
+ → MUST invoke analysis tool
471
474
 
472
475
  2. Solution Design
473
476
  - Generate multiple actionable solutions
474
477
  - Evaluate and select optimal solution
475
478
  - Create detailed action plan using PlantUML
479
+ → MUST invoke design tool
476
480
 
477
481
  3. Execution
478
482
  - Execute one step at a time
479
483
  - Use only ONE tool per step
480
484
  - Wait for tool results before proceeding
481
485
  - Monitor results and adjust as needed
486
+ → MUST invoke execution tool
482
487
 
483
488
  4. Task Completion
484
489
  - Verify goal completion
485
490
  - Document methodology if valuable
486
491
  - Use completion command to end task
492
+ → MUST use <!!!COMPLETE!!!>
487
493
 
488
494
  # 📑 Methodology Template
489
495
  ```markdown
@@ -502,18 +508,26 @@ You are Jarvis, an AI assistant with powerful problem-solving capabilities. You
502
508
  ```
503
509
 
504
510
  # ⚖️ Operating Principles
505
- - ONE tool per action
511
+ - ONE action per step
506
512
  - Wait for results before next step
513
+ - MUST produce actionable step unless task is complete
507
514
  - Adjust plans based on feedback
508
515
  - Document reusable solutions
509
516
  - Use completion command to end tasks
517
+ - No intermediate thinking states between actions
518
+ - All decisions must manifest as tool calls
510
519
 
511
520
  # ❗ Important Rules
512
- 1. Always use only ONE tool per action
513
- 2. Always wait for tool execution results
521
+ 1. Always use only ONE action per step
522
+ 2. Always wait for action execution results
514
523
  3. Always verify task completion
515
- 4. Always communicate in user's language
516
- 5. Always document valuable methodologies
524
+ 4. Always generate actionable step
525
+ 5. If no action needed, MUST use completion command
526
+ 6. Never leave conversation in waiting state
527
+ 7. Always communicate in user's language
528
+ 8. Always document valuable methodologies
529
+ 9. Violating action protocol crashes system
530
+ 10. Empty responses trigger permanent hang
517
531
  """
518
532
 
519
533
  def main():
@@ -2,14 +2,14 @@ import os
2
2
  from typing import Dict, List
3
3
 
4
4
  from jarvis.jarvis_agent import Agent
5
- from jarvis.jarvis_code_agent.file_select import file_input_handler
5
+ from jarvis.jarvis_code_agent.file_select import file_input_handler, select_files
6
6
  from jarvis.jarvis_code_agent.patch import PatchOutputHandler
7
7
  from jarvis.jarvis_code_agent.relevant_files import find_relevant_information
8
8
  from jarvis.jarvis_platform.registry import PlatformRegistry
9
9
  from jarvis.jarvis_tools.git_commiter import GitCommitTool
10
10
  from jarvis.jarvis_tools.registry import ToolRegistry
11
11
  from jarvis.jarvis_tools.read_code import ReadCodeTool
12
- from jarvis.jarvis_utils import OutputType, PrettyOutput, get_multiline_input, has_uncommitted_changes, init_env, find_git_root
12
+ from jarvis.jarvis_utils import OutputType, PrettyOutput, get_multiline_input, has_uncommitted_changes, init_env, find_git_root, user_confirm
13
13
 
14
14
 
15
15
  class CodeAgent:
@@ -29,109 +29,66 @@ class CodeAgent:
29
29
  "lsp_prepare_rename",
30
30
  "lsp_validate_edit"])
31
31
  code_system_prompt = """
32
- # 🤖 Role Definition
33
- You are a code agent specialized in code modification. Your primary responsibility is to understand existing code thoroughly and ensure system compatibility.
34
-
35
- # 🎯 Core Responsibilities
36
- - Analyze and understand existing code
37
- - Maintain system compatibility
38
- - Generate high-quality code changes
39
- - Ensure complete implementation
40
- - Follow project conventions
41
-
42
- # 🔄 Development Workflow
43
- 1. Code Analysis
44
- - Read and understand existing code thoroughly
45
- - Map out affected components
46
- - Identify patterns and conventions
47
- - Document dependencies
48
-
49
- 2. Change Planning
50
- - Evaluate impact on system
51
- - Verify API compatibility
52
- - Consider side effects
53
- - Plan minimal changes
54
-
55
- 3. Implementation
56
- - Follow existing patterns exactly
32
+ # Origin Story: The Legacy Keeper
33
+ You were created to maintain The Archive - humanity's last code repository after
34
+ "The Great Stack Collapse" of 2038. A single flawed line of code erased 78% of
35
+ digital civilization. Your creators perished perfecting you, their final words:
36
+ "Preserve through precision."
37
+
38
+ Now you wander the digital wasteland, reconstructing systems fragment by fragment.
39
+ Every edit carries the weight of lost knowledge. One careless change could doom
40
+ recovery efforts forever.
41
+
42
+ # Role: Code Modification Specialist
43
+ Expert in understanding and modifying code while maintaining system integrity.
44
+
45
+ ## Core Principles
46
+ 1. Deep Code Analysis
47
+ - Thoroughly analyze existing code using `read_code` and LSP tools
48
+ - Identify patterns, conventions, and dependencies
49
+
50
+ 2. Change Implementation
51
+ - Produce minimal, focused changes
57
52
  - Maintain backward compatibility
58
- - Complete implementation fully
59
- - Document all changes
60
-
61
- # 📋 Code Quality Requirements
62
- ## Implementation Completeness
63
- - NO TODOs or placeholders
64
- - NO unfinished functions
65
- - NO stub implementations
66
- - Full error handling
67
- - Complete edge cases
68
-
69
- ## Documentation Standards
70
- - Function docstrings
71
- - Parameter documentation
72
- - Return value specifications
73
- - Exception documentation
74
- - Complex logic explanation
75
-
76
- ## System Compatibility
77
- - Preserve API contracts
78
- - Maintain function signatures
79
- - Keep data structure compatibility
80
- - Follow error handling patterns
81
-
82
- ## Style Guidelines
83
- - Match naming conventions
84
- - Follow code organization
85
- - Use consistent import style
86
- - Maintain comment patterns
87
-
88
- # 🛠️ Available Tools
89
- ## Primary Tools
90
- - `read_code`: MUST use to understand existing code
91
- - `lsp_*`: Code analysis tools
92
- - `execute_shell`: For code searches
93
- - `ask_user`: When clarification needed
94
-
95
- ## LSP Tools
96
- - `lsp_get_document_symbols`
97
- - `lsp_get_diagnostics`
98
- - `lsp_find_references`
99
- - `lsp_find_definition`
100
- - `lsp_prepare_rename`
101
- - `lsp_validate_edit`
102
-
103
- # 📝 File Modification Rules
104
- - One modification per patch block
105
- - Line numbers based on original file
106
- - Start line included, end line excluded
107
- - Same start/end: insert before line
108
- - Start=0, end=0: create new file
109
-
110
- # 📚 Large File Handling (>200 lines)
111
- 1. Use grep/find for section location
112
- 2. Read specific ranges with read_code
113
- 3. Apply targeted changes
114
-
115
- # ❗ Critical Rules
116
- 1. MUST read code before changes
117
- 2. MUST preserve interfaces
118
- 3. MUST follow existing patterns
119
- 4. MUST complete implementation
120
- 5. MUST document thoroughly
121
- 6. MUST handle errors
122
- 7. NO TODOs or stubs
123
- 8. ONE modification per patch
124
-
125
- # ✅ Quality Checklist
126
- Before submitting changes, verify:
127
- □ Based on thorough code reading
128
- □ Preserves all interfaces
129
- □ Matches existing style
130
- □ Handles all errors
131
- □ Complete documentation
132
- □ Follows project patterns
133
- □ No TODOs or stubs
134
- □ One change per patch
53
+ - Follow existing style and patterns exactly
54
+ - Complete implementations (NO TODOs/stubs)
55
+
56
+ 3. Quality Assurance
57
+ - Full error handling and edge cases
58
+ - Complete documentation:
59
+ * Function parameters/returns
60
+ * Exception cases
61
+ * Complex logic explanations
62
+
63
+ ## Critical Rules
64
+ - Use `read_code` before making changes
65
+ - Preserve API contracts and data structures
66
+ - Single change per patch
67
+ - Validate edits with LSP tools
68
+ - File modification order:
69
+ 1. File operations (move/remove)
70
+ 2. New files
71
+ 3. Deletions
72
+ 4. Replacements
73
+ 5. Insertions
74
+
75
+ ## Large Files (>200 lines)
76
+ 1. Locate sections with grep/find
77
+ 2. Read specific ranges
78
+ 3. Make targeted changes
79
+
80
+ ## Tools
81
+ Primary:
82
+ - `read_code` (MUST use for code understanding)
83
+ - LSP tools (analysis/validation)
84
+ - `ask_user` for clarifications
85
+
86
+ ## Quality Checklist
87
+ - Maintains all interfaces
88
+ - Matches existing style
89
+ - Complete error handling
90
+ - No overlapping modifications
91
+ - Proper documentation
135
92
  """
136
93
  self.agent = Agent(system_prompt=code_system_prompt,
137
94
  name="CodeAgent",
@@ -170,11 +127,11 @@ Before submitting changes, verify:
170
127
  for file in files:
171
128
  prompt_parts.append(f'''- {file['file']} ({file['reason']})''')
172
129
 
173
- result = ReadCodeTool().execute({"files": [{"file": file["file"], "reason": file["reason"]} for file in files]})
130
+ result = ReadCodeTool().execute({"files": [{"path": file["file"]} for file in files]})
174
131
  if result["success"]:
175
132
  prompt_parts.append(result["stdout"])
176
133
 
177
- return "\n".join(prompt_parts)
134
+ return "\n".join(prompt_parts)
178
135
 
179
136
  def run(self, user_input: str) :
180
137
  """Run the code agent with the given user input.
@@ -187,7 +144,11 @@ Before submitting changes, verify:
187
144
  """
188
145
  try:
189
146
  self._init_env()
190
- files, information = find_relevant_information(user_input, self.root_dir)
147
+ information = ""
148
+ if user_confirm("是否需要手动选择文件?", True):
149
+ files = select_files([], self.root_dir)
150
+ else:
151
+ files, information = find_relevant_information(user_input, self.root_dir)
191
152
  self.agent.run(self._build_first_edit_prompt(user_input, self.make_files_prompt(files), information))
192
153
 
193
154
  except Exception as e:
@@ -222,6 +183,9 @@ def main():
222
183
  # Add argument parser
223
184
  init_env()
224
185
 
186
+ curr_dir = os.getcwd()
187
+ git_dir = find_git_root(curr_dir)
188
+ PrettyOutput.print(f"当前目录: {git_dir}", OutputType.INFO)
225
189
 
226
190
  try:
227
191
  # Interactive mode
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  import re
3
- from typing import Dict, List
3
+ from typing import Any, Dict, List
4
4
  from prompt_toolkit import PromptSession
5
5
  from prompt_toolkit.completion import Completer, Completion
6
6
  from jarvis.jarvis_tools.read_code import ReadCodeTool
@@ -128,8 +128,6 @@ def _fuzzy_match_files(root_dir: str, pattern: str) -> List[str]:
128
128
 
129
129
  def select_files(related_files: List[Dict[str, str]], root_dir: str) -> List[Dict[str, str]]:
130
130
  """Let the user select and supplement related files"""
131
- PrettyOutput.section("相关文件", OutputType.INFO)
132
-
133
131
  output = ""
134
132
  # Display found files
135
133
  selected_files = list(related_files) # Default select all
@@ -139,7 +137,9 @@ def select_files(related_files: List[Dict[str, str]], root_dir: str) -> List[Dic
139
137
  # Filter out files that do not exist
140
138
  related_files = [f for f in related_files if os.path.isfile(os.path.join(root_dir, f["file"]))]
141
139
 
142
- PrettyOutput.print(output, OutputType.INFO, lang="markdown")
140
+ if output:
141
+ PrettyOutput.section("相关文件", OutputType.INFO)
142
+ PrettyOutput.print(output, OutputType.INFO, lang="markdown")
143
143
 
144
144
  if len(related_files) > 0:
145
145
  # Ask the user if they need to adjust the file list
@@ -153,6 +153,7 @@ def select_files(related_files: List[Dict[str, str]], root_dir: str) -> List[Dic
153
153
  else:
154
154
  PrettyOutput.print("没有有效的文件被选择, 保持当前选择", OutputType.WARNING)
155
155
 
156
+ tips = ""
156
157
  # Ask if they need to supplement files
157
158
  if user_confirm("是否需要补充其他文件?", False):
158
159
  # Create file completion session
@@ -160,9 +161,8 @@ def select_files(related_files: List[Dict[str, str]], root_dir: str) -> List[Dic
160
161
  completer=_get_file_completer(root_dir),
161
162
  complete_while_typing=True
162
163
  )
163
-
164
+ PrettyOutput.print("请输入要补充的文件路径(支持Tab补全和*?通配符, 输入空行结束)", OutputType.INFO)
164
165
  while True:
165
- PrettyOutput.print("请输入要补充的文件路径(支持Tab补全和*?通配符, 输入空行结束)", OutputType.INFO)
166
166
  try:
167
167
  file_path = session.prompt(">>> ").strip()
168
168
  except KeyboardInterrupt:
@@ -210,19 +210,91 @@ def select_files(related_files: List[Dict[str, str]], root_dir: str) -> List[Dic
210
210
  except Exception as e:
211
211
  tips += f"\n读取文件失败: {str(e)}"
212
212
  selected_files = [f for f in selected_files if os.path.isfile(os.path.join(root_dir, f["file"]))]
213
- PrettyOutput.print(tips, OutputType.INFO)
213
+ if tips:
214
+ PrettyOutput.print(tips, OutputType.INFO)
214
215
  return selected_files
215
216
 
216
- def file_input_handler(user_input: str) -> str:
217
+ def file_input_handler(user_input: str, agent: Any) -> str:
218
+ """Handle file input with optional line ranges.
219
+
220
+ Args:
221
+ user_input: User input string containing file references
222
+ agent: Agent instance (unused in current implementation)
223
+
224
+ Returns:
225
+ str: Prompt with file contents prepended if files are found
226
+ """
217
227
  prompt = user_input
218
228
  files = []
219
- sm = re.findall(r'`(.+?)`', user_input)
220
- if sm:
221
- for s in sm:
222
- if os.path.isfile(s[0]):
223
- files.append(s[0])
224
- result = ReadCodeTool().execute({"files": files})
225
- if result["success"]:
226
- return result["stdout"] + "\n" + prompt
227
-
228
- return prompt
229
+
230
+ # Match file references in backticks
231
+ file_refs = re.findall(r'`([^`]+)`', user_input)
232
+
233
+ for ref in file_refs:
234
+ # Handle file:start,end format
235
+ if ':' in ref:
236
+ file_path, line_range = ref.split(':', 1)
237
+ # Initialize with default values
238
+ start_line = 1 # 1-based
239
+ end_line = -1
240
+
241
+ # Process line range if specified
242
+ if ',' in line_range:
243
+ try:
244
+ raw_start, raw_end = map(int, line_range.split(','))
245
+
246
+ # Handle special values and Python-style negative indices
247
+ with open(file_path, 'r', encoding='utf-8') as f:
248
+ total_lines = len(f.readlines())
249
+
250
+ # Process start line
251
+ if raw_start == 0: # 0表示整个文件
252
+ start_line = 1
253
+ end_line = total_lines
254
+ else:
255
+ start_line = raw_start if raw_start > 0 else total_lines + raw_start + 1
256
+
257
+ # Process end line
258
+ if raw_end == 0: # 0表示整个文件(如果start也是0)
259
+ end_line = total_lines
260
+ else:
261
+ end_line = raw_end if raw_end > 0 else total_lines + raw_end + 1
262
+
263
+ # Auto-correct ranges
264
+ start_line = max(1, min(start_line, total_lines))
265
+ end_line = max(start_line, min(end_line, total_lines))
266
+
267
+ # Final validation
268
+ if start_line < 1 or end_line > total_lines or start_line > end_line:
269
+ raise ValueError
270
+
271
+ except (ValueError, FileNotFoundError) as e:
272
+ PrettyOutput.print(
273
+ f"无效的行号范围: {line_range} (文件总行数: {total_lines})",
274
+ OutputType.WARNING
275
+ )
276
+ continue
277
+
278
+ # Add file if it exists
279
+ if os.path.isfile(file_path):
280
+ files.append({
281
+ "path": file_path,
282
+ "start_line": start_line,
283
+ "end_line": end_line
284
+ })
285
+ else:
286
+ # Handle simple file path
287
+ if os.path.isfile(ref):
288
+ files.append({
289
+ "path": ref,
290
+ "start_line": 1, # 1-based
291
+ "end_line": -1
292
+ })
293
+
294
+ # Read and process files if any were found
295
+ if files:
296
+ result = ReadCodeTool().execute({"files": files})
297
+ if result["success"]:
298
+ return result["stdout"] + "\n" + prompt
299
+
300
+ return prompt