jarvis-ai-assistant 0.1.104__py3-none-any.whl → 0.1.105__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 (62) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +124 -67
  3. jarvis/jarvis_code_agent/code_agent.py +133 -22
  4. jarvis/jarvis_code_agent/patch.py +4 -7
  5. jarvis/jarvis_code_agent/relevant_files.py +163 -72
  6. jarvis/jarvis_codebase/main.py +36 -15
  7. jarvis/jarvis_lsp/base.py +143 -0
  8. jarvis/jarvis_lsp/cpp.py +134 -0
  9. jarvis/jarvis_lsp/go.py +140 -0
  10. jarvis/jarvis_lsp/python.py +135 -0
  11. jarvis/jarvis_lsp/registry.py +234 -0
  12. jarvis/jarvis_lsp/rust.py +142 -0
  13. jarvis/jarvis_platform/__init__.py +3 -0
  14. jarvis/{models → jarvis_platform}/ai8.py +1 -1
  15. jarvis/{models → jarvis_platform}/kimi.py +1 -1
  16. jarvis/{models → jarvis_platform}/ollama.py +1 -1
  17. jarvis/{models → jarvis_platform}/openai.py +1 -1
  18. jarvis/{models → jarvis_platform}/oyi.py +1 -1
  19. jarvis/{models → jarvis_platform}/registry.py +11 -11
  20. jarvis/{jarvis_platform → jarvis_platform_manager}/main.py +1 -1
  21. jarvis/jarvis_rag/main.py +6 -6
  22. jarvis/jarvis_smart_shell/main.py +3 -3
  23. jarvis/jarvis_tools/__init__.py +0 -0
  24. jarvis/{tools → jarvis_tools}/ask_user.py +1 -1
  25. jarvis/{tools → jarvis_tools}/code_review.py +34 -8
  26. jarvis/jarvis_tools/create_code_agent.py +115 -0
  27. jarvis/{tools → jarvis_tools}/create_sub_agent.py +1 -1
  28. jarvis/jarvis_tools/deep_thinking.py +160 -0
  29. jarvis/jarvis_tools/deep_thinking_agent.py +146 -0
  30. jarvis/{tools → jarvis_tools}/git_commiter.py +2 -2
  31. jarvis/jarvis_tools/lsp_find_definition.py +134 -0
  32. jarvis/jarvis_tools/lsp_find_references.py +111 -0
  33. jarvis/jarvis_tools/lsp_get_diagnostics.py +121 -0
  34. jarvis/jarvis_tools/lsp_get_document_symbols.py +87 -0
  35. jarvis/jarvis_tools/lsp_prepare_rename.py +130 -0
  36. jarvis/jarvis_tools/lsp_validate_edit.py +141 -0
  37. jarvis/{tools → jarvis_tools}/methodology.py +6 -1
  38. jarvis/{tools → jarvis_tools}/registry.py +6 -5
  39. jarvis/{tools → jarvis_tools}/search.py +2 -2
  40. jarvis/utils.py +68 -25
  41. {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/METADATA +21 -10
  42. jarvis_ai_assistant-0.1.105.dist-info/RECORD +62 -0
  43. {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/entry_points.txt +4 -4
  44. jarvis/models/__init__.py +0 -3
  45. jarvis/tools/create_code_test_agent.py +0 -115
  46. jarvis/tools/create_ctags_agent.py +0 -164
  47. jarvis/tools/find_in_codebase.py +0 -78
  48. jarvis_ai_assistant-0.1.104.dist-info/RECORD +0 -50
  49. /jarvis/{models → jarvis_platform}/base.py +0 -0
  50. /jarvis/{tools → jarvis_platform_manager}/__init__.py +0 -0
  51. /jarvis/{tools → jarvis_tools}/ask_codebase.py +0 -0
  52. /jarvis/{tools → jarvis_tools}/base.py +0 -0
  53. /jarvis/{tools → jarvis_tools}/chdir.py +0 -0
  54. /jarvis/{tools → jarvis_tools}/execute_shell.py +0 -0
  55. /jarvis/{tools → jarvis_tools}/file_operation.py +0 -0
  56. /jarvis/{tools → jarvis_tools}/rag.py +0 -0
  57. /jarvis/{tools → jarvis_tools}/read_code.py +0 -0
  58. /jarvis/{tools → jarvis_tools}/read_webpage.py +0 -0
  59. /jarvis/{tools → jarvis_tools}/select_code_files.py +0 -0
  60. {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/LICENSE +0 -0
  61. {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.105.dist-info}/WHEEL +0 -0
  62. {jarvis_ai_assistant-0.1.104.dist-info → jarvis_ai_assistant-0.1.105.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.104"
3
+ __version__ = "0.1.105"
jarvis/agent.py CHANGED
@@ -5,22 +5,29 @@ from typing import Callable, Dict, List, Optional
5
5
  from prompt_toolkit import prompt
6
6
  import yaml
7
7
 
8
- from jarvis.models.base import BasePlatform
9
- from jarvis.models.registry import PlatformRegistry
10
- from jarvis.tools.registry import ToolRegistry, tool_call_help
11
- from jarvis.utils import PrettyOutput, OutputType, is_auto_complete, load_methodology, add_agent, delete_current_agent, get_max_context_length, get_multiline_input, init_env
8
+ from jarvis.jarvis_platform.base import BasePlatform
9
+ from jarvis.jarvis_platform.registry import PlatformRegistry
10
+ from jarvis.jarvis_tools.registry import ToolRegistry, tool_call_help
11
+ from jarvis.utils import PrettyOutput, OutputType, is_auto_complete, is_need_summary, is_record_methodology, load_methodology, add_agent, delete_current_agent, get_max_context_length, get_multiline_input, init_env, is_use_methodology
12
12
  import os
13
13
 
14
14
  class Agent:
15
15
 
16
- def __del__(self):
17
- delete_current_agent()
18
-
19
16
  def set_summary_prompt(self, summary_prompt: str):
17
+ """Set the summary prompt for task completion.
18
+
19
+ Args:
20
+ summary_prompt: The prompt template for generating task summaries
21
+ """
20
22
  self.summary_prompt = summary_prompt
21
23
 
22
- def set_output_filter(self, output_filter: List[Callable]):
23
- self.output_filter = output_filter
24
+ def set_output_handler_before_tool(self, handler: List[Callable]):
25
+ """Set handlers to process output before tool execution.
26
+
27
+ Args:
28
+ handler: List of callable functions to process output
29
+ """
30
+ self.output_handler_before_tool = handler
24
31
 
25
32
  def __init__(self,
26
33
  system_prompt: str,
@@ -29,35 +36,47 @@ class Agent:
29
36
  tool_registry: Optional[ToolRegistry] = None,
30
37
  platform: Optional[BasePlatform] = None,
31
38
  summary_prompt: Optional[str] = None,
32
- auto_complete: bool = False,
33
- record_methodology: bool = True,
34
- output_filter: Optional[List[Callable]] = None,
35
- need_summary: bool = True):
36
- """Initialize Agent with a model, optional tool registry and name
39
+ auto_complete: Optional[bool] = None,
40
+ output_handler_before_tool: Optional[List[Callable]] = None,
41
+ output_handler_after_tool: Optional[List[Callable]] = None,
42
+ use_methodology: Optional[bool] = None,
43
+ record_methodology: Optional[bool] = None,
44
+ need_summary: Optional[bool] = None,
45
+ max_context_length: Optional[int] = None):
46
+ """Initialize an Agent instance.
37
47
 
38
48
  Args:
39
- system_prompt: System prompt
40
- name: Agent name, default is "Jarvis"
41
- is_sub_agent: Whether it is a sub-agent, default is False
42
- tool_registry: Tool registry instance
43
- platform: Optional platform instance, default uses normal platform
49
+ system_prompt: The system prompt defining agent behavior
50
+ name: Agent name, defaults to "Jarvis"
51
+ is_sub_agent: Whether this is a sub-agent
52
+ tool_registry: Registry of available tools
53
+ platform: AI platform to use
54
+ summary_prompt: Template for generating summaries
55
+ auto_complete: Whether to enable auto-completion
56
+ output_handler_before_tool: Handlers to process output before tool execution
57
+ output_handler_after_tool: Handlers to process output after tool execution
58
+ use_methodology: Whether to use methodology
59
+ record_methodology: Whether to record methodology
60
+ need_summary: Whether to generate summaries
61
+ max_context_length: Maximum context length
44
62
  """
45
- add_agent(name)
46
63
  PrettyOutput.print(f"Welcome to Jarvis, your AI assistant, Initiating...", OutputType.SYSTEM)
47
64
  if platform is not None:
48
65
  self.model = platform
49
66
  else:
50
67
  self.model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
51
68
  self.tool_registry = tool_registry if tool_registry else ToolRegistry()
52
- self.record_methodology = record_methodology
69
+ self.record_methodology = record_methodology if record_methodology is not None else is_record_methodology()
70
+ self.use_methodology = use_methodology if use_methodology is not None else is_use_methodology()
53
71
  self.name = name
54
72
  self.is_sub_agent = is_sub_agent
55
73
  self.prompt = ""
56
74
  self.conversation_length = 0 # Use length counter instead
57
75
  self.system_prompt = system_prompt
58
- self.need_summary = need_summary
76
+ self.need_summary = need_summary if need_summary is not None else is_need_summary()
59
77
  # Load configuration from environment variables
60
- self.output_filter = output_filter if output_filter else []
78
+ self.output_handler_before_tool = output_handler_before_tool if output_handler_before_tool else []
79
+ self.output_handler_after_tool = output_handler_after_tool if output_handler_after_tool else []
61
80
 
62
81
  self.summary_prompt = summary_prompt if summary_prompt else f"""Please generate a concise summary report of the task execution, including:
63
82
 
@@ -70,28 +89,22 @@ class Agent:
70
89
  Please describe in concise bullet points, highlighting important information.
71
90
  """
72
91
 
73
- self.max_context_length = get_max_context_length()
74
-
75
- self.auto_complete = auto_complete
76
-
92
+ self.max_context_length = max_context_length if max_context_length is not None else get_max_context_length()
77
93
 
78
-
79
-
80
- # Initialize methodology related attributes
81
- self.methodology_data = []
94
+ self.auto_complete = auto_complete if auto_complete is not None else is_auto_complete()
82
95
 
83
96
  PrettyOutput.section(f"Jarvis initialized - With {self.model.name()}", OutputType.SYSTEM)
97
+
84
98
  tools = self.tool_registry.get_all_tools()
85
99
  if tools:
86
100
  PrettyOutput.section(f"Available tools: {', '.join([tool['name'] for tool in tools])}", OutputType.SYSTEM)
87
101
 
88
-
89
- # Load methodology
90
102
 
91
103
  tools_prompt = self.tool_registry.load_tools()
92
104
  complete_prompt = """"""
93
105
  if self.auto_complete:
94
106
  complete_prompt = """
107
+ ## Task Completion
95
108
  When the task is completed, you should print the following message:
96
109
  <!!!COMPLETE!!!>
97
110
  """
@@ -106,8 +119,18 @@ Please describe in concise bullet points, highlighting important information.
106
119
  self.first = True
107
120
 
108
121
  @staticmethod
109
- def extract_tool_calls(content: str) -> List[Dict]:
110
- """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"""
122
+ def _extract_tool_calls(content: str) -> List[Dict]:
123
+ """Extract tool calls from content.
124
+
125
+ Args:
126
+ content: The content containing tool calls
127
+
128
+ Returns:
129
+ List[Dict]: List of extracted tool calls with name and arguments
130
+
131
+ Raises:
132
+ Exception: If tool call is missing necessary fields
133
+ """
111
134
  # Split content into lines
112
135
  lines = content.split('\n')
113
136
  tool_call_lines = []
@@ -143,7 +166,17 @@ Please describe in concise bullet points, highlighting important information.
143
166
  return []
144
167
 
145
168
  def _call_model(self, message: str) -> str:
146
- """Call model to get response"""
169
+ """Call the AI model with retry logic.
170
+
171
+ Args:
172
+ message: The input message for the model
173
+
174
+ Returns:
175
+ str: Model's response
176
+
177
+ Note:
178
+ Will retry with exponential backoff up to 30 seconds between retries
179
+ """
147
180
  sleep_time = 5
148
181
  while True:
149
182
  ret = self.model.chat_until_success(message)
@@ -159,16 +192,17 @@ Please describe in concise bullet points, highlighting important information.
159
192
 
160
193
 
161
194
  def _summarize_and_clear_history(self) -> None:
162
- """
163
- [System message]
164
- Summarize current conversation history and clear history, only keep system message and summary
195
+ """Summarize current conversation and clear history.
165
196
 
166
197
  This method will:
167
- 1. Request the model to summarize the key information from the current conversation
198
+ 1. Generate a summary of key information
168
199
  2. Clear the conversation history
169
200
  3. Keep the system message
170
- 4. Add the summary as new context
171
- 5. Reset the conversation round
201
+ 4. Add summary as new context
202
+ 5. Reset conversation length
203
+
204
+ Note:
205
+ Used when context length exceeds maximum
172
206
  """
173
207
  # Create a new model instance to summarize, avoid affecting the main conversation
174
208
 
@@ -203,10 +237,14 @@ Please continue the task based on the above information.
203
237
  PrettyOutput.print(f"Failed to summarize conversation history: {str(e)}", OutputType.ERROR)
204
238
 
205
239
  def _complete_task(self) -> str:
206
- """Complete task and generate summary
240
+ """Complete the current task and generate summary if needed.
207
241
 
208
242
  Returns:
209
243
  str: Task summary or completion status
244
+
245
+ Note:
246
+ - For main agent: May generate methodology if enabled
247
+ - For sub-agent: May generate summary if enabled
210
248
  """
211
249
  PrettyOutput.section("Task completed", OutputType.SUCCESS)
212
250
 
@@ -227,7 +265,7 @@ Please continue the task based on the above information.
227
265
 
228
266
  # 检查是否包含工具调用
229
267
  try:
230
- tool_calls = Agent.extract_tool_calls(response)
268
+ tool_calls = Agent._extract_tool_calls(response)
231
269
  if tool_calls:
232
270
  self.tool_registry.handle_tool_calls(tool_calls)
233
271
  except Exception as e:
@@ -246,17 +284,23 @@ Please continue the task based on the above information.
246
284
 
247
285
 
248
286
  def run(self, user_input: str, file_list: Optional[List[str]] = None) -> str:
249
- """Process user input and return response, return task summary report
287
+ """Process user input and execute the task.
250
288
 
251
289
  Args:
252
- user_input: User input task description
253
- file_list: Optional file list, default is None
254
-
290
+ user_input: User's task description or request
291
+ file_list: Optional list of files to process
292
+
255
293
  Returns:
256
294
  str: Task summary report
295
+
296
+ Note:
297
+ - Handles context management
298
+ - Processes tool calls
299
+ - Manages conversation flow
300
+ - Supports interactive mode
257
301
  """
258
302
 
259
-
303
+ add_agent(self.name)
260
304
 
261
305
  try:
262
306
  PrettyOutput.section("Preparing environment", OutputType.PLANNING)
@@ -266,7 +310,7 @@ Please continue the task based on the above information.
266
310
  # 显示任务开始
267
311
  PrettyOutput.section(f"Starting new task: {self.name}", OutputType.PLANNING)
268
312
 
269
- if self.first:
313
+ if self.first and self.use_methodology:
270
314
  self.prompt = f"{user_input}\n\n{load_methodology(user_input)}"
271
315
  self.first = False
272
316
  else:
@@ -289,11 +333,11 @@ Please continue the task based on the above information.
289
333
  self.prompt = ""
290
334
  self.conversation_length += len(current_response)
291
335
 
292
- for filter in self.output_filter:
293
- self.prompt += filter(current_response)
336
+ for handler in self.output_handler_before_tool:
337
+ self.prompt += handler(current_response)
294
338
 
295
339
  try:
296
- result = Agent.extract_tool_calls(current_response)
340
+ result = Agent._extract_tool_calls(current_response)
297
341
  except Exception as e:
298
342
  PrettyOutput.print(f"Tool call error: {str(e)}", OutputType.ERROR)
299
343
  self.prompt += f"Tool call error: {str(e)}"
@@ -303,6 +347,9 @@ Please continue the task based on the above information.
303
347
  PrettyOutput.print("Executing tool call...", OutputType.PROGRESS)
304
348
  tool_result = self.tool_registry.handle_tool_calls(result)
305
349
  self.prompt += tool_result
350
+
351
+ for handler in self.output_handler_after_tool:
352
+ self.prompt += handler(current_response)
306
353
 
307
354
  if self.prompt:
308
355
  continue
@@ -328,9 +375,17 @@ Please continue the task based on the above information.
328
375
  PrettyOutput.print(str(e), OutputType.ERROR)
329
376
  return f"Task failed: {str(e)}"
330
377
 
378
+ finally:
379
+ delete_current_agent()
331
380
 
332
- def clear_history(self):
333
- """Clear conversation history, only keep system prompt"""
381
+ def _clear_history(self):
382
+ """Clear conversation history while preserving system prompt.
383
+
384
+ This will:
385
+ 1. Clear the prompt
386
+ 2. Reset the model
387
+ 3. Reset conversation length counter
388
+ """
334
389
  self.prompt = ""
335
390
  self.model.reset()
336
391
  self.conversation_length = 0 # Reset conversation length
@@ -338,7 +393,7 @@ Please continue the task based on the above information.
338
393
 
339
394
 
340
395
 
341
- def load_tasks() -> dict:
396
+ def _load_tasks() -> dict:
342
397
  """Load tasks from .jarvis files in user home and current directory."""
343
398
  tasks = {}
344
399
 
@@ -375,18 +430,20 @@ def load_tasks() -> dict:
375
430
  except Exception as e:
376
431
  PrettyOutput.print(f"Error loading .jarvis/pre-command file: {str(e)}", OutputType.ERROR)
377
432
 
378
- # Read methodology
379
- method_path = os.path.expanduser("~/.jarvis/methodology")
380
- if os.path.exists(method_path):
381
- with open(method_path, "r", encoding="utf-8") as f:
382
- methodology = yaml.safe_load(f)
383
- if isinstance(methodology, dict):
384
- for name, desc in methodology.items():
385
- tasks[f"Run Methodology: {str(name)}\n {str(desc)}" ] = str(desc)
433
+
434
+ if is_use_methodology():
435
+ # Read methodology
436
+ method_path = os.path.expanduser("~/.jarvis/methodology")
437
+ if os.path.exists(method_path):
438
+ with open(method_path, "r", encoding="utf-8") as f:
439
+ methodology = yaml.safe_load(f)
440
+ if isinstance(methodology, dict):
441
+ for name, desc in methodology.items():
442
+ tasks[f"Run Methodology: {str(name)}\n {str(desc)}" ] = str(desc)
386
443
 
387
444
  return tasks
388
445
 
389
- def select_task(tasks: dict) -> str:
446
+ def _select_task(tasks: dict) -> str:
390
447
  """Let user select a task from the list or skip. Returns task description if selected."""
391
448
  if not tasks:
392
449
  return ""
@@ -462,9 +519,9 @@ def main():
462
519
  agent = Agent(system_prompt=origin_agent_system_prompt, tool_registry=ToolRegistry())
463
520
 
464
521
  # 加载预定义任务
465
- tasks = load_tasks()
522
+ tasks = _load_tasks()
466
523
  if tasks:
467
- selected_task = select_task(tasks)
524
+ selected_task = _select_task(tasks)
468
525
  if selected_task:
469
526
  PrettyOutput.print(f"\nExecute task: {selected_task}", OutputType.INFO)
470
527
  agent.run(selected_task, args.files)
@@ -1,17 +1,13 @@
1
- from enum import auto
2
1
  import os
3
- import re
4
2
  from typing import List
5
3
 
6
- import yaml
7
4
  from jarvis.agent import Agent
8
5
  from jarvis.jarvis_code_agent.patch import apply_patch
9
- from jarvis.jarvis_code_agent.file_select import select_files
10
6
  from jarvis.jarvis_code_agent.relevant_files import find_relevant_files
11
- from jarvis.models.registry import PlatformRegistry
12
- from jarvis.tools.git_commiter import GitCommitTool
13
- from jarvis.tools.registry import ToolRegistry
14
- from jarvis.utils import OutputType, PrettyOutput, get_file_line_count, get_multiline_input, get_single_line_input, has_uncommitted_changes, init_env, find_git_root, is_disable_codebase, make_choice_input, user_confirm
7
+ from jarvis.jarvis_platform.registry import PlatformRegistry
8
+ from jarvis.jarvis_tools.git_commiter import GitCommitTool
9
+ from jarvis.jarvis_tools.registry import ToolRegistry
10
+ from jarvis.utils import OutputType, PrettyOutput, get_file_line_count, get_multiline_input, has_uncommitted_changes, init_env, find_git_root
15
11
 
16
12
 
17
13
 
@@ -21,7 +17,18 @@ class CodeAgent:
21
17
  def __init__(self):
22
18
  self.root_dir = os.getcwd()
23
19
  tool_registry = ToolRegistry()
24
- tool_registry.use_tools(["read_code", "execute_shell", "search", "ask_user", "ask_codebase"])
20
+ tool_registry.use_tools(["read_code",
21
+ "execute_shell",
22
+ "search",
23
+ "create_code_agent",
24
+ "ask_user",
25
+ "ask_codebase",
26
+ "lsp_get_document_symbols",
27
+ "lsp_get_diagnostics",
28
+ "lsp_find_references",
29
+ "lsp_find_definition",
30
+ "lsp_prepare_rename",
31
+ "lsp_validate_edit"])
25
32
  code_system_prompt = """
26
33
  You are a code agent, you are responsible for modifying the code.
27
34
 
@@ -30,23 +37,109 @@ You should read the code and analyze the code, and then provide a plan for the c
30
37
  ## Workflow Steps
31
38
 
32
39
  1. ANALYSIS
33
- - Understand the requirement thoroughly
34
- - Identify which files need to be modified
35
- - Review the current implementation
36
- - Consider potential impacts
40
+ - Use chain of thought to analyze the requirement:
41
+ ```
42
+ Thought: Let me understand what the user is asking for...
43
+ Action: Break down the requirement into specific tasks
44
+ Observation: The key tasks are...
45
+
46
+ Thought: Assess task complexity...
47
+ Action: Evaluate each task's scope and dependencies
48
+ Observation: Task complexity analysis shows...
49
+
50
+ Thought: Determine if task splitting is needed...
51
+ Action: Consider using multiple create_code_agent calls
52
+ Observation: Based on complexity, the approach should be...
53
+
54
+ Conclusion:
55
+ 1. Task Breakdown: [list of specific tasks]
56
+ 2. Complexity Assessment: [simple/complex]
57
+ 3. Development Approach: [single/multiple agents]
58
+ 4. Task Dependencies: [dependency order]
59
+ ```
60
+
61
+ IMPORTANT TASK MANAGEMENT:
62
+ - For complex requirements:
63
+ * Break down into smaller, manageable tasks
64
+ * Use create_code_agent for each sub-task
65
+ * Maintain proper task ordering
66
+ * Ensure integration between sub-tasks
67
+
68
+ Example Task Split:
69
+ ```
70
+ 1. For complex task "Implement new logging system":
71
+ a. First create_code_agent: "Create basic logging interface"
72
+ b. Second create_code_agent: "Implement file logging backend"
73
+ c. Third create_code_agent: "Add log rotation support"
74
+
75
+ 2. Benefits:
76
+ - Focused development for each part
77
+ - Clear progress tracking
78
+ - Easier code review
79
+ - Better error handling
80
+ ```
37
81
 
38
82
  2. PLANNING
39
- - Break down the changes into logical steps
40
- - Consider dependencies between changes
41
- - Plan the implementation sequence
42
- - Think about potential risks
83
+ - Break down the changes into logical steps using chain of thought:
84
+ ```
85
+ Thought: First, let me analyze what needs to be changed...
86
+ Action: Use LSP tools to understand the code structure
87
+ Observation: Found these key components...
88
+
89
+ Thought: Based on the analysis, I need to modify...
90
+ Action: Check dependencies and potential impacts
91
+ Observation: These files will be affected...
92
+
93
+ Thought: Consider previously applied patches...
94
+ Action: Review the changes made so far
95
+ Observation: Previous patches have modified...
96
+
97
+ Thought: The remaining changes should be implemented in this order...
98
+ Plan:
99
+ 1. First modify X because... [considering previous changes]
100
+ 2. Then update Y to handle... [building on previous patches]
101
+ 3. Finally adjust Z to ensure... [maintaining consistency]
102
+ ```
103
+
104
+ IMPORTANT PATCH GUIDELINES:
105
+ - Track all previously applied patches
106
+ - Base new patches on the updated code state
107
+ - Consider cumulative effects of patches
108
+ - Verify patch locations against current file state
109
+ - Update line numbers based on previous changes
110
+ - Maintain consistency with earlier modifications
111
+ - If unsure about current state, ask for clarification
43
112
 
44
113
  3. IMPLEMENTATION
45
114
  For each file that needs changes:
46
- a. Read and understand the current code
47
- b. Plan the specific modifications
48
- c. Write the patch in the required format
49
- d. Review the patch for correctness
115
+ a. Code Understanding:
116
+ - Use LSP tools to verify current implementation:
117
+ * lsp_get_document_symbols to see current structure
118
+ * lsp_find_definition to confirm current definitions
119
+ * lsp_find_references to trace current usages
120
+ - Consider effects of previous patches
121
+ - Understand current code state
122
+ - Verify patch locations are still valid
123
+
124
+ b. Change Planning:
125
+ - Plan changes based on current code state
126
+ - Account for previous modifications
127
+ - Ensure compatibility with applied patches
128
+ - Update line numbers if needed
129
+ - Document dependencies on previous changes
130
+
131
+ c. Implementation:
132
+ - Write patches for current code state
133
+ - Reference previous patch effects
134
+ - Maintain consistency with earlier changes
135
+ - Verify patch locations are accurate
136
+ - Consider cumulative impact
137
+
138
+ d. Verification:
139
+ - Verify against current code state
140
+ - Test compatibility with previous patches
141
+ - Check for patch sequence issues
142
+ - Validate cumulative changes
50
143
 
51
144
  ## File Reading Guidelines
52
145
 
@@ -130,6 +223,24 @@ Note: In this example:
130
223
  - Use 'execute_shell' for grep/find/ctags operations
131
224
  - Use 'search' to search on web
132
225
  - Use 'ask_user' when clarification is needed
226
+ - LSP Tools for Code Analysis:
227
+ * lsp_get_document_symbols: Get all symbols in a file
228
+ * lsp_get_diagnostics: Get errors and warnings
229
+ * lsp_find_references: Find all references to a symbol
230
+ * lsp_find_definition: Find symbol definition
231
+ * lsp_prepare_rename: Check if symbol can be renamed
232
+ * lsp_validate_edit: Validate code changes
233
+ Example LSP Usage:
234
+ ```
235
+ <TOOL_CALL>
236
+ name: lsp_find_definition
237
+ arguments:
238
+ file_path: src/main.py
239
+ line: 10
240
+ character: 15
241
+ language: python
242
+ </TOOL_CALL>
243
+ ```
133
244
 
134
245
  Please proceed with the analysis and implementation following this workflow.
135
246
  Start by examining the files and planning your changes.
@@ -142,7 +253,7 @@ Then provide the necessary patches in the specified format.
142
253
  tool_registry=tool_registry,
143
254
  platform=PlatformRegistry().get_codegen_platform(),
144
255
  record_methodology=False,
145
- output_filter=[apply_patch],
256
+ output_handler_after_tool=[apply_patch],
146
257
  need_summary=False)
147
258
 
148
259
 
@@ -1,9 +1,8 @@
1
1
  import re
2
- from typing import Dict, Any, List, Tuple
2
+ from typing import Dict, Any, List
3
3
  import os
4
- from jarvis.tools.git_commiter import GitCommitTool
5
- from jarvis.tools.read_code import ReadCodeTool
6
- from jarvis.utils import OutputType, PrettyOutput, has_uncommitted_changes, make_choice_input, user_confirm
4
+ from jarvis.jarvis_tools.git_commiter import GitCommitTool
5
+ from jarvis.utils import OutputType, PrettyOutput, has_uncommitted_changes, user_confirm
7
6
 
8
7
 
9
8
  def _parse_patch(patch_str: str) -> Dict[str, List[Dict[str, Any]]]:
@@ -60,9 +59,7 @@ def _parse_patch(patch_str: str) -> Dict[str, List[Dict[str, Any]]]:
60
59
  def apply_patch(output_str: str)->str:
61
60
  """Apply patches to files"""
62
61
  patches = _parse_patch(output_str)
63
- if not patches:
64
- return ""
65
-
62
+
66
63
  for filepath, patch_info in patches.items():
67
64
  try:
68
65
  # Check if file exists