auto-coder 0.1.399__py3-none-any.whl → 1.0.0__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.

Files changed (71) hide show
  1. {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/METADATA +1 -1
  2. {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/RECORD +71 -35
  3. autocoder/agent/agentic_filter.py +1 -1
  4. autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +1 -1
  5. autocoder/auto_coder_runner.py +121 -26
  6. autocoder/chat_auto_coder.py +81 -22
  7. autocoder/commands/auto_command.py +1 -1
  8. autocoder/common/__init__.py +2 -2
  9. autocoder/common/ac_style_command_parser/parser.py +27 -12
  10. autocoder/common/auto_coder_lang.py +78 -0
  11. autocoder/common/command_completer_v2.py +1 -1
  12. autocoder/common/file_monitor/test_file_monitor.py +307 -0
  13. autocoder/common/git_utils.py +7 -2
  14. autocoder/common/pruner/__init__.py +0 -0
  15. autocoder/common/pruner/agentic_conversation_pruner.py +197 -0
  16. autocoder/common/pruner/context_pruner.py +574 -0
  17. autocoder/common/pruner/conversation_pruner.py +132 -0
  18. autocoder/common/pruner/test_agentic_conversation_pruner.py +342 -0
  19. autocoder/common/pruner/test_context_pruner.py +546 -0
  20. autocoder/common/pull_requests/__init__.py +256 -0
  21. autocoder/common/pull_requests/base_provider.py +191 -0
  22. autocoder/common/pull_requests/config.py +66 -0
  23. autocoder/common/pull_requests/example.py +1 -0
  24. autocoder/common/pull_requests/exceptions.py +46 -0
  25. autocoder/common/pull_requests/manager.py +201 -0
  26. autocoder/common/pull_requests/models.py +164 -0
  27. autocoder/common/pull_requests/providers/__init__.py +23 -0
  28. autocoder/common/pull_requests/providers/gitcode_provider.py +19 -0
  29. autocoder/common/pull_requests/providers/gitee_provider.py +20 -0
  30. autocoder/common/pull_requests/providers/github_provider.py +214 -0
  31. autocoder/common/pull_requests/providers/gitlab_provider.py +29 -0
  32. autocoder/common/pull_requests/test_module.py +1 -0
  33. autocoder/common/pull_requests/utils.py +344 -0
  34. autocoder/common/tokens/__init__.py +77 -0
  35. autocoder/common/tokens/counter.py +231 -0
  36. autocoder/common/tokens/file_detector.py +105 -0
  37. autocoder/common/tokens/filters.py +111 -0
  38. autocoder/common/tokens/models.py +28 -0
  39. autocoder/common/v2/agent/agentic_edit.py +538 -590
  40. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +8 -1
  41. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
  42. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +43 -0
  43. autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
  44. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +1 -1
  45. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +1 -1
  46. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +33 -88
  47. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +8 -8
  48. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +118 -0
  49. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +324 -0
  50. autocoder/common/v2/agent/agentic_edit_types.py +47 -4
  51. autocoder/common/v2/agent/runner/__init__.py +31 -0
  52. autocoder/common/v2/agent/runner/base_runner.py +106 -0
  53. autocoder/common/v2/agent/runner/event_runner.py +216 -0
  54. autocoder/common/v2/agent/runner/sdk_runner.py +40 -0
  55. autocoder/common/v2/agent/runner/terminal_runner.py +283 -0
  56. autocoder/common/v2/agent/runner/tool_display.py +191 -0
  57. autocoder/index/entry.py +1 -1
  58. autocoder/plugins/token_helper_plugin.py +107 -7
  59. autocoder/run_context.py +9 -0
  60. autocoder/sdk/__init__.py +114 -81
  61. autocoder/sdk/cli/handlers.py +2 -1
  62. autocoder/sdk/cli/main.py +9 -2
  63. autocoder/sdk/cli/options.py +4 -3
  64. autocoder/sdk/core/auto_coder_core.py +7 -152
  65. autocoder/sdk/core/bridge.py +5 -4
  66. autocoder/sdk/models/options.py +8 -6
  67. autocoder/version.py +1 -1
  68. {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/WHEEL +0 -0
  69. {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/entry_points.txt +0 -0
  70. {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/licenses/LICENSE +0 -0
  71. {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,105 @@
1
+ import os
2
+ import mimetypes
3
+ from pathlib import Path
4
+
5
+
6
+ class FileTypeDetector:
7
+ """文件类型检测器,用于判断文件类型和编码"""
8
+
9
+ # 常见的文本文件MIME类型前缀
10
+ TEXT_MIME_PREFIXES = ('text/', 'application/json', 'application/xml', 'application/javascript')
11
+
12
+ # 常见的文本文件扩展名
13
+ TEXT_EXTENSIONS = {
14
+ '.txt', '.md', '.py', '.js', '.jsx', '.ts', '.tsx', '.html', '.css', '.scss', '.sass',
15
+ '.json', '.xml', '.yaml', '.yml', '.ini', '.conf', '.sh', '.bash', '.zsh', '.c', '.cpp',
16
+ '.h', '.hpp', '.java', '.kt', '.rs', '.go', '.rb', '.php', '.pl', '.swift', '.dart',
17
+ '.vue', '.svelte', '.lua', '.r', '.sql', '.graphql', '.toml', '.csv'
18
+ }
19
+
20
+ @staticmethod
21
+ def is_text_file(file_path: str) -> bool:
22
+ """
23
+ 判断文件是否为文本文件
24
+
25
+ Args:
26
+ file_path: 文件路径
27
+
28
+ Returns:
29
+ bool: 是否为文本文件
30
+ """
31
+ # 首先通过扩展名判断
32
+ ext = os.path.splitext(file_path)[1].lower()
33
+ if ext in FileTypeDetector.TEXT_EXTENSIONS:
34
+ return True
35
+
36
+ # 通过MIME类型判断
37
+ mime_type = FileTypeDetector.get_mime_type(file_path)
38
+ if any(mime_type.startswith(prefix) for prefix in FileTypeDetector.TEXT_MIME_PREFIXES):
39
+ return True
40
+
41
+ # 通过文件内容判断
42
+ try:
43
+ with open(file_path, 'rb') as f:
44
+ # 读取前4KB进行判断
45
+ chunk = f.read(4096)
46
+ # 检查是否包含空字节(二进制文件通常包含空字节)
47
+ if b'\x00' in chunk:
48
+ return False
49
+ # 尝试解码为UTF-8
50
+ try:
51
+ chunk.decode('utf-8')
52
+ return True
53
+ except UnicodeDecodeError:
54
+ # 尝试其他常见编码
55
+ for encoding in ['gbk', 'latin1', 'ascii']:
56
+ try:
57
+ chunk.decode(encoding)
58
+ return True
59
+ except UnicodeDecodeError:
60
+ continue
61
+ return False
62
+ except (IOError, OSError):
63
+ pass
64
+
65
+ return False
66
+
67
+ @staticmethod
68
+ def detect_encoding(file_path: str) -> str:
69
+ """
70
+ 检测文件编码
71
+
72
+ Args:
73
+ file_path: 文件路径
74
+
75
+ Returns:
76
+ str: 文件编码,默认为utf-8
77
+ """
78
+ # 尝试常见编码
79
+ encodings = ['utf-8', 'gbk', 'latin1', 'ascii']
80
+
81
+ for encoding in encodings:
82
+ try:
83
+ with open(file_path, 'r', encoding=encoding) as f:
84
+ f.read(100) # 尝试读取一小部分内容
85
+ return encoding
86
+ except UnicodeDecodeError:
87
+ continue
88
+ except (IOError, OSError):
89
+ break
90
+
91
+ return 'utf-8' # 默认编码
92
+
93
+ @staticmethod
94
+ def get_mime_type(file_path: str) -> str:
95
+ """
96
+ 获取文件的MIME类型
97
+
98
+ Args:
99
+ file_path: 文件路径
100
+
101
+ Returns:
102
+ str: MIME类型
103
+ """
104
+ mime_type, _ = mimetypes.guess_type(file_path)
105
+ return mime_type or 'application/octet-stream' # 默认为二进制类型
@@ -0,0 +1,111 @@
1
+ import os
2
+ import re
3
+ from pathlib import Path
4
+ from typing import List, Optional, Tuple
5
+
6
+
7
+ class FileFilter:
8
+ """文件过滤器,用于过滤需要统计的文件"""
9
+
10
+ def __init__(self,
11
+ patterns: List[str] = None,
12
+ exclude_patterns: List[str] = None,
13
+ min_size: int = None,
14
+ max_size: int = None,
15
+ only_text_files: bool = True):
16
+ """
17
+ 初始化文件过滤器
18
+
19
+ Args:
20
+ patterns: 包含的文件名模式(正则表达式)
21
+ exclude_patterns: 排除的文件名模式(正则表达式)
22
+ min_size: 最小文件大小(字节)
23
+ max_size: 最大文件大小(字节)
24
+ only_text_files: 是否只包含文本文件
25
+ """
26
+ self.patterns = []
27
+ self.exclude_patterns = []
28
+ self.min_size = min_size
29
+ self.max_size = max_size
30
+ self.only_text_files = only_text_files
31
+
32
+ if patterns:
33
+ for pattern in patterns:
34
+ self.add_pattern(pattern)
35
+
36
+ if exclude_patterns:
37
+ for pattern in exclude_patterns:
38
+ self.add_exclude_pattern(pattern)
39
+
40
+ def add_pattern(self, pattern: str) -> None:
41
+ """
42
+ 添加包含的文件名模式
43
+
44
+ Args:
45
+ pattern: 正则表达式模式
46
+ """
47
+ try:
48
+ self.patterns.append(re.compile(pattern))
49
+ except re.error:
50
+ raise ValueError(f"Invalid regex pattern: {pattern}")
51
+
52
+ def add_exclude_pattern(self, pattern: str) -> None:
53
+ """
54
+ 添加排除的文件名模式
55
+
56
+ Args:
57
+ pattern: 正则表达式模式
58
+ """
59
+ try:
60
+ self.exclude_patterns.append(re.compile(pattern))
61
+ except re.error:
62
+ raise ValueError(f"Invalid regex pattern: {pattern}")
63
+
64
+ def set_size_range(self, min_size: Optional[int] = None, max_size: Optional[int] = None) -> None:
65
+ """
66
+ 设置文件大小范围
67
+
68
+ Args:
69
+ min_size: 最小文件大小(字节)
70
+ max_size: 最大文件大小(字节)
71
+ """
72
+ self.min_size = min_size
73
+ self.max_size = max_size
74
+
75
+ def matches(self, file_path: str) -> bool:
76
+ """
77
+ 检查文件是否匹配过滤条件
78
+
79
+ Args:
80
+ file_path: 文件路径
81
+
82
+ Returns:
83
+ bool: 是否匹配
84
+ """
85
+ # 检查文件是否存在
86
+ if not os.path.isfile(file_path):
87
+ return False
88
+
89
+ # 检查文件大小
90
+ if self.min_size is not None or self.max_size is not None:
91
+ size = os.path.getsize(file_path)
92
+ if self.min_size is not None and size < self.min_size:
93
+ return False
94
+ if self.max_size is not None and size > self.max_size:
95
+ return False
96
+
97
+ # 检查是否匹配排除模式
98
+ for pattern in self.exclude_patterns:
99
+ if pattern.search(file_path):
100
+ return False
101
+
102
+ # 如果没有包含模式,则默认匹配所有文件
103
+ if not self.patterns:
104
+ return True
105
+
106
+ # 检查是否匹配包含模式
107
+ for pattern in self.patterns:
108
+ if pattern.search(file_path):
109
+ return True
110
+
111
+ return False
@@ -0,0 +1,28 @@
1
+ from typing import List, Dict, Optional
2
+ from dataclasses import dataclass
3
+
4
+
5
+ @dataclass
6
+ class TokenResult:
7
+ """单个文件的 token 统计结果"""
8
+ file_path: str
9
+ token_count: int
10
+ char_count: int
11
+ line_count: int
12
+ success: bool = True
13
+ error: Optional[str] = None
14
+
15
+
16
+ @dataclass
17
+ class DirectoryTokenResult:
18
+ """目录的 token 统计结果"""
19
+ directory_path: str
20
+ total_tokens: int
21
+ file_count: int
22
+ skipped_count: int
23
+ files: List[TokenResult]
24
+ errors: List[str] = None
25
+
26
+ def __post_init__(self):
27
+ if self.errors is None:
28
+ self.errors = []