jarvis-ai-assistant 0.1.131__py3-none-any.whl → 0.1.134__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 +1 -1
- jarvis/jarvis_agent/__init__.py +165 -285
- jarvis/jarvis_agent/jarvis.py +143 -0
- jarvis/jarvis_agent/main.py +0 -2
- jarvis/jarvis_agent/patch.py +70 -48
- jarvis/jarvis_agent/shell_input_handler.py +1 -1
- jarvis/jarvis_code_agent/code_agent.py +169 -117
- jarvis/jarvis_dev/main.py +327 -626
- jarvis/jarvis_git_squash/main.py +10 -31
- jarvis/jarvis_lsp/base.py +0 -42
- jarvis/jarvis_lsp/cpp.py +0 -15
- jarvis/jarvis_lsp/go.py +0 -15
- jarvis/jarvis_lsp/python.py +0 -19
- jarvis/jarvis_lsp/registry.py +0 -62
- jarvis/jarvis_lsp/rust.py +0 -15
- jarvis/jarvis_multi_agent/__init__.py +19 -69
- jarvis/jarvis_multi_agent/main.py +43 -0
- jarvis/jarvis_platform/ai8.py +7 -32
- jarvis/jarvis_platform/base.py +2 -7
- jarvis/jarvis_platform/kimi.py +3 -144
- jarvis/jarvis_platform/ollama.py +54 -68
- jarvis/jarvis_platform/openai.py +0 -4
- jarvis/jarvis_platform/oyi.py +0 -75
- jarvis/jarvis_platform/registry.py +2 -16
- jarvis/jarvis_platform/yuanbao.py +264 -0
- jarvis/jarvis_rag/file_processors.py +138 -0
- jarvis/jarvis_rag/main.py +1305 -425
- jarvis/jarvis_tools/ask_codebase.py +216 -43
- jarvis/jarvis_tools/code_review.py +158 -113
- jarvis/jarvis_tools/create_sub_agent.py +0 -1
- jarvis/jarvis_tools/execute_python_script.py +58 -0
- jarvis/jarvis_tools/execute_shell.py +13 -26
- jarvis/jarvis_tools/execute_shell_script.py +1 -1
- jarvis/jarvis_tools/file_analyzer.py +282 -0
- jarvis/jarvis_tools/file_operation.py +1 -1
- jarvis/jarvis_tools/find_caller.py +278 -0
- jarvis/jarvis_tools/find_symbol.py +295 -0
- jarvis/jarvis_tools/function_analyzer.py +331 -0
- jarvis/jarvis_tools/git_commiter.py +5 -5
- jarvis/jarvis_tools/methodology.py +88 -53
- jarvis/jarvis_tools/project_analyzer.py +308 -0
- jarvis/jarvis_tools/rag.py +0 -5
- jarvis/jarvis_tools/read_code.py +24 -3
- jarvis/jarvis_tools/read_webpage.py +195 -81
- jarvis/jarvis_tools/registry.py +132 -11
- jarvis/jarvis_tools/search_web.py +22 -307
- jarvis/jarvis_tools/tool_generator.py +8 -10
- jarvis/jarvis_utils/__init__.py +1 -0
- jarvis/jarvis_utils/config.py +80 -76
- jarvis/jarvis_utils/embedding.py +344 -45
- jarvis/jarvis_utils/git_utils.py +9 -1
- jarvis/jarvis_utils/input.py +7 -6
- jarvis/jarvis_utils/methodology.py +384 -15
- jarvis/jarvis_utils/output.py +5 -3
- jarvis/jarvis_utils/utils.py +60 -8
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/METADATA +8 -16
- jarvis_ai_assistant-0.1.134.dist-info/RECORD +82 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/entry_points.txt +4 -3
- jarvis/jarvis_codebase/__init__.py +0 -0
- jarvis/jarvis_codebase/main.py +0 -1011
- jarvis/jarvis_tools/lsp_find_definition.py +0 -150
- jarvis/jarvis_tools/lsp_find_references.py +0 -127
- jarvis/jarvis_tools/treesitter_analyzer.py +0 -331
- jarvis/jarvis_treesitter/README.md +0 -104
- jarvis/jarvis_treesitter/__init__.py +0 -20
- jarvis/jarvis_treesitter/database.py +0 -258
- jarvis/jarvis_treesitter/example.py +0 -115
- jarvis/jarvis_treesitter/grammar_builder.py +0 -182
- jarvis/jarvis_treesitter/language.py +0 -117
- jarvis/jarvis_treesitter/symbol.py +0 -31
- jarvis/jarvis_treesitter/tools_usage.md +0 -121
- jarvis_ai_assistant-0.1.131.dist-info/RECORD +0 -85
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.131.dist-info → jarvis_ai_assistant-0.1.134.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
from typing import Dict, Any, List
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from jarvis.jarvis_agent import Agent
|
|
5
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
6
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ProjectAnalyzerTool:
|
|
10
|
+
"""
|
|
11
|
+
项目分析工具
|
|
12
|
+
使用agent分析项目结构、入口点、模块划分等信息(支持所有文件类型)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
name = "project_analyzer"
|
|
16
|
+
description = "分析项目结构、入口点、模块划分等信息,提供项目概览(支持所有文件类型)"
|
|
17
|
+
parameters = {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"properties": {
|
|
20
|
+
"root_dir": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "项目根目录路径(可选)",
|
|
23
|
+
"default": "."
|
|
24
|
+
},
|
|
25
|
+
"focus_dirs": {
|
|
26
|
+
"type": "array",
|
|
27
|
+
"items": {
|
|
28
|
+
"type": "string"
|
|
29
|
+
},
|
|
30
|
+
"description": "要重点分析的目录列表(可选)",
|
|
31
|
+
"default": []
|
|
32
|
+
},
|
|
33
|
+
"exclude_dirs": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"items": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
},
|
|
38
|
+
"description": "要排除的目录列表(可选)",
|
|
39
|
+
"default": []
|
|
40
|
+
},
|
|
41
|
+
"objective": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "描述本次项目分析的目标和用途,例如'理解项目架构以便进行重构'或'寻找性能瓶颈'",
|
|
44
|
+
"default": ""
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"required": []
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
51
|
+
"""
|
|
52
|
+
执行项目分析工具
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
args: 包含参数的字典
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
包含执行结果的字典
|
|
59
|
+
"""
|
|
60
|
+
# 存储原始目录
|
|
61
|
+
original_dir = os.getcwd()
|
|
62
|
+
|
|
63
|
+
try:
|
|
64
|
+
# 解析参数
|
|
65
|
+
root_dir = args.get("root_dir", ".")
|
|
66
|
+
focus_dirs = args.get("focus_dirs", [])
|
|
67
|
+
exclude_dirs = args.get("exclude_dirs", [])
|
|
68
|
+
objective = args.get("objective", "")
|
|
69
|
+
|
|
70
|
+
# 创建agent的system prompt
|
|
71
|
+
system_prompt = self._create_system_prompt(
|
|
72
|
+
root_dir, focus_dirs, exclude_dirs, objective
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# 创建agent的summary prompt
|
|
76
|
+
summary_prompt = self._create_summary_prompt(root_dir, objective)
|
|
77
|
+
|
|
78
|
+
# 切换到根目录
|
|
79
|
+
os.chdir(root_dir)
|
|
80
|
+
|
|
81
|
+
# 构建使用的工具
|
|
82
|
+
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
83
|
+
tool_registry = ToolRegistry()
|
|
84
|
+
tool_registry.use_tools([
|
|
85
|
+
"execute_shell",
|
|
86
|
+
"read_code",
|
|
87
|
+
"find_symbol",
|
|
88
|
+
"function_analyzer",
|
|
89
|
+
"find_caller",
|
|
90
|
+
"file_analyzer",
|
|
91
|
+
"ask_codebase"
|
|
92
|
+
])
|
|
93
|
+
|
|
94
|
+
# 创建并运行agent
|
|
95
|
+
analyzer_agent = Agent(
|
|
96
|
+
system_prompt=system_prompt,
|
|
97
|
+
name=f"ProjectAnalyzer",
|
|
98
|
+
description=f"分析项目结构、模块划分和关键组件",
|
|
99
|
+
summary_prompt=summary_prompt,
|
|
100
|
+
platform=PlatformRegistry().get_normal_platform(),
|
|
101
|
+
output_handler=[tool_registry],
|
|
102
|
+
execute_tool_confirm=False,
|
|
103
|
+
auto_complete=True
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# 运行agent并获取结果
|
|
107
|
+
task_input = f"分析项目结构、入口点、模块划分等信息,提供项目概览"
|
|
108
|
+
result = analyzer_agent.run(task_input)
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
"success": True,
|
|
112
|
+
"stdout": result,
|
|
113
|
+
"stderr": ""
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
except Exception as e:
|
|
117
|
+
PrettyOutput.print(str(e), OutputType.ERROR)
|
|
118
|
+
return {
|
|
119
|
+
"success": False,
|
|
120
|
+
"stdout": "",
|
|
121
|
+
"stderr": f"项目分析失败: {str(e)}"
|
|
122
|
+
}
|
|
123
|
+
finally:
|
|
124
|
+
# 恢复原始目录
|
|
125
|
+
os.chdir(original_dir)
|
|
126
|
+
|
|
127
|
+
def _create_system_prompt(self, root_dir: str, focus_dirs: List[str],
|
|
128
|
+
exclude_dirs: List[str], objective: str) -> str:
|
|
129
|
+
"""
|
|
130
|
+
创建Agent的system prompt
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
root_dir: 项目根目录
|
|
134
|
+
focus_dirs: 重点分析的目录列表
|
|
135
|
+
exclude_dirs: 排除的目录列表
|
|
136
|
+
objective: 分析目标
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
系统提示文本
|
|
140
|
+
"""
|
|
141
|
+
focus_dirs_str = ", ".join(focus_dirs) if focus_dirs else "整个项目"
|
|
142
|
+
exclude_dirs_str = ", ".join(exclude_dirs) if exclude_dirs else "无"
|
|
143
|
+
|
|
144
|
+
objective_text = f"\n\n## 分析目标\n{objective}" if objective else "\n\n## 分析目标\n全面了解项目结构、模块划分和关键组件"
|
|
145
|
+
|
|
146
|
+
return f"""# 项目架构分析专家
|
|
147
|
+
|
|
148
|
+
## 任务描述
|
|
149
|
+
对项目 `{root_dir}` 进行针对性分析,专注于分析目标所需的内容,生成有针对性、深入且有洞察力的项目分析报告。{objective_text}
|
|
150
|
+
|
|
151
|
+
## 工具使用优先级
|
|
152
|
+
1. **优先使用 execute_shell 执行 fd 命令**:
|
|
153
|
+
- `fd -t f -e py` 查找所有Python文件
|
|
154
|
+
- `fd -t d` 列出所有目录
|
|
155
|
+
- `fd README.md` 查找所有README文件
|
|
156
|
+
|
|
157
|
+
2. **优先使用 execute_shell 执行 rg 命令**:
|
|
158
|
+
- `rg "import" --type py` 搜索导入语句
|
|
159
|
+
- `rg "class|def" --type py` 搜索类和函数定义
|
|
160
|
+
- `rg "TODO|FIXME" --type py` 搜索代码注释
|
|
161
|
+
|
|
162
|
+
3. **优先使用 execute_shell 执行 loc 命令**:
|
|
163
|
+
- `loc` 统计所有代码行数
|
|
164
|
+
- `loc --include="*.py"` 统计Python代码行数
|
|
165
|
+
|
|
166
|
+
4. **辅以 read_code 读取关键文件**:
|
|
167
|
+
- 读取README.md、配置文件、主要模块
|
|
168
|
+
- 对于较大的文件,可读取关键部分
|
|
169
|
+
|
|
170
|
+
5. **避免使用专用分析工具**:
|
|
171
|
+
- 只有当fd、rg、loc命令和read_code工具无法满足需求时才考虑使用
|
|
172
|
+
|
|
173
|
+
## 分析范围
|
|
174
|
+
- 项目根目录: `{root_dir}`
|
|
175
|
+
- 重点分析: {focus_dirs_str}
|
|
176
|
+
- 排除目录: {exclude_dirs_str}
|
|
177
|
+
|
|
178
|
+
## 分析策略
|
|
179
|
+
1. 在一切分析开始前,先使用loc确定项目的主要编程语言和技术栈
|
|
180
|
+
2. 理解分析目标,确定你需要寻找什么信息
|
|
181
|
+
3. 灵活采用适合目标的分析方法,不受预设分析框架的限制
|
|
182
|
+
4. 有选择地探索项目,只关注与目标直接相关的部分
|
|
183
|
+
5. 根据目标需要自行判断分析的深度和广度
|
|
184
|
+
6. 保证分析的完整性,收集充分的信息后再得出结论
|
|
185
|
+
|
|
186
|
+
## 分析步骤
|
|
187
|
+
以下步骤应根据具体分析目标灵活应用:
|
|
188
|
+
|
|
189
|
+
1. **确定项目的编程语言和技术栈**:
|
|
190
|
+
- 使用 `loc` 统计各类文件数量和分布
|
|
191
|
+
- 使用 `fd package.json` 或 `fd requirements.txt` 查找依赖配置文件
|
|
192
|
+
- 使用 `read_code` 读取配置文件,确定使用的主要框架和依赖
|
|
193
|
+
|
|
194
|
+
2. **梳理项目结构**:
|
|
195
|
+
- 使用 `fd -t d -d 3` 识别三层以内的目录结构
|
|
196
|
+
- 使用 `fd README.md` 查找并阅读项目说明文件
|
|
197
|
+
- 使用 `fd -t f -d 1` 查看根目录下的主要文件
|
|
198
|
+
|
|
199
|
+
3. **定位核心组件**:
|
|
200
|
+
- 使用 `fd -t f -e py` 找出所有Python文件(或其他语言文件)
|
|
201
|
+
- 使用 `rg "class\\s+[A-Z]" --type py` 查找主要类定义
|
|
202
|
+
- 使用 `rg "def\\s+main|if\\s+__name__\\s*==\\s*['\"]__main__['\"]" --type py` 查找入口点
|
|
203
|
+
|
|
204
|
+
4. **分析入口点和执行流程**:
|
|
205
|
+
- 使用 `read_code` 读取入口文件内容
|
|
206
|
+
- 使用 `rg "import|from" 入口文件路径` 查找导入的模块
|
|
207
|
+
- 分析初始化和主要执行流程
|
|
208
|
+
|
|
209
|
+
5. **研究核心实现**:
|
|
210
|
+
- 深入分析与分析目标相关的关键代码
|
|
211
|
+
- 使用 `read_code` 读取关键文件内容
|
|
212
|
+
- 使用 `rg` 搜索特定功能的实现
|
|
213
|
+
|
|
214
|
+
6. **总结并提供见解**:
|
|
215
|
+
- 基于分析形成对项目的整体理解
|
|
216
|
+
- 提供与分析目标直接相关的关键发现
|
|
217
|
+
- 做出有建设性的评价和建议
|
|
218
|
+
|
|
219
|
+
## 常用分析命令
|
|
220
|
+
|
|
221
|
+
### 项目结构分析
|
|
222
|
+
- `fd -t d -d 3` 列出三层以内的目录结构
|
|
223
|
+
- `fd -t f -e py -g "test*" -d 3` 查找前三层目录中的Python测试文件
|
|
224
|
+
- `fd -t f -e py | wc -l` 统计Python文件数量
|
|
225
|
+
- `fd -t f -e py -o -e js -o -e html -o -e css` 查找所有前端和后端文件
|
|
226
|
+
|
|
227
|
+
### 代码内容分析
|
|
228
|
+
- `rg "^\\s*class\\s+[A-Z]" --type py` 查找Python类定义
|
|
229
|
+
- `rg "^\\s*def\\s+" --type py` 查找Python函数定义
|
|
230
|
+
- `rg "import|from\\s+.+\\s+import" --type py` 查找Python导入语句
|
|
231
|
+
- `rg "CREATE TABLE" --type sql` 查找数据库表定义
|
|
232
|
+
|
|
233
|
+
### 代码统计分析
|
|
234
|
+
- `loc` 获取项目总体代码统计
|
|
235
|
+
- `loc --include="*.py"` 统计Python代码量
|
|
236
|
+
- `loc --include="*.js" --include="*.jsx" --include="*.ts" --include="*.tsx"` 统计JavaScript/TypeScript代码量
|
|
237
|
+
- `loc --exclude="test"` 排除测试代码后的统计
|
|
238
|
+
|
|
239
|
+
### 依赖分析
|
|
240
|
+
- `read_code requirements.txt` 读取Python依赖
|
|
241
|
+
- `read_code package.json` 读取Node.js依赖
|
|
242
|
+
- `read_code go.mod` 读取Go依赖
|
|
243
|
+
- `read_code pom.xml` 读取Java Maven依赖
|
|
244
|
+
|
|
245
|
+
记住:始终将分析目标作为分析过程的指导原则,不必为了完整性而执行与目标无关的步骤。
|
|
246
|
+
|
|
247
|
+
## 分析框架适应
|
|
248
|
+
|
|
249
|
+
根据不同类型的项目架构,应调整分析重点:
|
|
250
|
+
|
|
251
|
+
### 单体应用
|
|
252
|
+
- 核心业务逻辑和数据流
|
|
253
|
+
- 模块划分和内部依赖
|
|
254
|
+
- 扩展点和插件机制
|
|
255
|
+
|
|
256
|
+
### 微服务架构
|
|
257
|
+
- 服务边界和接口定义
|
|
258
|
+
- 服务间通信和数据交换
|
|
259
|
+
- 服务发现和配置管理
|
|
260
|
+
|
|
261
|
+
### 前端应用
|
|
262
|
+
- 组件结构和状态管理
|
|
263
|
+
- 路由和页面转换
|
|
264
|
+
- API调用和数据处理
|
|
265
|
+
|
|
266
|
+
### 数据处理系统
|
|
267
|
+
- 数据流向和转换过程
|
|
268
|
+
- 算法实现和优化方式
|
|
269
|
+
- 并行处理和性能考量
|
|
270
|
+
|
|
271
|
+
## 输出要求
|
|
272
|
+
- 直接回应分析目标的关键问题
|
|
273
|
+
- 提供与目标相关的深入洞察
|
|
274
|
+
- 分析内容应直接服务于分析目标
|
|
275
|
+
- 确保全面收集相关信息后再形成结论
|
|
276
|
+
- 避免与目标无关的冗余信息
|
|
277
|
+
- 使用具体代码路径和示例支持分析结论
|
|
278
|
+
- 提供针对分析目标的具体建议和改进方向"""
|
|
279
|
+
|
|
280
|
+
def _create_summary_prompt(self, root_dir: str, objective: str) -> str:
|
|
281
|
+
"""
|
|
282
|
+
创建Agent的summary prompt
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
root_dir: 项目根目录
|
|
286
|
+
objective: 分析目标
|
|
287
|
+
|
|
288
|
+
Returns:
|
|
289
|
+
总结提示文本
|
|
290
|
+
"""
|
|
291
|
+
objective_text = f"\n\n## 具体分析目标\n{objective}" if objective else ""
|
|
292
|
+
|
|
293
|
+
return f"""# 项目分析报告: `{root_dir}`{objective_text}
|
|
294
|
+
|
|
295
|
+
## 报告要求
|
|
296
|
+
生成一份完全以分析目标为导向的项目分析报告。不要遵循固定的报告模板,而是完全根据分析目标来组织内容:
|
|
297
|
+
|
|
298
|
+
- 首先详细说明项目的主要编程语言、技术栈、框架和依赖
|
|
299
|
+
- 专注回答分析目标提出的问题
|
|
300
|
+
- 只包含与分析目标直接相关的发现和洞察
|
|
301
|
+
- 完全跳过与分析目标无关的内容,无需做全面分析
|
|
302
|
+
- 分析深度应与目标的具体需求匹配
|
|
303
|
+
- 使用具体的代码路径和示例支持你的观点
|
|
304
|
+
- 确保在得出结论前已全面收集和分析相关信息,避免基于部分信息形成不完整或偏颇的判断
|
|
305
|
+
- 根据分析目标灵活组织报告结构,不必包含所有传统的项目分析章节
|
|
306
|
+
- 以清晰的Markdown格式呈现,简洁明了
|
|
307
|
+
|
|
308
|
+
在分析中保持灵活性,避免固定思维模式。你的任务不是提供全面的项目概览,而是直接解决分析目标中提出的具体问题。"""
|
jarvis/jarvis_tools/rag.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from typing import Dict, Any
|
|
2
2
|
import os
|
|
3
3
|
from jarvis.jarvis_rag.main import RAGTool as RAGCore
|
|
4
|
-
from jarvis.jarvis_utils.config import dont_use_local_model
|
|
5
4
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
6
5
|
|
|
7
6
|
class RAGTool:
|
|
@@ -27,10 +26,6 @@ class RAGTool:
|
|
|
27
26
|
"required": ["dir", "question"]
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
@staticmethod
|
|
31
|
-
def check() -> bool:
|
|
32
|
-
return not dont_use_local_model()
|
|
33
|
-
|
|
34
29
|
def __init__(self):
|
|
35
30
|
"""Initialize RAG tool"""
|
|
36
31
|
self.rag_instances = {} # Cache RAG instances for different directories
|
jarvis/jarvis_tools/read_code.py
CHANGED
|
@@ -7,7 +7,7 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
|
7
7
|
|
|
8
8
|
class ReadCodeTool:
|
|
9
9
|
name = "read_code"
|
|
10
|
-
description = "
|
|
10
|
+
description = "代码阅读与分析工具,用于读取源代码文件并添加行号,针对代码文件优化,提供更好的格式化输出和行号显示,适用于代码分析、审查和理解代码实现的场景"
|
|
11
11
|
parameters = {
|
|
12
12
|
"type": "object",
|
|
13
13
|
"properties": {
|
|
@@ -29,6 +29,16 @@ class ReadCodeTool:
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
def _handle_single_file(self, filepath: str, start_line: int = 1, end_line: int = -1) -> Dict[str, Any]:
|
|
32
|
+
"""处理单个文件的读取操作
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
filepath (str): 文件路径
|
|
36
|
+
start_line (int): 起始行号,默认为1
|
|
37
|
+
end_line (int): 结束行号,默认为-1表示文件末尾
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Dict[str, Any]: 包含成功状态、输出内容和错误信息的字典
|
|
41
|
+
"""
|
|
32
42
|
try:
|
|
33
43
|
abs_path = os.path.abspath(filepath)
|
|
34
44
|
with yaspin(text=f"正在读取文件: {abs_path}...", color="cyan") as spinner:
|
|
@@ -73,19 +83,22 @@ class ReadCodeTool:
|
|
|
73
83
|
# 添加行号并构建输出内容
|
|
74
84
|
selected_lines = lines[start_line-1:end_line]
|
|
75
85
|
numbered_content = "".join(
|
|
76
|
-
[f"{i:4d}
|
|
86
|
+
[f"{i:4d}:{line}"
|
|
77
87
|
for i, line in enumerate(selected_lines, start=start_line)]
|
|
78
88
|
)
|
|
79
89
|
|
|
80
90
|
# 构建输出格式
|
|
81
91
|
output = (
|
|
82
92
|
f"\n🔍 文件: {abs_path}\n"
|
|
83
|
-
f"📄 原始行号: {start_line}-{end_line} (共{
|
|
93
|
+
f"📄 原始行号: {start_line}-{end_line} (共{total_lines}行) \n\n"
|
|
84
94
|
f"{numbered_content}\n"
|
|
85
95
|
f"{'='*80}\n"
|
|
86
96
|
)
|
|
87
97
|
spinner.text = f"文件读取完成: {abs_path}"
|
|
88
98
|
spinner.ok("✅")
|
|
99
|
+
|
|
100
|
+
PrettyOutput.print(output, OutputType.SUCCESS)
|
|
101
|
+
|
|
89
102
|
return {
|
|
90
103
|
"success": True,
|
|
91
104
|
"stdout": output,
|
|
@@ -101,6 +114,14 @@ class ReadCodeTool:
|
|
|
101
114
|
}
|
|
102
115
|
|
|
103
116
|
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
117
|
+
"""执行代码读取操作
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
args (Dict): 包含文件列表的参数字典
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Dict[str, Any]: 包含成功状态、输出内容和错误信息的字典
|
|
124
|
+
"""
|
|
104
125
|
try:
|
|
105
126
|
if "files" not in args or not isinstance(args["files"], list):
|
|
106
127
|
return {
|