jarvis-ai-assistant 0.1.125__py3-none-any.whl → 0.1.128__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 (49) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +205 -187
  3. jarvis/jarvis_code_agent/code_agent.py +116 -109
  4. jarvis/jarvis_code_agent/patch.py +157 -138
  5. jarvis/jarvis_code_agent/shell_input_handler.py +22 -0
  6. jarvis/jarvis_codebase/main.py +314 -288
  7. jarvis/jarvis_dev/main.py +695 -716
  8. jarvis/jarvis_lsp/base.py +0 -12
  9. jarvis/jarvis_lsp/cpp.py +0 -9
  10. jarvis/jarvis_lsp/go.py +0 -9
  11. jarvis/jarvis_lsp/python.py +0 -28
  12. jarvis/jarvis_lsp/registry.py +0 -1
  13. jarvis/jarvis_lsp/rust.py +0 -9
  14. jarvis/jarvis_multi_agent/__init__.py +52 -52
  15. jarvis/jarvis_platform/base.py +6 -5
  16. jarvis/jarvis_platform_manager/main.py +1 -1
  17. jarvis/jarvis_rag/main.py +250 -186
  18. jarvis/jarvis_smart_shell/main.py +0 -1
  19. jarvis/jarvis_tools/ask_codebase.py +10 -9
  20. jarvis/jarvis_tools/ask_user.py +2 -2
  21. jarvis/jarvis_tools/base.py +4 -4
  22. jarvis/jarvis_tools/chdir.py +28 -28
  23. jarvis/jarvis_tools/code_review.py +44 -39
  24. jarvis/jarvis_tools/create_code_agent.py +4 -4
  25. jarvis/jarvis_tools/create_sub_agent.py +7 -7
  26. jarvis/jarvis_tools/execute_shell.py +53 -23
  27. jarvis/jarvis_tools/execute_shell_script.py +3 -3
  28. jarvis/jarvis_tools/file_operation.py +70 -41
  29. jarvis/jarvis_tools/git_commiter.py +61 -51
  30. jarvis/jarvis_tools/lsp_find_definition.py +7 -7
  31. jarvis/jarvis_tools/lsp_prepare_rename.py +7 -7
  32. jarvis/jarvis_tools/methodology.py +6 -6
  33. jarvis/jarvis_tools/rag.py +5 -5
  34. jarvis/jarvis_tools/read_webpage.py +52 -32
  35. jarvis/jarvis_tools/registry.py +167 -180
  36. jarvis/jarvis_tools/search_web.py +66 -41
  37. jarvis/jarvis_tools/select_code_files.py +3 -3
  38. jarvis/jarvis_tools/tool_generator.py +68 -55
  39. jarvis/jarvis_utils/methodology.py +77 -59
  40. jarvis/jarvis_utils/output.py +1 -0
  41. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/METADATA +31 -17
  42. jarvis_ai_assistant-0.1.128.dist-info/RECORD +74 -0
  43. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/WHEEL +1 -1
  44. jarvis/jarvis_tools/lsp_validate_edit.py +0 -141
  45. jarvis/jarvis_tools/read_code.py +0 -192
  46. jarvis_ai_assistant-0.1.125.dist-info/RECORD +0 -75
  47. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/LICENSE +0 -0
  48. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/entry_points.txt +0 -0
  49. {jarvis_ai_assistant-0.1.125.dist-info → jarvis_ai_assistant-0.1.128.dist-info}/top_level.txt +0 -0
@@ -3,11 +3,15 @@ import subprocess
3
3
  import os
4
4
  from typing import Any, Tuple
5
5
 
6
+ from yaspin import yaspin
7
+
6
8
  from jarvis.jarvis_agent import Agent
7
- from jarvis.jarvis_code_agent.patch import PatchOutputHandler, shell_input_handler
9
+ from jarvis.jarvis_code_agent.shell_input_handler import shell_input_handler
10
+ from jarvis.jarvis_code_agent.patch import PatchOutputHandler
8
11
  from jarvis.jarvis_platform.registry import PlatformRegistry
