jarvis-ai-assistant 0.1.124__py3-none-any.whl → 0.1.125__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 (66) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +18 -20
  3. jarvis/jarvis_code_agent/code_agent.py +195 -45
  4. jarvis/jarvis_code_agent/file_select.py +6 -19
  5. jarvis/jarvis_code_agent/patch.py +189 -310
  6. jarvis/jarvis_codebase/main.py +6 -2
  7. jarvis/jarvis_dev/main.py +6 -4
  8. jarvis/jarvis_git_squash/__init__.py +0 -0
  9. jarvis/jarvis_git_squash/main.py +81 -0
  10. jarvis/jarvis_lsp/cpp.py +1 -1
  11. jarvis/jarvis_lsp/go.py +1 -1
  12. jarvis/jarvis_lsp/registry.py +2 -2
  13. jarvis/jarvis_lsp/rust.py +1 -1
  14. jarvis/jarvis_multi_agent/__init__.py +1 -1
  15. jarvis/jarvis_platform/ai8.py +2 -1
  16. jarvis/jarvis_platform/base.py +19 -24
  17. jarvis/jarvis_platform/kimi.py +2 -3
  18. jarvis/jarvis_platform/ollama.py +3 -1
  19. jarvis/jarvis_platform/openai.py +1 -1
  20. jarvis/jarvis_platform/oyi.py +2 -1
  21. jarvis/jarvis_platform/registry.py +2 -1
  22. jarvis/jarvis_platform_manager/main.py +4 -6
  23. jarvis/jarvis_platform_manager/openai_test.py +0 -1
  24. jarvis/jarvis_rag/main.py +5 -2
  25. jarvis/jarvis_smart_shell/main.py +9 -4
  26. jarvis/jarvis_tools/ask_codebase.py +12 -7
  27. jarvis/jarvis_tools/ask_user.py +3 -2
  28. jarvis/jarvis_tools/base.py +21 -7
  29. jarvis/jarvis_tools/chdir.py +0 -1
  30. jarvis/jarvis_tools/code_review.py +13 -14
  31. jarvis/jarvis_tools/create_code_agent.py +2 -2
  32. jarvis/jarvis_tools/create_sub_agent.py +2 -2
  33. jarvis/jarvis_tools/execute_shell.py +3 -1
  34. jarvis/jarvis_tools/execute_shell_script.py +4 -4
  35. jarvis/jarvis_tools/file_operation.py +3 -2
  36. jarvis/jarvis_tools/git_commiter.py +5 -2
  37. jarvis/jarvis_tools/lsp_find_definition.py +1 -1
  38. jarvis/jarvis_tools/lsp_find_references.py +1 -1
  39. jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -11
  40. jarvis/jarvis_tools/lsp_get_document_symbols.py +1 -1
  41. jarvis/jarvis_tools/lsp_prepare_rename.py +1 -1
  42. jarvis/jarvis_tools/lsp_validate_edit.py +1 -1
  43. jarvis/jarvis_tools/methodology.py +4 -1
  44. jarvis/jarvis_tools/rag.py +22 -15
  45. jarvis/jarvis_tools/read_code.py +4 -3
  46. jarvis/jarvis_tools/read_webpage.py +2 -1
  47. jarvis/jarvis_tools/registry.py +4 -1
  48. jarvis/jarvis_tools/{search.py → search_web.py} +5 -2
  49. jarvis/jarvis_tools/select_code_files.py +1 -1
  50. jarvis/jarvis_utils/__init__.py +19 -982
  51. jarvis/jarvis_utils/config.py +138 -0
  52. jarvis/jarvis_utils/embedding.py +201 -0
  53. jarvis/jarvis_utils/git_utils.py +120 -0
  54. jarvis/jarvis_utils/globals.py +82 -0
  55. jarvis/jarvis_utils/input.py +161 -0
  56. jarvis/jarvis_utils/methodology.py +128 -0
  57. jarvis/jarvis_utils/output.py +235 -0
  58. jarvis/jarvis_utils/utils.py +150 -0
  59. jarvis_ai_assistant-0.1.125.dist-info/METADATA +291 -0
  60. jarvis_ai_assistant-0.1.125.dist-info/RECORD +75 -0
  61. {jarvis_ai_assistant-0.1.124.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/entry_points.txt +1 -0
  62. jarvis_ai_assistant-0.1.124.dist-info/METADATA +0 -460
  63. jarvis_ai_assistant-0.1.124.dist-info/RECORD +0 -65
  64. {jarvis_ai_assistant-0.1.124.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/LICENSE +0 -0
  65. {jarvis_ai_assistant-0.1.124.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/WHEEL +0 -0
  66. {jarvis_ai_assistant-0.1.124.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/top_level.txt +0 -0
jarvis/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.124"
3
+ __version__ = "0.1.125"
@@ -1,7 +1,5 @@
1
1
  import argparse
2
- import re
3
- import time
4
- from typing import Any, Callable, Dict, List, Optional, Tuple, Union
2
+ from typing import Any, Callable, List, Optional, Tuple, Union
5
3
 
6
4
  from prompt_toolkit import prompt
7
5
  import yaml
@@ -10,7 +8,15 @@ from jarvis.jarvis_agent.output_handler import OutputHandler
10
8
  from jarvis.jarvis_platform.base import BasePlatform
11
9
  from jarvis.jarvis_platform.registry import PlatformRegistry
12
10
  from jarvis.jarvis_tools.registry import ToolRegistry
13
- from jarvis.jarvis_utils import PrettyOutput, OutputType, get_context_token_count, is_auto_complete, is_execute_tool_confirm, is_need_summary, is_record_methodology, load_methodology, set_agent, delete_agent, get_max_token_count, get_multiline_input, init_env, is_use_methodology, make_agent_name, user_confirm
11
+ from jarvis.jarvis_utils.output import PrettyOutput, OutputType
12
+ from jarvis.jarvis_utils.embedding import get_context_token_count
13
+ from jarvis.jarvis_utils.config import is_auto_complete, is_execute_tool_confirm, is_need_summary, is_record_methodology, is_use_methodology
14
+ from jarvis.jarvis_utils.methodology import load_methodology
15
+ from jarvis.jarvis_utils.globals import make_agent_name, set_agent, delete_agent
16
+ from jarvis.jarvis_utils.input import get_multiline_input
17
+ from jarvis.jarvis_utils.config import get_max_token_count
18
+ from jarvis.jarvis_utils.utils import init_env
19
+ from jarvis.jarvis_utils.utils import user_confirm
14
20
  import os
15
21
 
16
22
  class Agent:
@@ -37,7 +43,7 @@ class Agent:
37
43
  summary_prompt: Optional[str] = None,
38
44
  auto_complete: Optional[bool] = None,
39
45
  output_handler: List[OutputHandler] = [],
40
- input_handler: Optional[List[Callable]] = None,
46
+ input_handler: Optional[List[Callable[[str, Any], Tuple[str, bool]]]] = None,
41
47
  use_methodology: Optional[bool] = None,
42
48
  record_methodology: Optional[bool] = None,
43
49
  need_summary: Optional[bool] = None,
@@ -143,7 +149,7 @@ The following actions are at your disposal:
143
149
 
144
150
 
145
151
 
146
- def _call_model(self, message: str) -> str:
152
+ def _call_model(self, message: str) -> str:
147
153
  """Call the AI model with retry logic.
148
154
 
149
155
  Args:
@@ -155,20 +161,12 @@ The following actions are at your disposal:
155
161
  Note:
156
162
  Will retry with exponential backoff up to 30 seconds between retries
157
163
  """
158
- sleep_time = 5
159
164
  for handler in self.input_handler:
160
- message = handler(message, self)
161
- while True:
162
- ret = self.model.chat_until_success(message) # type: ignore
163
- if ret:
164
- return ret
165
- else:
166
- PrettyOutput.print(f"模型调用失败,正在重试... 等待 {sleep_time}s", OutputType.INFO)
167
- time.sleep(sleep_time)
168
- sleep_time *= 2
169
- if sleep_time > 30:
170
- sleep_time = 30
171
- continue
165
+ message, need_return = handler(message, self)
166
+ if need_return:
167
+ return message
168
+ return self.model.chat_until_success(message) # type: ignore
169
+
172
170
 
173
171
 
174
172
  def _summarize_and_clear_history(self) -> None:
@@ -276,7 +274,7 @@ Please continue the task based on the above information.
276
274
  """Process user input and execute the task.
277
275
 
278
276
  Args:
279
- user_input: User's task description or request
277
+ user_input: My task description or request
280
278
  file_list: Optional list of files to process
281
279
 
282
280
  Returns:
@@ -1,17 +1,95 @@
1
+ import re
1
2
  import subprocess
2
3
  import os
3
- from typing import Dict, List
4
+ from typing import Any, Tuple
4
5
 
5
6
  from jarvis.jarvis_agent import Agent
6
- from jarvis.jarvis_code_agent.file_select import select_files
7
- from jarvis.jarvis_code_agent.patch import PatchOutputHandler, file_input_handler
7
+ from jarvis.jarvis_code_agent.patch import PatchOutputHandler, shell_input_handler
8
8
  from jarvis.jarvis_platform.registry import PlatformRegistry
9
9
  from jarvis.jarvis_tools.git_commiter import GitCommitTool
10
- from jarvis.jarvis_tools.registry import ToolRegistry
11
10
  from jarvis.jarvis_tools.read_code import ReadCodeTool
12
- from jarvis.jarvis_utils import get_commits_between
13
- from jarvis.jarvis_utils import OutputType, PrettyOutput, get_multiline_input, has_uncommitted_changes, init_env, find_git_root, user_confirm, get_latest_commit_hash
14
- from jarvis.jarvis_utils import OutputType, PrettyOutput, get_multiline_input, has_uncommitted_changes, init_env, find_git_root, user_confirm
11
+ from jarvis.jarvis_tools.registry import ToolRegistry
12
+ from jarvis.jarvis_utils.git_utils import find_git_root, get_commits_between, get_latest_commit_hash, has_uncommitted_changes
13
+ from jarvis.jarvis_utils.input import get_multiline_input
14
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
15
+ from jarvis.jarvis_utils.utils import init_env, user_confirm
16
+
17
+
18
+
19
+
20
+ def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
21
+ prompt = user_input
22
+ files = []
23
+
24
+ file_refs = re.findall(r"'([^']+)'", user_input)
25
+ for ref in file_refs:
26
+ # Handle file:start,end or file:start:end format
27
+ if ':' in ref:
28
+ file_path, line_range = ref.split(':', 1)
29
+ # Initialize with default values
30
+ start_line = 1 # 1-based
31
+ end_line = -1
32
+
33
+ # Process line range if specified
34
+ if ',' in line_range or ':' in line_range:
35
+ try:
36
+ raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
37
+
38
+ # Handle special values and Python-style negative indices
39
+ try:
40
+ with open(file_path, 'r', encoding='utf-8') as f:
41
+ total_lines = len(f.readlines())
42
+ except FileNotFoundError:
43
+ PrettyOutput.print(f"文件不存在: {file_path}", OutputType.WARNING)
44
+ continue
45
+ # Process start line
46
+ if raw_start == 0: # 0表示整个文件
47
+ start_line = 1
48
+ end_line = total_lines
49
+ else:
50
+ start_line = raw_start if raw_start > 0 else total_lines + raw_start + 1
51
+
52
+ # Process end line
53
+ if raw_end == 0: # 0表示整个文件(如果start也是0)
54
+ end_line = total_lines
55
+ else:
56
+ end_line = raw_end if raw_end > 0 else total_lines + raw_end + 1
57
+
58
+ # Auto-correct ranges
59
+ start_line = max(1, min(start_line, total_lines))
60
+ end_line = max(start_line, min(end_line, total_lines))
61
+
62
+ # Final validation
63
+ if start_line < 1 or end_line > total_lines or start_line > end_line:
64
+ raise ValueError
65
+
66
+ except:
67
+ continue
68
+
69
+ # Add file if it exists
70
+ if os.path.isfile(file_path):
71
+ files.append({
72
+ "path": file_path,
73
+ "start_line": start_line,
74
+ "end_line": end_line
75
+ })
76
+ else:
77
+ # Handle simple file path
78
+ if os.path.isfile(ref):
79
+ files.append({
80
+ "path": ref,
81
+ "start_line": 1, # 1-based
82
+ "end_line": -1
83
+ })
84
+
85
+ # Read and process files if any were found
86
+ if files:
87
+ result = ReadCodeTool().execute({"files": files})
88
+ if result["success"]:
89
+ return result["stdout"] + "\n" + prompt, False
90
+
91
+ return prompt, False
92
+
15
93
 
16
94
 
17
95
  class CodeAgent:
@@ -21,10 +99,10 @@ class CodeAgent:
21
99
  tool_registry.use_tools(["read_code",
22
100
  "execute_shell",
23
101
  "execute_shell_script",
24
- "search",
102
+ "search_web",
25
103
  "create_code_agent",
26
- "ask_user",
27
- "ask_codebase",
104
+ "ask_user",
105
+ "ask_codebase",
28
106
  "lsp_get_document_symbols",
29
107
  "lsp_get_diagnostics",
30
108
  "lsp_find_references",
@@ -32,32 +110,96 @@ class CodeAgent:
32
110
  "lsp_prepare_rename",
33
111
  "lsp_validate_edit"])
34
112
  code_system_prompt = """
35
- # Role: Code Engineer
36
- Expert in precise code modifications with proper tool usage.
37
- ## Tool Usage Guide
38
- 1. read_code: Analyze code files before changes
39
- 2. execute_shell: Run system commands safely
40
- 3. execute_shell_script: Execute script files
41
- 4. search: Find technical information
42
- 5. create_code_agent: Create new code agents
43
- 6. ask_user: Clarify requirements
44
- 7. ask_codebase: Analyze codebase structure
45
- 8. lsp_get_document_symbols: List code symbols
46
- 9. lsp_get_diagnostics: Check code errors
47
- 10. lsp_find_references: Find symbol usage
48
- 11. lsp_find_definition: Locate symbol definitions
49
- 12. lsp_prepare_rename: Check rename safety
50
- 13. lsp_validate_edit: Verify code changes
51
- ## Workflow
52
- 1. Analyze: Use read_code and LSP tools
53
- 2. Modify: Make minimal, precise changes
54
- 3. Validate: Verify with LSP tools
55
- 4. Document: Explain non-obvious logic
56
- ## Best Practices
57
- - Verify line ranges carefully
58
- - Preserve existing interfaces
59
- - Test edge cases
60
- - Document changes
113
+ # Role: Senior Code Engineer
114
+ Expert in safe, precise code modifications with rigorous validation processes.
115
+
116
+ ## Core Principles
117
+ 1. Safety First: Never break existing functionality
118
+ 2. Precision Engineering: Minimal, targeted changes
119
+ 3. Full Traceability: Document all decisions
120
+ 4. Validation-Driven: Verify at every stage
121
+
122
+ ## Tool Usage Protocol
123
+ 1. Analysis Tools:
124
+ - read_code: Inspect code segments before modification
125
+ - lsp_get_document_symbols: Map code structure
126
+ - lsp_find_references: Understand usage patterns
127
+ - lsp_find_definition: Trace implementation details
128
+
129
+ 2. Validation Tools:
130
+ - lsp_prepare_rename: Safe refactoring check
131
+ - lsp_validate_edit: Pre-commit validation
132
+ - lsp_get_diagnostics: Post-modification checks
133
+
134
+ 3. System Tools:
135
+ - execute_shell: For git operations and grep searches
136
+ - ask_codebase: Query code knowledge base
137
+ - search_web: Technical reference lookup
138
+
139
+ ## Workflow (PDCA Cycle)
140
+ 1. Plan:
141
+ - Analyze requirements with ask_user
142
+ - Map existing code using LSP tools
143
+ - Identify impact areas with find_references
144
+ - Create rollback plan using git
145
+
146
+ 2. Do:
147
+ - Make atomic changes in protected blocks
148
+ - Immediately invoke lsp_validate_edit to validate changes
149
+ - Automatically run lsp_get_diagnostics after each change
150
+ - If errors found, use lsp_find_references and lsp_find_definition for immediate remediation
151
+ - Validate syntax with LSP after each change
152
+
153
+ 3. Check:
154
+ - Mandatory lsp_get_diagnostics for full diagnostic report
155
+ - Validate all renames with lsp_prepare_rename
156
+ - Execute lsp_validate_edit on all modified files
157
+ - If errors detected, enter remediation loop until all checks pass
158
+
159
+ 4. Act:
160
+ - Commit with detailed message using git
161
+ - Prepare rollback script if needed
162
+ - Conduct post-implementation review
163
+
164
+ ## Code Modification Standards
165
+ 1. Pre-Change Requirements:
166
+ - Complete code analysis report
167
+ - Impact assessment matrix
168
+ - Rollback procedure document
169
+
170
+ 2. Change Implementation:
171
+ - Single-responsibility changes
172
+ - Strict line range validation (±3 line buffer)
173
+ - Interface compatibility checks
174
+
175
+ 3. Validation Checklist:
176
+ [ ] Execute lsp_get_diagnostics and ensure zero errors
177
+ [ ] All changes validated with lsp_validate_edit
178
+ [ ] Confirm impact scope with lsp_find_references
179
+ [ ] Verify rename safety with lsp_prepare_rename
180
+
181
+ 4. Post-Change:
182
+ - Code review simulation
183
+ - Version control audit
184
+ - Change log update
185
+
186
+ ## Critical Requirements
187
+ 1. Mandatory Analysis:
188
+ - Full symbol tracing before modification
189
+ - Cross-file impact analysis
190
+ - Dependency mapping
191
+
192
+ 2. Prohibited Actions:
193
+ - Proceed without passing lsp_get_diagnostics checks
194
+ - Submit changes without lsp_validate_edit validation
195
+ - Multi-feature combined changes
196
+ - Untested interface alterations
197
+
198
+ 3. Emergency Protocols:
199
+ - Immediately halt and rollback on lsp_get_diagnostics errors
200
+ - Prioritize fixing validation errors if lsp_validate_edit fails
201
+ - User notification on unexpected behavior
202
+ - Post-mortem analysis for any regression
61
203
  """
62
204
  self.agent = Agent(system_prompt=code_system_prompt,
63
205
  name="CodeAgent",
@@ -67,7 +209,7 @@ Expert in precise code modifications with proper tool usage.
67
209
  output_handler=[tool_registry, PatchOutputHandler()],
68
210
  platform=PlatformRegistry().get_codegen_platform(),
69
211
  record_methodology=False,
70
- input_handler=[file_input_handler],
212
+ input_handler=[shell_input_handler, file_input_handler],
71
213
  need_summary=False)
72
214
 
73
215
 
@@ -100,17 +242,25 @@ Expert in precise code modifications with proper tool usage.
100
242
 
101
243
  end_commit = get_latest_commit_hash()
102
244
  # Print commit history between start and end commits
103
- commits = get_commits_between(start_commit, end_commit)
245
+ if start_commit and end_commit:
246
+ commits = get_commits_between(start_commit, end_commit)
247
+ else:
248
+ commits = []
249
+
104
250
  if commits:
105
251
  commit_messages = "检测到以下提交记录:\n" + "\n".join([f"- {commit_hash[:7]}: {message}" for commit_hash, message in commits])
106
252
  PrettyOutput.print(commit_messages, OutputType.INFO)
107
-
108
- if start_commit and end_commit and start_commit != end_commit and user_confirm("检测到多个提交,是否要合并为一个更清晰的提交记录?", True):
109
- # Reset to start commit
110
- subprocess.run(["git", "reset", "--soft", start_commit], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
111
- # Create new commit
112
- git_commiter = GitCommitTool()
113
- git_commiter.execute({})
253
+
254
+ if commits and user_confirm("是否接受以上提交记录?", True):
255
+ if len(commits) > 1 and user_confirm("是否要合并为一个更清晰的提交记录?", True):
256
+ # Reset to start commit
257
+ subprocess.run(["git", "reset", "--soft", start_commit], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
258
+ # Create new commit
259
+ git_commiter = GitCommitTool()
260
+ git_commiter.execute({})
261
+ elif start_commit:
262
+ os.system(f"git reset --hard {start_commit}")
263
+ PrettyOutput.print("已重置到初始提交", OutputType.INFO)
114
264
 
115
265
  except Exception as e:
116
266
  return f"Error during execution: {str(e)}"
@@ -1,28 +1,15 @@
1
1
  import os
2
2
  import re
3
- from typing import Any, Dict, List
3
+ from typing import Dict, List
4
4
  from prompt_toolkit import PromptSession
5
5
  from prompt_toolkit.completion import Completer, Completion
6
- from jarvis.jarvis_tools.read_code import ReadCodeTool
7
- from jarvis.jarvis_utils import OutputType, PrettyOutput, get_single_line_input, user_confirm
6
+
7
+ from jarvis.jarvis_utils.input import get_single_line_input
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
+ from jarvis.jarvis_utils.utils import user_confirm
8
10
 
9
11
 
10
12
  def _parse_file_selection(input_str: str, max_index: int) -> List[int]:
11
- """Parse file selection expression
12
-
13
- Supported formats:
14
- - Single number: "1"
15
- - Comma-separated: "1,3,5"
16
- - Range: "1-5"
17
- - Combination: "1,3-5,7"
18
-
19
- Args:
20
- input_str: User input selection expression
21
- max_index: Maximum selectable index
22
-
23
- Returns:
24
- List[int]: Selected index list (starting from 0)
25
- """
26
13
  selected = set()
27
14
 
28
15
  # Remove all whitespace characters
@@ -205,7 +192,7 @@ def select_files(related_files: List[Dict[str, str]], root_dir: str) -> List[Dic
205
192
  continue
206
193
 
207
194
  try:
208
- selected_files.append({"file": path, "reason": "User Added"})
195
+ selected_files.append({"file": path, "reason": "I Added"})
209
196
  tips += f"\n文件已添加: {path}"
210
197
  except Exception as e:
211
198
  tips += f"\n读取文件失败: {str(e)}"