auto-coder 0.1.398__py3-none-any.whl → 0.1.400__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 (86) hide show
  1. auto_coder-0.1.400.dist-info/METADATA +396 -0
  2. {auto_coder-0.1.398.dist-info → auto_coder-0.1.400.dist-info}/RECORD +82 -29
  3. {auto_coder-0.1.398.dist-info → auto_coder-0.1.400.dist-info}/WHEEL +1 -1
  4. {auto_coder-0.1.398.dist-info → auto_coder-0.1.400.dist-info}/entry_points.txt +2 -0
  5. autocoder/agent/base_agentic/base_agent.py +2 -2
  6. autocoder/agent/base_agentic/tools/replace_in_file_tool_resolver.py +1 -1
  7. autocoder/agent/entry_command_agent/__init__.py +29 -0
  8. autocoder/agent/entry_command_agent/auto_tool.py +61 -0
  9. autocoder/agent/entry_command_agent/chat.py +475 -0
  10. autocoder/agent/entry_command_agent/designer.py +53 -0
  11. autocoder/agent/entry_command_agent/generate_command.py +50 -0
  12. autocoder/agent/entry_command_agent/project_reader.py +58 -0
  13. autocoder/agent/entry_command_agent/voice2text.py +71 -0
  14. autocoder/auto_coder.py +23 -548
  15. autocoder/auto_coder_runner.py +511 -8
  16. autocoder/chat/rules_command.py +1 -1
  17. autocoder/chat_auto_coder.py +6 -1
  18. autocoder/common/ac_style_command_parser/__init__.py +15 -0
  19. autocoder/common/ac_style_command_parser/example.py +7 -0
  20. autocoder/{command_parser.py → common/ac_style_command_parser/parser.py} +28 -45
  21. autocoder/common/ac_style_command_parser/test_parser.py +516 -0
  22. autocoder/common/auto_coder_lang.py +78 -0
  23. autocoder/common/command_completer_v2.py +1 -1
  24. autocoder/common/command_file_manager/examples.py +22 -8
  25. autocoder/common/command_file_manager/manager.py +37 -6
  26. autocoder/common/conversations/get_conversation_manager.py +143 -0
  27. autocoder/common/conversations/manager.py +122 -11
  28. autocoder/common/conversations/storage/index_manager.py +89 -0
  29. autocoder/common/pull_requests/__init__.py +256 -0
  30. autocoder/common/pull_requests/base_provider.py +191 -0
  31. autocoder/common/pull_requests/config.py +66 -0
  32. autocoder/common/pull_requests/example.py +1 -0
  33. autocoder/common/pull_requests/exceptions.py +46 -0
  34. autocoder/common/pull_requests/manager.py +201 -0
  35. autocoder/common/pull_requests/models.py +164 -0
  36. autocoder/common/pull_requests/providers/__init__.py +23 -0
  37. autocoder/common/pull_requests/providers/gitcode_provider.py +19 -0
  38. autocoder/common/pull_requests/providers/gitee_provider.py +20 -0
  39. autocoder/common/pull_requests/providers/github_provider.py +214 -0
  40. autocoder/common/pull_requests/providers/gitlab_provider.py +29 -0
  41. autocoder/common/pull_requests/test_module.py +1 -0
  42. autocoder/common/pull_requests/utils.py +344 -0
  43. autocoder/common/tokens/__init__.py +62 -0
  44. autocoder/common/tokens/counter.py +211 -0
  45. autocoder/common/tokens/file_detector.py +105 -0
  46. autocoder/common/tokens/filters.py +111 -0
  47. autocoder/common/tokens/models.py +28 -0
  48. autocoder/common/v2/agent/agentic_edit.py +312 -85
  49. autocoder/common/v2/agent/agentic_edit_types.py +11 -0
  50. autocoder/common/v2/code_auto_generate_editblock.py +10 -2
  51. autocoder/dispacher/__init__.py +10 -0
  52. autocoder/rags.py +0 -27
  53. autocoder/run_context.py +1 -0
  54. autocoder/sdk/__init__.py +188 -0
  55. autocoder/sdk/cli/__init__.py +15 -0
  56. autocoder/sdk/cli/__main__.py +26 -0
  57. autocoder/sdk/cli/completion_wrapper.py +38 -0
  58. autocoder/sdk/cli/formatters.py +211 -0
  59. autocoder/sdk/cli/handlers.py +175 -0
  60. autocoder/sdk/cli/install_completion.py +301 -0
  61. autocoder/sdk/cli/main.py +286 -0
  62. autocoder/sdk/cli/options.py +73 -0
  63. autocoder/sdk/constants.py +102 -0
  64. autocoder/sdk/core/__init__.py +20 -0
  65. autocoder/sdk/core/auto_coder_core.py +880 -0
  66. autocoder/sdk/core/bridge.py +500 -0
  67. autocoder/sdk/example.py +0 -0
  68. autocoder/sdk/exceptions.py +72 -0
  69. autocoder/sdk/models/__init__.py +19 -0
  70. autocoder/sdk/models/messages.py +209 -0
  71. autocoder/sdk/models/options.py +196 -0
  72. autocoder/sdk/models/responses.py +311 -0
  73. autocoder/sdk/session/__init__.py +32 -0
  74. autocoder/sdk/session/session.py +106 -0
  75. autocoder/sdk/session/session_manager.py +56 -0
  76. autocoder/sdk/utils/__init__.py +24 -0
  77. autocoder/sdk/utils/formatters.py +216 -0
  78. autocoder/sdk/utils/io_utils.py +302 -0
  79. autocoder/sdk/utils/validators.py +287 -0
  80. autocoder/version.py +2 -1
  81. auto_coder-0.1.398.dist-info/METADATA +0 -111
  82. autocoder/common/conversations/compatibility.py +0 -303
  83. autocoder/common/conversations/conversation_manager.py +0 -502
  84. autocoder/common/conversations/example.py +0 -152
  85. {auto_coder-0.1.398.dist-info → auto_coder-0.1.400.dist-info/licenses}/LICENSE +0 -0
  86. {auto_coder-0.1.398.dist-info → auto_coder-0.1.400.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,209 @@
1
+
2
+
3
+
4
+ """
5
+ Auto-Coder SDK 消息模型
6
+
7
+ 定义Message类和相关的消息处理功能。
8
+ """
9
+
10
+ from dataclasses import dataclass, field
11
+ from typing import Dict, Any, Optional, List
12
+ from datetime import datetime
13
+ import json
14
+
15
+ from ..constants import MESSAGE_ROLES
16
+
17
+
18
+ @dataclass
19
+ class Message:
20
+ """消息数据模型"""
21
+
22
+ role: str
23
+ content: str
24
+ timestamp: Optional[datetime] = None
25
+ metadata: Dict[str, Any] = field(default_factory=dict)
26
+
27
+ def __post_init__(self):
28
+ """初始化后处理"""
29
+ if self.timestamp is None:
30
+ self.timestamp = datetime.now()
31
+
32
+ # 验证role
33
+ if self.role not in MESSAGE_ROLES:
34
+ raise ValueError(f"Invalid role: {self.role}. Must be one of: {', '.join(MESSAGE_ROLES.keys())}")
35
+
36
+ def to_dict(self) -> Dict[str, Any]:
37
+ """转换为字典格式"""
38
+ return {
39
+ "role": self.role,
40
+ "content": self.content,
41
+ "timestamp": self.timestamp.isoformat() if self.timestamp else None,
42
+ "metadata": self.metadata
43
+ }
44
+
45
+ @classmethod
46
+ def from_dict(cls, data: Dict[str, Any]) -> "Message":
47
+ """从字典创建Message实例"""
48
+ timestamp = None
49
+ if data.get("timestamp"):
50
+ timestamp = datetime.fromisoformat(data["timestamp"])
51
+
52
+ return cls(
53
+ role=data["role"],
54
+ content=data["content"],
55
+ timestamp=timestamp,
56
+ metadata=data.get("metadata", {})
57
+ )
58
+
59
+ def to_json(self) -> str:
60
+ """转换为JSON字符串"""
61
+ return json.dumps(self.to_dict(), ensure_ascii=False, indent=2)
62
+
63
+ @classmethod
64
+ def from_json(cls, json_str: str) -> "Message":
65
+ """从JSON字符串创建Message实例"""
66
+ data = json.loads(json_str)
67
+ return cls.from_dict(data)
68
+
69
+ def add_metadata(self, key: str, value: Any) -> None:
70
+ """添加元数据"""
71
+ self.metadata[key] = value
72
+
73
+ def get_metadata(self, key: str, default: Any = None) -> Any:
74
+ """获取元数据"""
75
+ return self.metadata.get(key, default)
76
+
77
+ def is_user_message(self) -> bool:
78
+ """判断是否为用户消息"""
79
+ return self.role == "user"
80
+
81
+ def is_assistant_message(self) -> bool:
82
+ """判断是否为助手消息"""
83
+ return self.role == "assistant"
84
+
85
+ def is_system_message(self) -> bool:
86
+ """判断是否为系统消息"""
87
+ return self.role == "system"
88
+
89
+ def __str__(self) -> str:
90
+ """字符串表示"""
91
+ return f"Message(role={self.role}, content={self.content[:50]}...)"
92
+
93
+ def __repr__(self) -> str:
94
+ """详细字符串表示"""
95
+ return f"Message(role='{self.role}', content='{self.content}', timestamp={self.timestamp})"
96
+
97
+
98
+ @dataclass
99
+ class MessageBatch:
100
+ """消息批次,用于处理多个消息"""
101
+
102
+ messages: List[Message] = field(default_factory=list)
103
+ batch_id: Optional[str] = None
104
+ created_at: Optional[datetime] = None
105
+
106
+ def __post_init__(self):
107
+ """初始化后处理"""
108
+ if self.created_at is None:
109
+ self.created_at = datetime.now()
110
+
111
+ if self.batch_id is None:
112
+ self.batch_id = f"batch_{int(self.created_at.timestamp())}"
113
+
114
+ def add_message(self, message: Message) -> None:
115
+ """添加消息"""
116
+ self.messages.append(message)
117
+
118
+ def add_user_message(self, content: str, metadata: Dict[str, Any] = None) -> Message:
119
+ """添加用户消息"""
120
+ message = Message(
121
+ role="user",
122
+ content=content,
123
+ metadata=metadata or {}
124
+ )
125
+ self.add_message(message)
126
+ return message
127
+
128
+ def add_assistant_message(self, content: str, metadata: Dict[str, Any] = None) -> Message:
129
+ """添加助手消息"""
130
+ message = Message(
131
+ role="assistant",
132
+ content=content,
133
+ metadata=metadata or {}
134
+ )
135
+ self.add_message(message)
136
+ return message
137
+
138
+ def add_system_message(self, content: str, metadata: Dict[str, Any] = None) -> Message:
139
+ """添加系统消息"""
140
+ message = Message(
141
+ role="system",
142
+ content=content,
143
+ metadata=metadata or {}
144
+ )
145
+ self.add_message(message)
146
+ return message
147
+
148
+ def get_messages_by_role(self, role: str) -> List[Message]:
149
+ """根据角色获取消息"""
150
+ return [msg for msg in self.messages if msg.role == role]
151
+
152
+ def get_user_messages(self) -> List[Message]:
153
+ """获取用户消息"""
154
+ return self.get_messages_by_role("user")
155
+
156
+ def get_assistant_messages(self) -> List[Message]:
157
+ """获取助手消息"""
158
+ return self.get_messages_by_role("assistant")
159
+
160
+ def get_system_messages(self) -> List[Message]:
161
+ """获取系统消息"""
162
+ return self.get_messages_by_role("system")
163
+
164
+ def to_dict(self) -> Dict[str, Any]:
165
+ """转换为字典格式"""
166
+ return {
167
+ "batch_id": self.batch_id,
168
+ "created_at": self.created_at.isoformat() if self.created_at else None,
169
+ "messages": [msg.to_dict() for msg in self.messages]
170
+ }
171
+
172
+ @classmethod
173
+ def from_dict(cls, data: Dict[str, Any]) -> "MessageBatch":
174
+ """从字典创建MessageBatch实例"""
175
+ created_at = None
176
+ if data.get("created_at"):
177
+ created_at = datetime.fromisoformat(data["created_at"])
178
+
179
+ messages = [Message.from_dict(msg_data) for msg_data in data.get("messages", [])]
180
+
181
+ return cls(
182
+ batch_id=data.get("batch_id"),
183
+ created_at=created_at,
184
+ messages=messages
185
+ )
186
+
187
+ def to_json(self) -> str:
188
+ """转换为JSON字符串"""
189
+ return json.dumps(self.to_dict(), ensure_ascii=False, indent=2)
190
+
191
+ @classmethod
192
+ def from_json(cls, json_str: str) -> "MessageBatch":
193
+ """从JSON字符串创建MessageBatch实例"""
194
+ data = json.loads(json_str)
195
+ return cls.from_dict(data)
196
+
197
+ def __len__(self) -> int:
198
+ """返回消息数量"""
199
+ return len(self.messages)
200
+
201
+ def __iter__(self):
202
+ """迭代消息"""
203
+ return iter(self.messages)
204
+
205
+ def __getitem__(self, index: int) -> Message:
206
+ """根据索引获取消息"""
207
+ return self.messages[index]
208
+
209
+
@@ -0,0 +1,196 @@
1
+
2
+
3
+
4
+ """
5
+ Auto-Coder SDK 选项配置模型
6
+
7
+ 定义AutoCodeOptions类,提供完整的配置选项和验证规则。
8
+ """
9
+
10
+ from dataclasses import dataclass, field
11
+ from typing import Optional, List, Union, Dict, Any
12
+ from pathlib import Path
13
+ import os
14
+
15
+ from ..constants import (
16
+ DEFAULT_MAX_TURNS,
17
+ DEFAULT_OUTPUT_FORMAT,
18
+ DEFAULT_PERMISSION_MODE,
19
+ OUTPUT_FORMATS,
20
+ PERMISSION_MODES,
21
+ ALLOWED_TOOLS
22
+ )
23
+ from ..exceptions import ValidationError
24
+
25
+
26
+ @dataclass
27
+ class AutoCodeOptions:
28
+ """AutoCoder选项配置类"""
29
+
30
+ # 基础配置
31
+ max_turns: int = DEFAULT_MAX_TURNS
32
+ system_prompt: Optional[str] = None
33
+ cwd: Optional[Union[str, Path]] = None
34
+
35
+ # 工具和权限配置
36
+ allowed_tools: List[str] = field(default_factory=list)
37
+ permission_mode: str = DEFAULT_PERMISSION_MODE
38
+
39
+ # 输出配置
40
+ output_format: str = DEFAULT_OUTPUT_FORMAT
41
+ stream: bool = False
42
+
43
+ # 会话配置
44
+ session_id: Optional[str] = None
45
+ continue_session: bool = False # 继续最近的对话
46
+
47
+ # 模型配置
48
+ model: Optional[str] = None
49
+ temperature: float = 0.7
50
+
51
+ # 高级配置
52
+ timeout: int = 30
53
+ verbose: bool = False
54
+ include_project_structure: bool = True
55
+ pr: bool = False # 是否创建 PR
56
+
57
+ def __post_init__(self):
58
+ """初始化后验证"""
59
+ self._normalize_values()
60
+ self.validate()
61
+
62
+ def validate(self) -> None:
63
+ """验证配置选项"""
64
+
65
+ # 验证max_turns(-1表示不限制)
66
+ if self.max_turns <= 0 and self.max_turns != -1:
67
+ raise ValidationError("max_turns", "must be positive integer or -1 (unlimited)")
68
+
69
+ if self.max_turns > 100 and self.max_turns != -1:
70
+ raise ValidationError("max_turns", "cannot exceed 100 (unless -1 for unlimited)")
71
+
72
+ # 验证output_format
73
+ if self.output_format not in OUTPUT_FORMATS:
74
+ raise ValidationError(
75
+ "output_format",
76
+ f"must be one of: {', '.join(OUTPUT_FORMATS.keys())}"
77
+ )
78
+
79
+ # 验证permission_mode
80
+ if self.permission_mode not in PERMISSION_MODES:
81
+ raise ValidationError(
82
+ "permission_mode",
83
+ f"must be one of: {', '.join(PERMISSION_MODES.keys())}"
84
+ )
85
+
86
+ # 验证allowed_tools
87
+ if self.allowed_tools:
88
+ invalid_tools = set(self.allowed_tools) - set(ALLOWED_TOOLS)
89
+ if invalid_tools:
90
+ raise ValidationError(
91
+ "allowed_tools",
92
+ f"invalid tools: {', '.join(invalid_tools)}. "
93
+ f"Valid tools: {', '.join(ALLOWED_TOOLS)}"
94
+ )
95
+
96
+ # 验证temperature
97
+ if not 0.0 <= self.temperature <= 2.0:
98
+ raise ValidationError("temperature", "must be between 0.0 and 2.0")
99
+
100
+ # 验证timeout
101
+ if self.timeout <= 0:
102
+ raise ValidationError("timeout", "must be positive integer")
103
+
104
+ # 验证cwd
105
+ if self.cwd is not None:
106
+ cwd_path = Path(self.cwd)
107
+ if not cwd_path.exists():
108
+ raise ValidationError("cwd", f"directory does not exist: {self.cwd}")
109
+ if not cwd_path.is_dir():
110
+ raise ValidationError("cwd", f"path is not a directory: {self.cwd}")
111
+
112
+ def _normalize_values(self) -> None:
113
+ """标准化配置值"""
114
+
115
+ # 标准化cwd路径
116
+ if self.cwd is not None:
117
+ self.cwd = str(Path(self.cwd).resolve())
118
+ else:
119
+ self.cwd = os.getcwd()
120
+
121
+ # 如果没有指定allowed_tools,使用默认值
122
+ if not self.allowed_tools:
123
+ self.allowed_tools = ALLOWED_TOOLS.copy()
124
+
125
+ # 标准化字符串值
126
+ self.output_format = self.output_format.lower()
127
+ self.permission_mode = self.permission_mode.lower()
128
+
129
+ def to_dict(self) -> Dict[str, Any]:
130
+ """转换为字典格式"""
131
+ return {
132
+ "max_turns": self.max_turns,
133
+ "system_prompt": self.system_prompt,
134
+ "cwd": self.cwd,
135
+ "allowed_tools": self.allowed_tools,
136
+ "permission_mode": self.permission_mode,
137
+ "output_format": self.output_format,
138
+ "stream": self.stream,
139
+ "session_id": self.session_id,
140
+ "model": self.model,
141
+ "temperature": self.temperature,
142
+ "timeout": self.timeout,
143
+ "verbose": self.verbose,
144
+ "include_project_structure": self.include_project_structure,
145
+ "pr": self.pr
146
+ }
147
+
148
+ @classmethod
149
+ def from_dict(cls, data: Dict[str, Any]) -> "AutoCodeOptions":
150
+ """从字典创建实例"""
151
+ # 过滤掉不存在的字段
152
+ valid_fields = {f.name for f in cls.__dataclass_fields__.values()}
153
+ filtered_data = {k: v for k, v in data.items() if k in valid_fields}
154
+
155
+ return cls(**filtered_data)
156
+
157
+ def copy(self, **changes) -> "AutoCodeOptions":
158
+ """创建副本并应用更改"""
159
+ data = self.to_dict()
160
+ data.update(changes)
161
+ return self.from_dict(data)
162
+
163
+ def merge(self, other: "AutoCodeOptions") -> "AutoCodeOptions":
164
+ """合并两个配置对象"""
165
+ # 创建新的配置对象,从当前对象开始
166
+ data = self.to_dict()
167
+
168
+ # 只覆盖other中明确设置的值(非None且非默认值)
169
+ if other.max_turns != DEFAULT_MAX_TURNS:
170
+ data["max_turns"] = other.max_turns
171
+ if other.system_prompt is not None:
172
+ data["system_prompt"] = other.system_prompt
173
+ if other.output_format != DEFAULT_OUTPUT_FORMAT:
174
+ data["output_format"] = other.output_format
175
+ if other.permission_mode != DEFAULT_PERMISSION_MODE:
176
+ data["permission_mode"] = other.permission_mode
177
+ if other.model is not None:
178
+ data["model"] = other.model
179
+ if other.temperature != 0.7:
180
+ data["temperature"] = other.temperature
181
+ if other.timeout != 30:
182
+ data["timeout"] = other.timeout
183
+ if other.verbose is not False:
184
+ data["verbose"] = other.verbose
185
+ if other.stream is not False:
186
+ data["stream"] = other.stream
187
+ if other.include_project_structure is not True:
188
+ data["include_project_structure"] = other.include_project_structure
189
+ if other.session_id is not None:
190
+ data["session_id"] = other.session_id
191
+ if other.allowed_tools != []:
192
+ data["allowed_tools"] = other.allowed_tools
193
+
194
+ return self.from_dict(data)
195
+
196
+