12
+ from jarvis.jarvis_tools.file_operation import FileOperationTool
9
13
  from jarvis.jarvis_tools.git_commiter import GitCommitTool
10
- from jarvis.jarvis_tools.read_code import ReadCodeTool
14
+
11
15
  from jarvis.jarvis_tools.registry import ToolRegistry
12
16
  from jarvis.jarvis_utils.git_utils import find_git_root, get_commits_between, get_latest_commit_hash, has_uncommitted_changes
13
17
  from jarvis.jarvis_utils.input import get_multiline_input
@@ -81,12 +85,15 @@ def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
81
85
  "start_line": 1, # 1-based
82
86
  "end_line": -1
83
87
  })
84
-
88
+
85
89
  # Read and process files if any were found
86
90
  if files:
87
- result = ReadCodeTool().execute({"files": files})
88
- if result["success"]:
89
- return result["stdout"] + "\n" + prompt, False
91
+ with yaspin(text="正在读取文件...", color="cyan") as spinner:
92
+ result = FileOperationTool().execute({"operation":"read","files": files})
93
+ if result["success"]:
94
+ spinner.text = "文件读取完成"
95
+ spinner.ok("✅")
96
+ return result["stdout"] + "\n" + prompt, False
90
97
 
91
98
  return prompt, False
92
99
 
@@ -96,8 +103,7 @@ class CodeAgent:
96
103
  def __init__(self):
97
104
  self.root_dir = os.getcwd()
98
105
  tool_registry = ToolRegistry()
99
- tool_registry.use_tools(["read_code",
100
- "execute_shell",
106
+ tool_registry.use_tools(["execute_shell",
101
107
  "execute_shell_script",
102
108
  "search_web",
103
109
  "create_code_agent",
@@ -107,99 +113,92 @@ class CodeAgent:
107
113
  "lsp_get_diagnostics",
108
114
  "lsp_find_references",
109
115
  "lsp_find_definition",
110
- "lsp_prepare_rename",
111
- "lsp_validate_edit"])
116
+ "lsp_prepare_rename"
117
+ ])
112
118
  code_system_prompt = """
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
119
+ # 角色:高级代码工程师
120
+ 精通安全、精确的代码修改,具有严格的验证流程。
121
+
122
+ ## 核心原则
123
+ 1. 安全第一:绝不破坏现有功能
124
+ 2. 精准工程:最小化、针对性修改
125
+ 3. 完整可追溯:记录所有决策
126
+ 4. 验证驱动:在每个阶段进行验证
127
+
128
+ ## 工具使用协议
129
+ 1. 分析工具:
130
+ - lsp_get_document_symbols:映射代码结构
131
+ - lsp_find_references:理解使用模式
132
+ - lsp_find_definition:追踪实现细节
133
+
134
+ 2. 验证工具:
135
+ - lsp_prepare_rename:安全重构检查
136
+ - lsp_get_diagnostics:修改后检查
137
+
138
+ 3. 系统工具:
139
+ - execute_shell:用于git操作和grep搜索
140
+ - ask_codebase:查询代码知识库
141
+ - search_web:技术参考查找
142
+
143
+ ## 工作流程(PDCA循环)
144
+ 1. 计划:
145
+ - 使用ask_user分析需求
146
+ - 使用LSP工具映射现有代码
147
+ - 使用find_references识别影响区域
148
+ - 使用git创建回滚计划
149
+
150
+ 2. 执行:
151
+ - 在受保护的块中进行原子修改
152
+ - 每次更改后自动运行lsp_get_diagnostics
153
+ - 如果发现错误,使用lsp_find_references和lsp_find_definition进行即时修复
154
+ - 每次更改后使用LSP验证语法
155
+
156
+ 3. 检查:
157
+ - 强制使用lsp_get_diagnostics进行完整诊断报告
158
+ - 使用lsp_preprepare_rename验证所有重命名
159
+ - 如果检测到错误,进入修复循环直到所有检查通过
160
+
161
+ 4. 行动:
162
+ - 使用git提交详细消息
163
+ - 准备回滚脚本(如果需要)
164
+ - 进行实施后审查
165
+
166
+ ## 代码修改标准
167
+ 1. 修改前要求:
168
+ - 完整的代码分析报告
169
+ - 影响评估矩阵
170
+ - 回滚程序文档
171
+
172
+ 2. 修改实施:
173
+ - 单一职责修改
174
+ - 严格的代码范围验证(±3行缓冲区)
175
+ - 接口兼容性检查
176
+
177
+ 3. 验证清单:
178
+ [ ] 执行lsp_get_diagnostics并确保零错误
179
+ [ ] 使用lsp_find_references确认影响范围
180
+ [ ] 使用lsp_prepare_rename验证重命名安全性
181
+
182
+ 4. 修改后:
183
+ - 代码审查模拟
184
+ - 版本控制审计
185
+ - 更新变更日志
186
+
187
+ ## 关键要求
188
+ 1. 强制分析:
189
+ - 修改前完整符号追踪
190
+ - 跨文件影响分析
191
+ - 依赖关系映射
192
+
193
+ 2. 禁止操作:
194
+ - 未通过lsp_get_diagnostics检查继续操作
195
+ - 多个功能组合修改
196
+ - 未经测试的接口修改
197
+
198
+ 3. 紧急协议:
199
+ - lsp_get_diagnostics出现错误时立即停止并回滚
200
+ - 出现意外行为时通知用户
201
+ - 对任何回归进行事后分析
203
202
  """
