auto-coder 0.1.388__py3-none-any.whl → 0.1.390__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 auto-coder might be problematic. Click here for more details.
- {auto_coder-0.1.388.dist-info → auto_coder-0.1.390.dist-info}/METADATA +2 -2
- {auto_coder-0.1.388.dist-info → auto_coder-0.1.390.dist-info}/RECORD +22 -18
- autocoder/auto_coder_rag.py +5 -0
- autocoder/auto_coder_runner.py +12 -3
- autocoder/chat_auto_coder.py +6 -2
- autocoder/common/__init__.py +1 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +16 -17
- autocoder/memory/__init__.py +0 -7
- autocoder/memory/active_changes.py +255 -0
- autocoder/memory/active_diagrams.py +302 -0
- autocoder/memory/active_documents.py +287 -0
- autocoder/memory/active_header.py +88 -0
- autocoder/memory/active_package.py +109 -365
- autocoder/rag/api_server.py +9 -2
- autocoder/rag/lang.py +4 -0
- autocoder/rag/long_context_rag.py +11 -2
- autocoder/rag/qa_conversation_strategy.py +5 -3
- autocoder/version.py +1 -1
- {auto_coder-0.1.388.dist-info → auto_coder-0.1.390.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.388.dist-info → auto_coder-0.1.390.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.388.dist-info → auto_coder-0.1.390.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.388.dist-info → auto_coder-0.1.390.dist-info}/top_level.txt +0 -0
|
@@ -13,6 +13,12 @@ from loguru import logger as global_logger
|
|
|
13
13
|
from autocoder.common.token_cost_caculate import TokenCostCalculator, TokenUsageStats
|
|
14
14
|
from autocoder.common import AutoCoderArgs
|
|
15
15
|
|
|
16
|
+
# 导入新的独立模块
|
|
17
|
+
from .active_header import ActiveHeader
|
|
18
|
+
from .active_changes import ActiveChanges
|
|
19
|
+
from .active_documents import ActiveDocuments
|
|
20
|
+
from .active_diagrams import ActiveDiagrams
|
|
21
|
+
|
|
16
22
|
class ActivePackage:
|
|
17
23
|
"""
|
|
18
24
|
ActivePackage负责生成每个目录的活动上下文文档,
|
|
@@ -33,7 +39,13 @@ class ActivePackage:
|
|
|
33
39
|
self.llm = llm
|
|
34
40
|
self.product_mode = product_mode
|
|
35
41
|
# 创建专用的 logger 实例
|
|
36
|
-
self.logger = global_logger.bind(name="ActivePackage")
|
|
42
|
+
self.logger = global_logger.bind(name="ActivePackage")
|
|
43
|
+
|
|
44
|
+
# 初始化四个独立的处理模块
|
|
45
|
+
self.header_processor = ActiveHeader()
|
|
46
|
+
self.changes_processor = ActiveChanges(llm, product_mode)
|
|
47
|
+
self.documents_processor = ActiveDocuments(llm, product_mode)
|
|
48
|
+
self.diagrams_processor = ActiveDiagrams(llm, product_mode)
|
|
37
49
|
|
|
38
50
|
def generate_active_file(self, context: Dict[str, Any], query: str,
|
|
39
51
|
existing_file_path: Optional[str] = None,
|
|
@@ -77,7 +89,7 @@ class ActivePackage:
|
|
|
77
89
|
# 根据是否有现有内容选择不同的生成方式
|
|
78
90
|
if existing_content:
|
|
79
91
|
# 有现有内容,使用更新模式
|
|
80
|
-
file_content, usage_stats = self.generate_updated_active_file(enhanced_context, query, existing_content,args)
|
|
92
|
+
file_content, usage_stats = self.generate_updated_active_file(enhanced_context, query, existing_content, args)
|
|
81
93
|
# 合并token和费用统计
|
|
82
94
|
total_stats["total_tokens"] += usage_stats["total_tokens"]
|
|
83
95
|
total_stats["input_tokens"] += usage_stats["input_tokens"]
|
|
@@ -85,7 +97,7 @@ class ActivePackage:
|
|
|
85
97
|
total_stats["cost"] += usage_stats["cost"]
|
|
86
98
|
else:
|
|
87
99
|
# 无现有内容,使用创建模式
|
|
88
|
-
file_content, usage_stats = self.generate_new_active_file(enhanced_context, query,args)
|
|
100
|
+
file_content, usage_stats = self.generate_new_active_file(enhanced_context, query, args)
|
|
89
101
|
# 合并token和费用统计
|
|
90
102
|
total_stats["total_tokens"] += usage_stats["total_tokens"]
|
|
91
103
|
total_stats["input_tokens"] += usage_stats["input_tokens"]
|
|
@@ -172,78 +184,63 @@ class ActivePackage:
|
|
|
172
184
|
|
|
173
185
|
return enhanced_context
|
|
174
186
|
|
|
175
|
-
def generate_new_active_file(self, context: Dict[str, Any], query: str,args:AutoCoderArgs) -> Tuple[str, Dict[str, Any]]:
|
|
187
|
+
def generate_new_active_file(self, context: Dict[str, Any], query: str, args: AutoCoderArgs) -> Tuple[str, Dict[str, Any]]:
|
|
176
188
|
"""
|
|
177
189
|
生成全新的活动文件内容
|
|
178
190
|
|
|
179
191
|
Args:
|
|
180
192
|
context: 目录上下文字典
|
|
181
193
|
query: 用户查询/需求
|
|
194
|
+
args: AutoCoderArgs实例,包含配置信息
|
|
182
195
|
|
|
183
196
|
Returns:
|
|
184
197
|
Tuple[str, Dict[str, Any]]: 新生成的活动文件内容和token使用及费用信息
|
|
185
198
|
"""
|
|
186
199
|
try:
|
|
187
|
-
#
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
# 使用TokenCostCalculator跟踪token使用情况
|
|
195
|
-
token_calculator = TokenCostCalculator(logger_name="ActivePackage",args=args)
|
|
196
|
-
current_change_stats: TokenUsageStats = token_calculator.track_token_usage(
|
|
197
|
-
llm=self.llm,
|
|
198
|
-
meta_holder=meta_holder_current_change,
|
|
199
|
-
operation_name="Current Change Generation",
|
|
200
|
-
start_time=start_time_current_change,
|
|
201
|
-
end_time=end_time_current_change,
|
|
202
|
-
product_mode=self.product_mode
|
|
203
|
-
)
|
|
200
|
+
# 初始化总统计
|
|
201
|
+
total_stats = {
|
|
202
|
+
"total_tokens": 0,
|
|
203
|
+
"input_tokens": 0,
|
|
204
|
+
"output_tokens": 0,
|
|
205
|
+
"cost": 0.0
|
|
206
|
+
}
|
|
204
207
|
|
|
205
|
-
|
|
208
|
+
# 1. 生成标题部分
|
|
209
|
+
header = self.header_processor.generate_header(context)
|
|
206
210
|
|
|
207
|
-
# 2.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
# 2. 生成当前变更部分
|
|
212
|
+
current_change, changes_stats = self.changes_processor.generate_changes(context, query, args)
|
|
213
|
+
# 合并统计
|
|
214
|
+
total_stats["total_tokens"] += changes_stats["total_tokens"]
|
|
215
|
+
total_stats["input_tokens"] += changes_stats["input_tokens"]
|
|
216
|
+
total_stats["output_tokens"] += changes_stats["output_tokens"]
|
|
217
|
+
total_stats["cost"] += changes_stats["cost"]
|
|
213
218
|
|
|
214
|
-
#
|
|
215
|
-
document_stats
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
product_mode=self.product_mode
|
|
222
|
-
)
|
|
219
|
+
# 3. 生成文档部分
|
|
220
|
+
document, document_stats = self.documents_processor.generate_documents(context, query, args)
|
|
221
|
+
# 合并统计
|
|
222
|
+
total_stats["total_tokens"] += document_stats["total_tokens"]
|
|
223
|
+
total_stats["input_tokens"] += document_stats["input_tokens"]
|
|
224
|
+
total_stats["output_tokens"] += document_stats["output_tokens"]
|
|
225
|
+
total_stats["cost"] += document_stats["cost"]
|
|
223
226
|
|
|
224
|
-
|
|
227
|
+
# 4. 生成关系图表部分
|
|
228
|
+
diagrams, diagrams_stats = self.diagrams_processor.generate_diagrams(context, query, args)
|
|
229
|
+
# 合并统计
|
|
230
|
+
total_stats["total_tokens"] += diagrams_stats["total_tokens"]
|
|
231
|
+
total_stats["input_tokens"] += diagrams_stats["input_tokens"]
|
|
232
|
+
total_stats["output_tokens"] += diagrams_stats["output_tokens"]
|
|
233
|
+
total_stats["cost"] += diagrams_stats["cost"]
|
|
225
234
|
|
|
226
|
-
|
|
227
|
-
total_tokens = current_change_stats.total_tokens + document_stats.total_tokens
|
|
228
|
-
input_tokens = current_change_stats.input_tokens + document_stats.input_tokens
|
|
229
|
-
output_tokens = current_change_stats.output_tokens + document_stats.output_tokens
|
|
230
|
-
total_cost = current_change_stats.total_cost + document_stats.total_cost
|
|
231
|
-
self.logger.info(f"Total Usage - Tokens: {total_tokens}, Input: {input_tokens}, Output: {output_tokens}, Cost: ${total_cost:.6f}")
|
|
235
|
+
self.logger.info(f"Total Usage - Tokens: {total_stats['total_tokens']}, Input: {total_stats['input_tokens']}, Output: {total_stats['output_tokens']}, Cost: ${total_stats['cost']:.6f}")
|
|
232
236
|
|
|
233
|
-
#
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
# 3. 组合成完整的活动文件内容
|
|
237
|
-
file_content = f"# 活动上下文 - {dir_name}\n\n"
|
|
237
|
+
# 5. 组合成完整的活动文件内容
|
|
238
|
+
file_content = header
|
|
238
239
|
file_content += f"## 当前变更\n\n{current_change}\n\n"
|
|
239
|
-
file_content += f"## 文档\n\n{document}\n"
|
|
240
|
+
file_content += f"## 文档\n\n{document}\n\n"
|
|
241
|
+
file_content += f"## 关系图表\n\n{diagrams}\n"
|
|
240
242
|
|
|
241
|
-
return file_content,
|
|
242
|
-
"total_tokens": total_tokens,
|
|
243
|
-
"input_tokens": input_tokens,
|
|
244
|
-
"output_tokens": output_tokens,
|
|
245
|
-
"cost": total_cost
|
|
246
|
-
}
|
|
243
|
+
return file_content, total_stats
|
|
247
244
|
except Exception as e:
|
|
248
245
|
self.logger.error(f"Error generating new active file: {e}")
|
|
249
246
|
# 返回错误信息和空统计
|
|
@@ -256,43 +253,31 @@ class ActivePackage:
|
|
|
256
253
|
err_content = f"# 生成文档时出错 - {os.path.basename(context.get('directory_path', '未知目录'))}\n\n错误: {str(e)}"
|
|
257
254
|
return err_content, empty_stats
|
|
258
255
|
|
|
259
|
-
def extract_sections(self, content: str) -> Tuple[str, str, str]:
|
|
256
|
+
def extract_sections(self, content: str) -> Tuple[str, str, str, str]:
|
|
260
257
|
"""
|
|
261
|
-
|
|
258
|
+
从现有内容中提取标题、当前变更、文档和图表部分
|
|
262
259
|
|
|
263
260
|
Args:
|
|
264
261
|
content: 现有文件内容
|
|
265
262
|
|
|
266
263
|
Returns:
|
|
267
|
-
Tuple[str, str, str]:
|
|
264
|
+
Tuple[str, str, str, str]: 标题部分、当前变更部分、文档部分、图表部分
|
|
268
265
|
"""
|
|
269
|
-
# 默认值
|
|
270
|
-
header = "# 活动上下文\n\n"
|
|
271
|
-
current_change_section = ""
|
|
272
|
-
document_section = ""
|
|
273
|
-
|
|
274
266
|
try:
|
|
275
|
-
#
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
267
|
+
# 使用各个处理器提取对应部分
|
|
268
|
+
header = self.header_processor.extract_header(content)
|
|
269
|
+
current_change_section = self.changes_processor.extract_changes(content)
|
|
270
|
+
document_section = self.documents_processor.extract_documents(content)
|
|
271
|
+
diagrams_section = self.diagrams_processor.extract_diagrams(content)
|
|
279
272
|
|
|
280
|
-
|
|
281
|
-
current_change_match = re.search(r'## 当前变更\s*\n(.*?)(?=\n## |$)', content, re.DOTALL)
|
|
282
|
-
if current_change_match:
|
|
283
|
-
current_change_section = current_change_match.group(1).strip()
|
|
284
|
-
|
|
285
|
-
# 提取文档部分
|
|
286
|
-
document_match = re.search(r'## 文档\s*\n(.*?)(?=\n## |$)', content, re.DOTALL)
|
|
287
|
-
if document_match:
|
|
288
|
-
document_section = document_match.group(1).strip()
|
|
289
|
-
|
|
290
|
-
return header, current_change_section, document_section
|
|
273
|
+
return header, current_change_section, document_section, diagrams_section
|
|
291
274
|
except Exception as e:
|
|
292
275
|
self.logger.error(f"Error extracting sections: {e}")
|
|
293
|
-
|
|
276
|
+
# 返回默认值
|
|
277
|
+
default_header = "# 活动上下文\n\n"
|
|
278
|
+
return default_header, "", "", ""
|
|
294
279
|
|
|
295
|
-
def generate_updated_active_file(self, context: Dict[str, Any], query: str, existing_content: str,args:AutoCoderArgs) -> Tuple[str, Dict[str, Any]]:
|
|
280
|
+
def generate_updated_active_file(self, context: Dict[str, Any], query: str, existing_content: str, args: AutoCoderArgs) -> Tuple[str, Dict[str, Any]]:
|
|
296
281
|
"""
|
|
297
282
|
基于现有内容生成更新后的活动文件内容
|
|
298
283
|
|
|
@@ -300,71 +285,62 @@ class ActivePackage:
|
|
|
300
285
|
context: 目录上下文字典
|
|
301
286
|
query: 用户查询/需求
|
|
302
287
|
existing_content: 现有的活动文件内容
|
|
288
|
+
args: AutoCoderArgs实例,包含配置信息
|
|
303
289
|
|
|
304
290
|
Returns:
|
|
305
291
|
Tuple[str, Dict[str, Any]]: 更新后的活动文件内容和token使用及费用信息
|
|
306
292
|
"""
|
|
307
293
|
try:
|
|
308
|
-
#
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
meta_holder_current_change).run(context, query, existing_current_change)
|
|
316
|
-
end_time_current_change = time.monotonic()
|
|
294
|
+
# 初始化总统计
|
|
295
|
+
total_stats = {
|
|
296
|
+
"total_tokens": 0,
|
|
297
|
+
"input_tokens": 0,
|
|
298
|
+
"output_tokens": 0,
|
|
299
|
+
"cost": 0.0
|
|
300
|
+
}
|
|
317
301
|
|
|
318
|
-
#
|
|
319
|
-
|
|
320
|
-
update_current_change_stats: TokenUsageStats = token_calculator.track_token_usage(
|
|
321
|
-
llm=self.llm,
|
|
322
|
-
meta_holder=meta_holder_current_change,
|
|
323
|
-
operation_name="Update Current Change",
|
|
324
|
-
start_time=start_time_current_change,
|
|
325
|
-
end_time=end_time_current_change,
|
|
326
|
-
product_mode=self.product_mode
|
|
327
|
-
)
|
|
302
|
+
# 1. 从现有内容中提取各部分
|
|
303
|
+
header, existing_current_change, existing_document, existing_diagrams = self.extract_sections(existing_content)
|
|
328
304
|
|
|
329
|
-
|
|
305
|
+
# 2. 更新标题部分
|
|
306
|
+
updated_header = self.header_processor.update_header(context, header)
|
|
330
307
|
|
|
331
|
-
# 3.
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
308
|
+
# 3. 更新当前变更部分
|
|
309
|
+
updated_current_change, changes_stats = self.changes_processor.update_changes(
|
|
310
|
+
context, query, existing_current_change, args)
|
|
311
|
+
# 合并统计
|
|
312
|
+
total_stats["total_tokens"] += changes_stats["total_tokens"]
|
|
313
|
+
total_stats["input_tokens"] += changes_stats["input_tokens"]
|
|
314
|
+
total_stats["output_tokens"] += changes_stats["output_tokens"]
|
|
315
|
+
total_stats["cost"] += changes_stats["cost"]
|
|
337
316
|
|
|
338
|
-
#
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
)
|
|
317
|
+
# 4. 更新文档部分
|
|
318
|
+
updated_document, document_stats = self.documents_processor.update_documents(
|
|
319
|
+
context, query, existing_document, args)
|
|
320
|
+
# 合并统计
|
|
321
|
+
total_stats["total_tokens"] += document_stats["total_tokens"]
|
|
322
|
+
total_stats["input_tokens"] += document_stats["input_tokens"]
|
|
323
|
+
total_stats["output_tokens"] += document_stats["output_tokens"]
|
|
324
|
+
total_stats["cost"] += document_stats["cost"]
|
|
347
325
|
|
|
348
|
-
|
|
326
|
+
# 5. 更新关系图表部分
|
|
327
|
+
updated_diagrams, diagrams_stats = self.diagrams_processor.update_diagrams(
|
|
328
|
+
context, query, existing_diagrams, args)
|
|
329
|
+
# 合并统计
|
|
330
|
+
total_stats["total_tokens"] += diagrams_stats["total_tokens"]
|
|
331
|
+
total_stats["input_tokens"] += diagrams_stats["input_tokens"]
|
|
332
|
+
total_stats["output_tokens"] += diagrams_stats["output_tokens"]
|
|
333
|
+
total_stats["cost"] += diagrams_stats["cost"]
|
|
349
334
|
|
|
350
|
-
|
|
351
|
-
total_tokens = update_current_change_stats.total_tokens + update_document_stats.total_tokens
|
|
352
|
-
input_tokens = update_current_change_stats.input_tokens + update_document_stats.input_tokens
|
|
353
|
-
output_tokens = update_current_change_stats.output_tokens + update_document_stats.output_tokens
|
|
354
|
-
total_cost = update_current_change_stats.total_cost + update_document_stats.total_cost
|
|
355
|
-
self.logger.info(f"Total Usage - Tokens: {total_tokens}, Input: {input_tokens}, Output: {output_tokens}, Cost: ${total_cost:.6f}")
|
|
335
|
+
self.logger.info(f"Total Usage - Tokens: {total_stats['total_tokens']}, Input: {total_stats['input_tokens']}, Output: {total_stats['output_tokens']}, Cost: ${total_stats['cost']:.6f}")
|
|
356
336
|
|
|
357
|
-
#
|
|
358
|
-
file_content =
|
|
337
|
+
# 6. 组合成完整的活动文件内容
|
|
338
|
+
file_content = updated_header
|
|
359
339
|
file_content += f"## 当前变更\n\n{updated_current_change}\n\n"
|
|
360
|
-
file_content += f"## 文档\n\n{updated_document}\n"
|
|
340
|
+
file_content += f"## 文档\n\n{updated_document}\n\n"
|
|
341
|
+
file_content += f"## 关系图表\n\n{updated_diagrams}\n"
|
|
361
342
|
|
|
362
|
-
return file_content,
|
|
363
|
-
"total_tokens": total_tokens,
|
|
364
|
-
"input_tokens": input_tokens,
|
|
365
|
-
"output_tokens": output_tokens,
|
|
366
|
-
"cost": total_cost
|
|
367
|
-
}
|
|
343
|
+
return file_content, total_stats
|
|
368
344
|
except Exception as e:
|
|
369
345
|
self.logger.error(f"Error updating active file: {e}")
|
|
370
346
|
# 返回错误信息和空统计
|
|
@@ -376,236 +352,4 @@ class ActivePackage:
|
|
|
376
352
|
}
|
|
377
353
|
dir_name = os.path.basename(context.get('directory_path', '未知目录'))
|
|
378
354
|
err_content = f"# 更新文档时出错 - {dir_name}\n\n错误: {str(e)}\n\n## 原始内容\n\n{existing_content}"
|
|
379
|
-
return err_content, empty_stats
|
|
380
|
-
|
|
381
|
-
@byzerllm.prompt()
|
|
382
|
-
def update_current_change(self, context: Dict[str, Any], query: str, existing_current_change: str) -> str:
|
|
383
|
-
"""
|
|
384
|
-
请基于现有的"当前变更"文档和新的变更信息,生成一个更新后的"当前变更"部分。
|
|
385
|
-
|
|
386
|
-
现有的"当前变更"内容:
|
|
387
|
-
```
|
|
388
|
-
{{ existing_current_change }}
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
当前需求:
|
|
392
|
-
{{ query }}
|
|
393
|
-
|
|
394
|
-
目录:{{ context.directory_path }}
|
|
395
|
-
|
|
396
|
-
最新变更的文件:
|
|
397
|
-
{% for file in context.changed_files %}
|
|
398
|
-
- {{ file.path }}
|
|
399
|
-
{% endfor %}
|
|
400
|
-
|
|
401
|
-
{% if context.file_diffs %}
|
|
402
|
-
文件变更摘要:
|
|
403
|
-
{% for diff in context.file_diffs %}
|
|
404
|
-
- {{ diff.path }}: {% if diff.type == 'modified' %}修改 (从{{ diff.before_lines }}行到{{ diff.after_lines }}行){% elif diff.type == 'added' %}新增{% elif diff.type == 'deleted' %}删除{% endif %}
|
|
405
|
-
{% endfor %}
|
|
406
|
-
{% endif %}
|
|
407
|
-
|
|
408
|
-
{% if context.changed_files and context.changed_files[0].has_diff %}
|
|
409
|
-
变更前后的代码对比:
|
|
410
|
-
{% for file in context.changed_files %}
|
|
411
|
-
{% if file.has_diff %}
|
|
412
|
-
文件: {{ file.path }}
|
|
413
|
-
变更前:
|
|
414
|
-
```
|
|
415
|
-
{{ file.before_content }}
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
变更后:
|
|
419
|
-
```
|
|
420
|
-
{{ file.after_content }}
|
|
421
|
-
```
|
|
422
|
-
{% endif %}
|
|
423
|
-
{% endfor %}
|
|
424
|
-
{% endif %}
|
|
425
|
-
|
|
426
|
-
请执行以下任务:
|
|
427
|
-
1. 保留现有文档中的有用历史信息
|
|
428
|
-
2. 添加最新的变更信息,重点描述当前需求相关的变更
|
|
429
|
-
3. 明确指出新的变更与之前变更的关系(如继续完善、修复问题、新增功能等)
|
|
430
|
-
4. 确保变更描述清晰、具体,并表明每个文件的变更内容和目的
|
|
431
|
-
5. 如果有冲突的信息,优先保留最新的信息
|
|
432
|
-
6. 变更部分最多保留20条。
|
|
433
|
-
|
|
434
|
-
你的回答应该是一个完整的"当前变更"部分内容,不需要包含标题。
|
|
435
|
-
"""
|
|
436
|
-
|
|
437
|
-
@byzerllm.prompt()
|
|
438
|
-
def update_document(self, context: Dict[str, Any], query: str, existing_document: str) -> str:
|
|
439
|
-
"""
|
|
440
|
-
请基于现有的"文档"部分和新的变更信息,生成一个更新后的"文档"部分。
|
|
441
|
-
|
|
442
|
-
现有的"文档"内容:
|
|
443
|
-
```
|
|
444
|
-
{{ existing_document }}
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
当前需求:
|
|
448
|
-
{{ query }}
|
|
449
|
-
|
|
450
|
-
目录:{{ context.directory_path }}
|
|
451
|
-
|
|
452
|
-
相关文件:
|
|
453
|
-
{% for file in context.changed_files %}
|
|
454
|
-
- {{ file.path }}
|
|
455
|
-
{% endfor %}
|
|
456
|
-
|
|
457
|
-
{% if context.current_files %}
|
|
458
|
-
当前目录中的其他相关文件:
|
|
459
|
-
{% for file in context.current_files %}
|
|
460
|
-
- {{ file.path }}
|
|
461
|
-
{% endfor %}
|
|
462
|
-
{% endif %}
|
|
463
|
-
|
|
464
|
-
{% if context.file_diffs %}
|
|
465
|
-
文件变更摘要:
|
|
466
|
-
{% for diff in context.file_diffs %}
|
|
467
|
-
- {{ diff.path }}: {% if diff.type == 'modified' %}修改 (从{{ diff.before_lines }}行到{{ diff.after_lines }}行){% elif diff.type == 'added' %}新增{% elif diff.type == 'deleted' %}删除{% endif %}
|
|
468
|
-
{% endfor %}
|
|
469
|
-
{% endif %}
|
|
470
|
-
|
|
471
|
-
{% if context.changed_files and context.changed_files[0].has_diff %}
|
|
472
|
-
变更前后的代码对比:
|
|
473
|
-
{% for file in context.changed_files %}
|
|
474
|
-
{% if file.has_diff %}
|
|
475
|
-
文件: {{ file.path }}
|
|
476
|
-
变更前:
|
|
477
|
-
```
|
|
478
|
-
{{ file.before_content }}
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
变更后:
|
|
482
|
-
```
|
|
483
|
-
{{ file.after_content }}
|
|
484
|
-
```
|
|
485
|
-
{% endif %}
|
|
486
|
-
{% endfor %}
|
|
487
|
-
{% endif %}
|
|
488
|
-
|
|
489
|
-
请执行以下任务:
|
|
490
|
-
1. 保留现有文档中的准确信息
|
|
491
|
-
2. 更新每个文件的文档,反映最新的变更
|
|
492
|
-
3. 如果有新文件,为其创建完整的文档
|
|
493
|
-
4. 确保文档格式一致性,每个文件的文档包含:功能、关键组件、变更影响、与其他文件的关系
|
|
494
|
-
5. 如有冲突信息,优先保留最新信息,但保留历史上下文
|
|
495
|
-
|
|
496
|
-
格式应为:
|
|
497
|
-
|
|
498
|
-
### [文件名]
|
|
499
|
-
- **功能**:
|
|
500
|
-
- **关键组件**:
|
|
501
|
-
- **变更影响**:
|
|
502
|
-
- **关系**:
|
|
503
|
-
|
|
504
|
-
你的回答应该是一个完整的"文档"部分内容,不需要包含标题。
|
|
505
|
-
"""
|
|
506
|
-
|
|
507
|
-
@byzerllm.prompt()
|
|
508
|
-
def generate_current_change(self, context: Dict[str, Any], query: str) -> str:
|
|
509
|
-
"""
|
|
510
|
-
请分析下面的代码变更,并描述它们与当前需求的关系。
|
|
511
|
-
|
|
512
|
-
需求:
|
|
513
|
-
{{ query }}
|
|
514
|
-
|
|
515
|
-
目录:{{ context.directory_path }}
|
|
516
|
-
|
|
517
|
-
变更的文件:
|
|
518
|
-
{% for file in context.changed_files %}
|
|
519
|
-
- {{ file.path }}
|
|
520
|
-
{% endfor %}
|
|
521
|
-
|
|
522
|
-
{% if context.file_diffs %}
|
|
523
|
-
文件变更摘要:
|
|
524
|
-
{% for diff in context.file_diffs %}
|
|
525
|
-
- {{ diff.path }}: {% if diff.type == 'modified' %}修改 (从{{ diff.before_lines }}行到{{ diff.after_lines }}行){% elif diff.type == 'added' %}新增{% elif diff.type == 'deleted' %}删除{% endif %}
|
|
526
|
-
{% endfor %}
|
|
527
|
-
{% endif %}
|
|
528
|
-
|
|
529
|
-
{% if context.changed_files and context.changed_files[0].has_diff %}
|
|
530
|
-
变更前后的代码对比:
|
|
531
|
-
{% for file in context.changed_files %}
|
|
532
|
-
{% if file.has_diff %}
|
|
533
|
-
文件: {{ file.path }}
|
|
534
|
-
变更前:
|
|
535
|
-
```
|
|
536
|
-
{{ file.before_content }}
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
变更后:
|
|
540
|
-
```
|
|
541
|
-
{{ file.after_content }}
|
|
542
|
-
```
|
|
543
|
-
{% endif %}
|
|
544
|
-
{% endfor %}
|
|
545
|
-
{% endif %}
|
|
546
|
-
|
|
547
|
-
分析并描述这些变更如何满足需求,以及这个目录中的文件在整体变更中起到什么作用。
|
|
548
|
-
描述应该清晰、具体,并表明每个文件的变更内容和目的。
|
|
549
|
-
"""
|
|
550
|
-
|
|
551
|
-
@byzerllm.prompt()
|
|
552
|
-
def generate_document(self, context: Dict[str, Any], query: str) -> str:
|
|
553
|
-
"""
|
|
554
|
-
请为下面列出的每个文件生成详细的文档说明。
|
|
555
|
-
|
|
556
|
-
需求:
|
|
557
|
-
{{ query }}
|
|
558
|
-
|
|
559
|
-
目录:{{ context.directory_path }}
|
|
560
|
-
|
|
561
|
-
文件列表:
|
|
562
|
-
{% for file in context.changed_files %}
|
|
563
|
-
- {{ file.path }}
|
|
564
|
-
{% endfor %}
|
|
565
|
-
|
|
566
|
-
{% if context.current_files %}
|
|
567
|
-
当前目录中的其他相关文件:
|
|
568
|
-
{% for file in context.current_files %}
|
|
569
|
-
- {{ file.path }}
|
|
570
|
-
{% endfor %}
|
|
571
|
-
{% endif %}
|
|
572
|
-
|
|
573
|
-
{% if context.file_diffs %}
|
|
574
|
-
文件变更摘要:
|
|
575
|
-
{% for diff in context.file_diffs %}
|
|
576
|
-
- {{ diff.path }}: {% if diff.type == 'modified' %}修改 (从{{ diff.before_lines }}行到{{ diff.after_lines }}行){% elif diff.type == 'added' %}新增{% elif diff.type == 'deleted' %}删除{% endif %}
|
|
577
|
-
{% endfor %}
|
|
578
|
-
{% endif %}
|
|
579
|
-
|
|
580
|
-
{% if context.changed_files and context.changed_files[0].has_diff %}
|
|
581
|
-
变更前后的代码对比:
|
|
582
|
-
{% for file in context.changed_files %}
|
|
583
|
-
{% if file.has_diff %}
|
|
584
|
-
文件: {{ file.path }}
|
|
585
|
-
变更前:
|
|
586
|
-
```
|
|
587
|
-
{{ file.before_content }}
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
变更后:
|
|
591
|
-
```
|
|
592
|
-
{{ file.after_content }}
|
|
593
|
-
```
|
|
594
|
-
{% endif %}
|
|
595
|
-
{% endfor %}
|
|
596
|
-
{% endif %}
|
|
597
|
-
|
|
598
|
-
对于每个文件,请提供:
|
|
599
|
-
1. 文件的主要功能
|
|
600
|
-
2. 文件中的关键组件(类、函数等)
|
|
601
|
-
3. 此次变更对文件的影响(如果适用)
|
|
602
|
-
4. 文件与其他文件的关系
|
|
603
|
-
|
|
604
|
-
格式应为:
|
|
605
|
-
|
|
606
|
-
### [文件名]
|
|
607
|
-
- **功能**:
|
|
608
|
-
- **关键组件**:
|
|
609
|
-
- **变更影响**:
|
|
610
|
-
- **关系**:
|
|
611
|
-
"""
|
|
355
|
+
return err_content, empty_stats
|
autocoder/rag/api_server.py
CHANGED
|
@@ -127,7 +127,14 @@ async def create_chat_completion(
|
|
|
127
127
|
if body.stream:
|
|
128
128
|
return StreamingResponse(
|
|
129
129
|
content=generator,
|
|
130
|
-
media_type="text/event-stream"
|
|
130
|
+
media_type="text/event-stream",
|
|
131
|
+
headers={
|
|
132
|
+
"Cache-Control": "no-cache, no-transform",
|
|
133
|
+
"Connection": "keep-alive",
|
|
134
|
+
"Content-Type": "text/event-stream",
|
|
135
|
+
"X-Accel-Buffering": "no",
|
|
136
|
+
"Transfer-Encoding": "chunked",
|
|
137
|
+
}
|
|
131
138
|
)
|
|
132
139
|
else:
|
|
133
140
|
return JSONResponse(content=generator.model_dump())
|
|
@@ -381,5 +388,5 @@ def serve(llm:ByzerLLM, args: ServerArgs):
|
|
|
381
388
|
log_level=args.uvicorn_log_level,
|
|
382
389
|
timeout_keep_alive=TIMEOUT_KEEP_ALIVE,
|
|
383
390
|
ssl_keyfile=args.ssl_keyfile,
|
|
384
|
-
ssl_certfile=args.ssl_certfile
|
|
391
|
+
ssl_certfile=args.ssl_certfile
|
|
385
392
|
)
|
autocoder/rag/lang.py
CHANGED
|
@@ -49,6 +49,10 @@ MESSAGES = {
|
|
|
49
49
|
"context_docs_names": {
|
|
50
50
|
"en": "The following are the documents related to the user's question: {{context_docs_names}}",
|
|
51
51
|
"zh": "以下是和用户问题相关的文档:{{context_docs_names}}"
|
|
52
|
+
},
|
|
53
|
+
"rag_processing": {
|
|
54
|
+
"en": "Processing...\n",
|
|
55
|
+
"zh": "处理中...\n"
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
|
|
@@ -460,7 +460,7 @@ class LongContextRAG:
|
|
|
460
460
|
),
|
|
461
461
|
)
|
|
462
462
|
|
|
463
|
-
context = []
|
|
463
|
+
context = []
|
|
464
464
|
|
|
465
465
|
return self._generate_sream(
|
|
466
466
|
conversations=conversations,
|
|
@@ -492,6 +492,15 @@ class LongContextRAG:
|
|
|
492
492
|
extra_request_params=None
|
|
493
493
|
):
|
|
494
494
|
"""将RAG流程分为三个主要阶段的生成器函数"""
|
|
495
|
+
|
|
496
|
+
yield ("", SingleOutputMeta(
|
|
497
|
+
input_tokens_count=0,
|
|
498
|
+
generated_tokens_count=0,
|
|
499
|
+
reasoning_content=get_message_with_format_and_newline(
|
|
500
|
+
"rag_processing"
|
|
501
|
+
)
|
|
502
|
+
))
|
|
503
|
+
|
|
495
504
|
# 第一阶段:文档召回和过滤
|
|
496
505
|
doc_retrieval_generator = self._process_document_retrieval(
|
|
497
506
|
conversations=conversations,
|
|
@@ -676,7 +685,7 @@ class LongContextRAG:
|
|
|
676
685
|
def _process_document_retrieval(self, conversations,
|
|
677
686
|
query, rag_stat):
|
|
678
687
|
"""第一阶段:文档召回和过滤"""
|
|
679
|
-
recall_start_time = time.time() # 记录召回阶段开始时间
|
|
688
|
+
recall_start_time = time.time() # 记录召回阶段开始时间
|
|
680
689
|
|
|
681
690
|
yield ("", SingleOutputMeta(
|
|
682
691
|
input_tokens_count=0,
|
|
@@ -216,13 +216,15 @@ class SingleRoundStrategy(QAConversationStrategy):
|
|
|
216
216
|
- If the documents do not contain enough information to answer, reply: "抱歉,文档中没有足够的信息来回答这个问题。"
|
|
217
217
|
- Do NOT invent, guess, or add information beyond what is provided.
|
|
218
218
|
|
|
219
|
+
|
|
220
|
+
{% if local_image_host %}
|
|
219
221
|
- For Markdown images like :
|
|
220
222
|
- Analyze surrounding text to determine relevance.
|
|
221
223
|
- Include relevant images naturally in your answer, preserving image paths.
|
|
222
|
-
- Convert Windows paths to Linux style (e.g., C:\\path\\to\\img.png -> C:/path/to/img.png)
|
|
223
|
-
{% if local_image_host %}
|
|
224
|
+
- Convert Windows paths to Linux style (e.g., C:\\path\\to\\img.png -> C:/path/to/img.png)
|
|
224
225
|
- Prefix image URLs with http://{{ local_image_host }}/static/
|
|
225
|
-
{
|
|
226
|
+
for example: , return 
|
|
227
|
+
{% endif %}
|
|
226
228
|
|
|
227
229
|
- Format your answer with Markdown for readability.
|
|
228
230
|
- Always use the language used by the user in their question.
|
autocoder/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.390"
|
|
File without changes
|
|
File without changes
|