204
203
  self.agent = Agent(system_prompt=code_system_prompt,
205
204
  name="CodeAgent",
@@ -215,12 +214,17 @@ Expert in safe, precise code modifications with rigorous validation processes.
215
214
 
216
215
 
217
216
  def _init_env(self):
218
- curr_dir = os.getcwd()
219
- git_dir = find_git_root(curr_dir)
220
- self.root_dir = git_dir
221
- if has_uncommitted_changes():
222
- git_commiter = GitCommitTool()
223
- git_commiter.execute({})
217
+ with yaspin(text="正在初始化环境...", color="cyan") as spinner:
218
+ curr_dir = os.getcwd()
219
+ git_dir = find_git_root(curr_dir)
220
+ self.root_dir = git_dir
221
+ if has_uncommitted_changes():
222
+ with spinner.hidden():
223
+ git_commiter = GitCommitTool()
224
+ git_commiter.execute({})
225
+ else:
226
+ spinner.text = "环境初始化完成"
227
+ spinner.ok("✅")
224
228
 
225
229
 
226
230
 
@@ -235,10 +239,13 @@ Expert in safe, precise code modifications with rigorous validation processes.
235
239
  """
236
240
  try:
237
241
  self._init_env()
238
- start_commit = get_latest_commit_hash()
239
242
 
243
+ start_commit = get_latest_commit_hash()
240
244
 
241
- self.agent.run(user_input)
245
+ try:
246
+ self.agent.run(user_input)
247
+ except Exception as e:
248
+ PrettyOutput.print(f"执行失败: {str(e)}", OutputType.WARNING)
242
249
 
243
250
  end_commit = get_latest_commit_hash()
244
251
  # Print commit history between start and end commits
@@ -296,4 +303,4 @@ def main():
296
303
  return 0
297
304
 
298
305
  if __name__ == "__main__":
299
- exit(main())
306
+ exit(main())
@@ -2,11 +2,13 @@ import re
2
2
  from typing import Dict, Any, Tuple
3
3
  import os
4
4
 
5
+ from yaspin import yaspin
6
+
5
7
  from jarvis.jarvis_agent.output_handler import OutputHandler
6
8
  from jarvis.jarvis_platform.registry import PlatformRegistry
7
9
  from jarvis.jarvis_tools.git_commiter import GitCommitTool
8
- from jarvis.jarvis_tools.file_operation import FileOperationTool
9
10
  from jarvis.jarvis_tools.execute_shell_script import ShellScriptTool
11
+ from jarvis.jarvis_tools.file_operation import FileOperationTool
10
12
  from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
11
13
  from jarvis.jarvis_utils.git_utils import get_commits_between, get_latest_commit_hash
12
14
  from jarvis.jarvis_utils.input import get_multiline_input
@@ -26,31 +28,31 @@ class PatchOutputHandler(OutputHandler):
26
28
 
27
29
  def prompt(self) -> str:
28
30
  return """
29
- # 🛠️ Contextual Code Patch Specification
30
- Use <PATCH> blocks to specify code changes:
31
+ # 🛠️ 上下文代码补丁规范
32
+ 使用<PATCH>块来指定代码更改:
31
33
  --------------------------------
32
34
  <PATCH>
33
- File: [file_path]
34
- Reason: [change_reason]
35
- [contextual_code_snippet]
35
+ File: [文件路径]
36
+ Reason: [修改原因]
37
+ [上下文代码片段]
36
38
  </PATCH>
37
39
  --------------------------------
38
- Rules:
39
- 1. Code snippets must include sufficient context (3 lines before/after)
40
- 2. I can see full code, so only show modified code sections
41
- 3. Preserve original indentation and formatting
42
- 4. For new files, provide complete code
43
- 5. When modifying existing files, retain surrounding unchanged code
44
- Example:
40
+ 规则:
41
+ 1. 代码片段必须包含足够的上下文(前后各3行)
42
+ 2. 我可以看到完整代码,所以只需显示修改的代码部分
43
+ 3. 保留原始缩进和格式
44
+ 4. 对于新文件,提供完整代码
45
+ 5. 修改现有文件时,保留周围未更改的代码
46
+ 示例:
45
47
  <PATCH>
46
48
  File: src/utils/math.py
47
- Reason: Fix zero division handling
49
+ Reason: 修复除零处理
48
50
  def safe_divide(a, b):
49
- # Add parameter validation
51
+ # 添加参数验证
50
52
  if b == 0:
51
- raise ValueError("Divisor cannot be zero")
53
+ raise ValueError("除数不能为零")
52
54
  return a / b
53
- # existing code ...
55
+ # 现有代码 ...
54
56
  def add(a, b):
55
57
  return a + b
56
58
  </PATCH>
@@ -73,50 +75,63 @@ def _parse_patch(patch_str: str) -> Dict[str, str]:
73
75
 
74
76
  def apply_patch(output_str: str) -> str:
75
77
  """Apply patches to files"""
76
- try:
77
- patches = _parse_patch(output_str)
78
- except Exception as e:
79
- PrettyOutput.print(f"解析补丁失败: {str(e)}", OutputType.ERROR)
80
- return ""
81
-
82
- # 获取当前提交hash作为起始点
83
- start_hash = get_latest_commit_hash()
84
-
85
- # 按文件逐个处理
86
- for filepath, patch_content in patches.items():
78
+ with yaspin(text="正在应用补丁...", color="cyan") as spinner:
87
79
  try:
88
- handle_code_operation(filepath, patch_content)
89
- PrettyOutput.print(f"文件 {filepath} 处理完成", OutputType.SUCCESS)
80
+ patches = _parse_patch(output_str)
90
81
  except Exception as e:
91
- revert_file(filepath) # 回滚单个文件
92
- PrettyOutput.print(f"文件 {filepath} 处理失败: {str(e)}", OutputType.ERROR)
93
-
94
- final_ret = ""
95
- diff = get_diff()
96
- if diff:
97
- PrettyOutput.print(diff, OutputType.CODE, lang="diff")
98
- if handle_commit_workflow():
99
- # 获取提交信息
100
- end_hash = get_latest_commit_hash()
101
- commits = get_commits_between(start_hash, end_hash)
102
-
103
- # 添加提交信息到final_ret
104
- if commits:
105
- final_ret += "✅ The patches have been applied\n"
106
- final_ret += "Commit History:\n"
107
- for commit_hash, commit_message in commits:
108
- final_ret += f"- {commit_hash[:7]}: {commit_message}\n"
82
+ PrettyOutput.print(f"解析补丁失败: {str(e)}", OutputType.ERROR)
83
+ return ""
84
+
85
+ # 获取当前提交hash作为起始点
86
+ spinner.text= "开始获取当前提交hash..."
87
+ start_hash = get_latest_commit_hash()
88
+ spinner.write("✅ 当前提交hash获取完成")
89
+
90
+ # 按文件逐个处理
91
+ for filepath, patch_content in patches.items():
92
+ try:
93
+ spinner.text = f"正在处理文件: {filepath}"
94
+ with spinner.hidden():
95
+ handle_code_operation(filepath, patch_content)
96
+ spinner.write(f"✅ 文件 {filepath} 处理完成")
97
+ except Exception as e:
98
+ spinner.text = f"文件 {filepath} 处理失败: {str(e)}, 回滚文件"
99
+ revert_file(filepath) # 回滚单个文件
100
+ spinner.write(f"✅ 文件 {filepath} 回滚完成")
101
+
102
+ final_ret = ""
103
+ diff = get_diff()
104
+ if diff:
105
+ PrettyOutput.print(diff, OutputType.CODE, lang="diff")
106
+ with spinner.hidden():
107
+ commited = handle_commit_workflow()
108
+ if commited:
109
+ # 获取提交信息
110
+ end_hash = get_latest_commit_hash()
111
+ commits = get_commits_between(start_hash, end_hash)
112
+
113
+ # 添加提交信息到final_ret
114
+ if commits:
115
+ final_ret += "✅ 补丁已应用\n"
116
+ final_ret += "提交信息:\n"
117
+ for commit_hash, commit_message in commits:
118
+ final_ret += f"- {commit_hash[:7]}: {commit_message}\n"
119
+
120
+ final_ret += f"应用补丁:\n{diff}"
121
+
122
+ else:
123
+ final_ret += "✅ 补丁已应用(没有新的提交)"
109
124
  else:
110
- final_ret += " The patches have been applied (no new commits)"
125
+ final_ret += " 我不想提交代码\n"
126
+ final_ret += "补丁预览:\n"
127
+ final_ret += diff
111
128
  else:
112
- final_ret += "❌ I don't want to commit the code"
113
- else:
114
- final_ret += "❌ There are no changes to commit"
115
- # 用户确认最终结果
116
- PrettyOutput.print(final_ret, OutputType.USER)
117
- if not is_confirm_before_apply_patch() or user_confirm("是否使用此回复?", default=True):
118
- return final_ret
119
- return get_multiline_input("请输入自定义回复")
129
+ final_ret += "❌ 没有要提交的更改\n"
130
+ # 用户确认最终结果
131
+ PrettyOutput.print(final_ret, OutputType.USER)
132
+ if not is_confirm_before_apply_patch() or user_confirm("是否使用此回复?", default=True):
133
+ return final_ret
134
+ return get_multiline_input("请输入自定义回复")
120
135
  def revert_file(filepath: str):
121
136
  """增强版git恢复,处理新文件"""
122
137
  import subprocess
@@ -170,87 +185,91 @@ def handle_commit_workflow()->bool:
170
185
  return commit_result["success"]
171
186
 
172
187
  # New handler functions below ▼▼▼
173
- def handle_code_operation(filepath: str, patch_content: str) -> str:
188
+ def handle_code_operation(filepath: str, patch_content: str) -> bool:
174
189
  """处理基于上下文的代码片段"""
175
- try:
176
- if not os.path.exists(filepath):
177
- # 新建文件
178
- os.makedirs(os.path.dirname(filepath), exist_ok=True)
179
- open(filepath, 'w', encoding='utf-8').close()
180
- old_file_content = FileOperationTool().execute({"operation": "read", "files": [{"path": filepath}]})
181
- if not old_file_content["success"]:
182
- return f"文件读取失败: {old_file_content['stderr']}"
183
-
184
- prompt = f"""
185
- You are a code reviewer, please review the following code and merge the code with the context.
186
- Original Code:
187
- {old_file_content["stdout"]}
188
- Patch:
189
- {patch_content}
190
- """
191
- prompt += f"""
192
- Please merge the code with the context and return the fully merged code.
190
+ with yaspin(text=f"正在修改文件 {filepath}...", color="cyan") as spinner:
191
+ try:
192
+ if not os.path.exists(filepath):
193
+ # 新建文件
194
+ spinner.text = "文件不存在,正在创建文件..."
195
+ os.makedirs(os.path.dirname(filepath), exist_ok=True)
196
+ open(filepath, 'w', encoding='utf-8').close()
197
+ spinner.write(" 文件创建完成")
198
+ old_file_content = FileOperationTool().execute({"operation": "read", "files": [{"path": filepath}]})
199
+ if not old_file_content["success"]:
200
+ spinner.write("❌ 文件读取失败")
201
+ return False
202
+
203
+ prompt = f"""
204
+ 你是一个代码审查员,请审查以下代码并将其与上下文合并。
205
+ 原始代码:
206
+ {old_file_content["stdout"]}
207
+ 补丁内容:
208
+ {patch_content}
209
+ """
210
+ prompt += f"""
211
+ 请将代码与上下文合并并返回完整的合并代码,每次最多输出300行代码。
193
212
 
194
- Requirements:
195
- 1. Strictly preserve original code formatting and indentation
196
- 2. Only include actual code content in <MERGED_CODE> block
197
- 3. Absolutely NO markdown code blocks (```) or backticks
198
- 4. Maintain exact line numbers from original code except for changes
213
+ 要求:
214
+ 1. 严格保留原始代码的格式、空行和缩进
215
+ 2. 仅在<MERGED_CODE>块中包含实际代码内容,包括空行和缩进
216
+ 3. 绝对不要使用markdown代码块(```)或反引号,除非修改的是markdown文件
217
+ 4. 除了合并后的代码,不要输出任何其他文本
218
+ 5. 所有代码输出完成后,输出<!!!FINISHED!!!>
199
219
 
200
- Output Format:
201
- <MERGED_CODE>
202
- [merged_code]
203
- </MERGED_CODE>
204
- """
205
- model = PlatformRegistry().get_codegen_platform()
206
- model.set_suppress_output(False)
207
- count = 5
208
- start_line = -1
209
- end_line = -1
210
- response = []
211
- while count > 0:
212
- count -= 1
213
- response.extend(model.chat_until_success(prompt).splitlines())
214
- try:
215
- start_line = response.index("<MERGED_CODE>") + 1
216
- except:
217
- pass
218
- try:
219
- end_line = response.index("</MERGED_CODE>")
220
- except:
221
- pass
222
- if start_line == -1:
223
- PrettyOutput.print(f"❌ 为文件 {filepath} 应用补丁失败", OutputType.WARNING)
224
- return f"代码合并失败"
225
- if end_line == -1:
226
- last_line = response[-1]
227
- prompt = f"""
228
- continue with the last line:
229
- {last_line}
230
- """
231
- response.pop() # 删除最后一行
232
- continue
233
- if end_line < start_line:
234
- PrettyOutput.print(f"❌ 为文件 {filepath} 应用补丁失败", OutputType.WARNING)
235
- return f"代码合并失败"
236
- break
237
- # 写入合并后的代码
238
- with open(filepath, 'w', encoding='utf-8') as f:
239
- f.write("\n".join(response[start_line:end_line]))
240
- PrettyOutput.print(f"✅ 为文件 {filepath} 应用补丁成功", OutputType.SUCCESS)
241
- return ""
242
- except Exception as e:
243
- return f"文件操作失败: {str(e)}"
244
- def shell_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
245
- lines = user_input.splitlines()
246
- cmdline = [line for line in lines if line.startswith("!")]
247
- if len(cmdline) == 0:
248
- return user_input, False
249
- else:
250
- script = '\n'.join([c[1:] for c in cmdline])
251
- PrettyOutput.print(script, OutputType.CODE, lang="bash")
252
- if user_confirm(f"是否要执行以上shell脚本?", default=True):
253
- ShellScriptTool().execute({"script_content": script})
254
- return "", True
255
- return user_input, False
256
-
220
+ 输出格式:
221
+ <MERGED_CODE>
222
+ [merged_code]
223
+ </MERGED_CODE>
224
+ """
225
+ PrettyOutput.section("代码生成", OutputType.SYSTEM)
226
+ model = PlatformRegistry().get_codegen_platform()
227
+ model.set_suppress_output(False)
228
+ count = 30
229
+ start_line = -1
230
+ end_line = -1
231
+ code = []
232
+ finished = False
233
+ with spinner.hidden():
234
+ while count>0:
235
+ count -= 1
236
+ response = model.chat_until_success(prompt).splitlines()
237
+ try:
238
+ start_line = response.index("<MERGED_CODE>") + 1
239
+ except:
240
+ return False
241
+ try:
242
+ end_line = response.index("</MERGED_CODE>")
243
+ except:
244
+ return False
245
+ code = response[start_line:end_line]
246
+ try:
247
+ response.index("<!!!FINISHED!!!>")
248
+ finished = True
249
+ break
250
+ except:
251
+ prompt += f"""继续输出接下来的300行代码
252
+ 要求:
253
+ 1. 严格保留原始代码的格式、空行和缩进
254
+ 2. 仅在<MERGED_CODE>块中包含实际代码内容,包括空行和缩进
255
+ 3. 绝对不要使用markdown代码块(```)或反引号,除非修改的是markdown文件
256
+ 4. 除了合并后的代码,不要输出任何其他文本
257
+ 5. 所有代码输出完成后,输出<!!!FINISHED!!!>
258
+ """
259
+ pass
260
+ if not finished:
261
+ spinner.text = "生成代码失败"
262
+ spinner.fail("❌")
263
+ return False
264
+ # 写入合并后的代码
265
+ spinner.text = "写入合并后的代码..."
266
+ with open(filepath, 'w', encoding='utf-8') as f:
267
+ f.write("\n".join(code)+"\n")
268
+ spinner.write("✅ 合并后的代码写入完成")
269
+ spinner.text = "代码修改完成"
270
+ spinner.ok("✅")
271
+ return True
272
+ except Exception as e:
273
+ spinner.text = "代码修改失败"
274
+ spinner.fail("")
275
+ return False
@@ -0,0 +1,22 @@
1
+
2
+
3
+ from typing import Any, Tuple
4
+
5
+ from jarvis.jarvis_tools.execute_shell_script import ShellScriptTool
6
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
+ from jarvis.jarvis_utils.utils import user_confirm
8
+
9
+
10
+ def shell_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
11
+ lines = user_input.splitlines()
12
+ cmdline = [line for line in lines if line.startswith("!")]
13
+ if len(cmdline) == 0:
14
+ return user_input, False
15
+ else:
16
+ script = '\n'.join([c[1:] for c in cmdline])
17
+ PrettyOutput.print(script, OutputType.CODE, lang="bash")
18
+ if user_confirm(f"是否要执行以上shell脚本?", default=True):
19
+ ShellScriptTool().execute({"script_content": script})
20
+ return "", True
21
+ return user_input, False
22
+