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,287 @@
1
+
2
+
3
+
4
+
5
+
6
+ """
7
+ Auto-Coder SDK 验证工具
8
+
9
+ 提供各种数据验证功能。
10
+ """
11
+
12
+ import re
13
+ import uuid
14
+ from typing import Any, List, Dict
15
+ from pathlib import Path
16
+
17
+ from ..models.options import AutoCodeOptions
18
+ from ..exceptions import ValidationError
19
+
20
+
21
+ def validate_session_id(session_id: str) -> bool:
22
+ """
23
+ 验证会话ID格式
24
+
25
+ Args:
26
+ session_id: 会话ID
27
+
28
+ Returns:
29
+ bool: 是否有效
30
+
31
+ Raises:
32
+ ValidationError: 验证失败时抛出
33
+ """
34
+ if not session_id:
35
+ raise ValidationError("session_id", "cannot be empty")
36
+
37
+ # 检查是否为有效的UUID格式
38
+ try:
39
+ uuid.UUID(session_id)
40
+ return True
41
+ except ValueError:
42
+ pass
43
+
44
+ # 检查是否为有效的自定义格式(字母数字和连字符)
45
+ if re.match(r'^[a-zA-Z0-9\-_]+$', session_id):
46
+ return True
47
+
48
+ raise ValidationError(
49
+ "session_id",
50
+ "must be a valid UUID or alphanumeric string with hyphens/underscores"
51
+ )
52
+
53
+
54
+ def validate_options(options: AutoCodeOptions) -> bool:
55
+ """
56
+ 验证AutoCodeOptions对象
57
+
58
+ Args:
59
+ options: 选项对象
60
+
61
+ Returns:
62
+ bool: 是否有效
63
+
64
+ Raises:
65
+ ValidationError: 验证失败时抛出
66
+ """
67
+ if not isinstance(options, AutoCodeOptions):
68
+ raise ValidationError("options", "must be an AutoCodeOptions instance")
69
+
70
+ # AutoCodeOptions内部已经有验证,这里调用即可
71
+ options.validate()
72
+ return True
73
+
74
+
75
+ def validate_file_path(file_path: str, must_exist: bool = False) -> bool:
76
+ """
77
+ 验证文件路径
78
+
79
+ Args:
80
+ file_path: 文件路径
81
+ must_exist: 是否必须存在
82
+
83
+ Returns:
84
+ bool: 是否有效
85
+
86
+ Raises:
87
+ ValidationError: 验证失败时抛出
88
+ """
89
+ if not file_path:
90
+ raise ValidationError("file_path", "cannot be empty")
91
+
92
+ try:
93
+ path = Path(file_path)
94
+
95
+ if must_exist and not path.exists():
96
+ raise ValidationError("file_path", f"file does not exist: {file_path}")
97
+
98
+ # 检查路径是否合法(不包含非法字符)
99
+ if any(char in str(path) for char in ['<', '>', ':', '"', '|', '?', '*']):
100
+ raise ValidationError("file_path", f"contains invalid characters: {file_path}")
101
+
102
+ return True
103
+ except OSError as e:
104
+ raise ValidationError("file_path", f"invalid path: {str(e)}")
105
+
106
+
107
+ def validate_directory_path(dir_path: str, must_exist: bool = False, create_if_missing: bool = False) -> bool:
108
+ """
109
+ 验证目录路径
110
+
111
+ Args:
112
+ dir_path: 目录路径
113
+ must_exist: 是否必须存在
114
+ create_if_missing: 如果不存在是否创建
115
+
116
+ Returns:
117
+ bool: 是否有效
118
+
119
+ Raises:
120
+ ValidationError: 验证失败时抛出
121
+ """
122
+ if not dir_path:
123
+ raise ValidationError("dir_path", "cannot be empty")
124
+
125
+ try:
126
+ path = Path(dir_path)
127
+
128
+ if not path.exists():
129
+ if must_exist and not create_if_missing:
130
+ raise ValidationError("dir_path", f"directory does not exist: {dir_path}")
131
+ elif create_if_missing:
132
+ path.mkdir(parents=True, exist_ok=True)
133
+ elif path.exists() and not path.is_dir():
134
+ raise ValidationError("dir_path", f"path exists but is not a directory: {dir_path}")
135
+
136
+ return True
137
+ except OSError as e:
138
+ raise ValidationError("dir_path", f"invalid directory path: {str(e)}")
139
+
140
+
141
+ def validate_prompt(prompt: str, max_length: int = 10000) -> bool:
142
+ """
143
+ 验证提示内容
144
+
145
+ Args:
146
+ prompt: 提示内容
147
+ max_length: 最大长度
148
+
149
+ Returns:
150
+ bool: 是否有效
151
+
152
+ Raises:
153
+ ValidationError: 验证失败时抛出
154
+ """
155
+ if not prompt:
156
+ raise ValidationError("prompt", "cannot be empty")
157
+
158
+ if not isinstance(prompt, str):
159
+ raise ValidationError("prompt", "must be a string")
160
+
161
+ if len(prompt.strip()) == 0:
162
+ raise ValidationError("prompt", "cannot be only whitespace")
163
+
164
+ if len(prompt) > max_length:
165
+ raise ValidationError("prompt", f"exceeds maximum length of {max_length} characters")
166
+
167
+ return True
168
+
169
+
170
+ def validate_output_format(output_format: str) -> bool:
171
+ """
172
+ 验证输出格式
173
+
174
+ Args:
175
+ output_format: 输出格式
176
+
177
+ Returns:
178
+ bool: 是否有效
179
+
180
+ Raises:
181
+ ValidationError: 验证失败时抛出
182
+ """
183
+ from ..constants import OUTPUT_FORMATS
184
+
185
+ if not output_format:
186
+ raise ValidationError("output_format", "cannot be empty")
187
+
188
+ if output_format not in OUTPUT_FORMATS:
189
+ raise ValidationError(
190
+ "output_format",
191
+ f"must be one of: {', '.join(OUTPUT_FORMATS.keys())}"
192
+ )
193
+
194
+ return True
195
+
196
+
197
+ def validate_permission_mode(permission_mode: str) -> bool:
198
+ """
199
+ 验证权限模式
200
+
201
+ Args:
202
+ permission_mode: 权限模式
203
+
204
+ Returns:
205
+ bool: 是否有效
206
+
207
+ Raises:
208
+ ValidationError: 验证失败时抛出
209
+ """
210
+ from ..constants import PERMISSION_MODES
211
+
212
+ if not permission_mode:
213
+ raise ValidationError("permission_mode", "cannot be empty")
214
+
215
+ if permission_mode not in PERMISSION_MODES:
216
+ raise ValidationError(
217
+ "permission_mode",
218
+ f"must be one of: {', '.join(PERMISSION_MODES.keys())}"
219
+ )
220
+
221
+ return True
222
+
223
+
224
+ def validate_allowed_tools(allowed_tools: List[str]) -> bool:
225
+ """
226
+ 验证允许的工具列表
227
+
228
+ Args:
229
+ allowed_tools: 工具列表
230
+
231
+ Returns:
232
+ bool: 是否有效
233
+
234
+ Raises:
235
+ ValidationError: 验证失败时抛出
236
+ """
237
+ from ..constants import ALLOWED_TOOLS
238
+
239
+ if not isinstance(allowed_tools, list):
240
+ raise ValidationError("allowed_tools", "must be a list")
241
+
242
+ if not allowed_tools:
243
+ return True # 空列表表示使用默认工具
244
+
245
+ invalid_tools = set(allowed_tools) - set(ALLOWED_TOOLS)
246
+ if invalid_tools:
247
+ raise ValidationError(
248
+ "allowed_tools",
249
+ f"invalid tools: {', '.join(invalid_tools)}. "
250
+ f"Valid tools: {', '.join(ALLOWED_TOOLS)}"
251
+ )
252
+
253
+ return True
254
+
255
+
256
+ def validate_metadata(metadata: Dict[str, Any], max_size: int = 1000) -> bool:
257
+ """
258
+ 验证元数据
259
+
260
+ Args:
261
+ metadata: 元数据字典
262
+ max_size: 最大键值对数量
263
+
264
+ Returns:
265
+ bool: 是否有效
266
+
267
+ Raises:
268
+ ValidationError: 验证失败时抛出
269
+ """
270
+ if not isinstance(metadata, dict):
271
+ raise ValidationError("metadata", "must be a dictionary")
272
+
273
+ if len(metadata) > max_size:
274
+ raise ValidationError("metadata", f"cannot exceed {max_size} key-value pairs")
275
+
276
+ # 检查键的有效性
277
+ for key in metadata.keys():
278
+ if not isinstance(key, str):
279
+ raise ValidationError("metadata", "all keys must be strings")
280
+ if len(key) > 100:
281
+ raise ValidationError("metadata", f"key '{key}' exceeds maximum length of 100 characters")
282
+
283
+ return True
284
+
285
+
286
+
287
+
autocoder/version.py CHANGED
@@ -1 +1,2 @@
1
- __version__ = "0.1.398"
1
+ __version__ = "0.1.400"
2
+
@@ -1,111 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: auto-coder
3
- Version: 0.1.398
4
- Summary: AutoCoder: AutoCoder
5
- Author: allwefantasy
6
- Classifier: Programming Language :: Python :: 3.10
7
- Classifier: Programming Language :: Python :: 3.11
8
- Classifier: Programming Language :: Python :: 3.12
9
- Description-Content-Type: text/markdown
10
- License-File: LICENSE
11
- Requires-Dist: contextlib2
12
- Requires-Dist: ninja
13
- Requires-Dist: jinja2
14
- Requires-Dist: rich
15
- Requires-Dist: paramiko
16
- Requires-Dist: tqdm
17
- Requires-Dist: loguru
18
- Requires-Dist: pyjava >=0.6.21
19
- Requires-Dist: fastapi
20
- Requires-Dist: uvicorn
21
- Requires-Dist: retrying
22
- Requires-Dist: zhipuai
23
- Requires-Dist: dashscope
24
- Requires-Dist: tiktoken
25
- Requires-Dist: tabulate
26
- Requires-Dist: jupyter-client
27
- Requires-Dist: prompt-toolkit
28
- Requires-Dist: tokenizers
29
- Requires-Dist: aiofiles
30
- Requires-Dist: readerwriterlock
31
- Requires-Dist: byzerllm[saas] >=0.1.190
32
- Requires-Dist: patch
33
- Requires-Dist: diff-match-patch
34
- Requires-Dist: GitPython
35
- Requires-Dist: openai >=1.14.3
36
- Requires-Dist: anthropic
37
- Requires-Dist: google-generativeai
38
- Requires-Dist: protobuf
39
- Requires-Dist: azure-cognitiveservices-speech
40
- Requires-Dist: real-agent
41
- Requires-Dist: duckdb
42
- Requires-Dist: python-docx
43
- Requires-Dist: docx2txt
44
- Requires-Dist: pdf2image
45
- Requires-Dist: docx2pdf
46
- Requires-Dist: pypdf
47
- Requires-Dist: pyperclip
48
- Requires-Dist: colorama
49
- Requires-Dist: pylint
50
- Requires-Dist: reportlab
51
- Requires-Dist: pathspec
52
- Requires-Dist: openpyxl
53
- Requires-Dist: python-pptx
54
- Requires-Dist: watchfiles
55
- Requires-Dist: cairosvg
56
- Requires-Dist: matplotlib
57
- Requires-Dist: mammoth
58
- Requires-Dist: markdownify
59
- Requires-Dist: pdfminer.six
60
- Requires-Dist: puremagic
61
- Requires-Dist: pydub
62
- Requires-Dist: youtube-transcript-api
63
- Requires-Dist: SpeechRecognition
64
- Requires-Dist: pathvalidate
65
- Requires-Dist: pexpect
66
- Requires-Dist: setuptools
67
- Requires-Dist: filelock
68
- Requires-Dist: mcp ; python_version >= "3.10"
69
-
70
- <p align="center">
71
- <picture>
72
- <img alt="auto-coder" src="./logo/auto-coder.jpeg" width=55%>
73
- </picture>
74
- </p>
75
-
76
- <h3 align="center">
77
- Auto-Coder (powered by Byzer-LLM)
78
- </h3>
79
-
80
- <p align="center">
81
- <a href="https://uelng8wukz.feishu.cn/wiki/QIpkwpQo2iSdkwk9nP6cNSPlnPc"><b>中文</b></a> |
82
-
83
- </p>
84
-
85
- ---
86
-
87
- *Latest News* 🔥
88
- - [2025/01] Release Auto-Coder 0.1.208
89
- - [2024/09] Release Auto-Coder 0.1.163
90
- - [2024/08] Release Auto-Coder 0.1.143
91
- - [2024/07] Release Auto-Coder 0.1.115
92
- - [2024/06] Release Auto-Coder 0.1.82
93
- - [2024/05] Release Auto-Coder 0.1.73
94
- - [2024/04] Release Auto-Coder 0.1.46
95
- - [2024/03] Release Auto-Coder 0.1.25
96
- - [2024/03] Release Auto-Coder 0.1.24
97
-
98
- ---
99
-
100
- ## Installation
101
-
102
- ```shell
103
- conda create --name autocoder python=3.10.11
104
- conda activate autocoder
105
- pip install -U auto-coder
106
- auto-coder.chat
107
- ```
108
-
109
- ## Tutorial
110
-
111
- 0. [Auto-Coder.Chat: 通向智能编程之路](https://uelng8wukz.feishu.cn/wiki/QIpkwpQo2iSdkwk9nP6cNSPlnPc)
@@ -1,303 +0,0 @@
1
- """
2
- Compatibility layer for existing conversation implementations.
3
-
4
- This module provides adapter functions and classes to help
5
- transition from the existing conversation implementations to
6
- the new unified conversation manager.
7
- """
8
-
9
- from typing import Dict, List, Any, Optional, Callable, Union
10
- import time
11
- from pydantic import BaseModel
12
-
13
- from autocoder.common import AutoCoderArgs
14
- from autocoder.common.conversations.conversation_manager import (
15
- ConversationManager,
16
- ConversationType,
17
- get_conversation_manager,
18
- Message
19
- )
20
-
21
-
22
- # ======= CommandMessage (auto_command.py) Compatibility =======
23
-
24
- class CommandMessage(BaseModel):
25
- """Compatible with auto_command.py CommandMessage."""
26
- role: str
27
- content: str
28
-
29
-
30
- class ExtendedCommandMessage(BaseModel):
31
- """Compatible with auto_command.py ExtendedCommandMessage."""
32
- message: CommandMessage
33
- timestamp: str
34
-
35
-
36
- class CommandConversation(BaseModel):
37
- """Compatible with auto_command.py CommandConversation."""
38
- history: Dict[str, ExtendedCommandMessage]
39
- current_conversation: List[ExtendedCommandMessage]
40
-
41
-
42
- def command_message_to_message(cmd_msg: Union[CommandMessage, ExtendedCommandMessage]) -> Message:
43
- """Convert a CommandMessage or ExtendedCommandMessage to a Message."""
44
- if isinstance(cmd_msg, ExtendedCommandMessage):
45
- return Message(
46
- role=cmd_msg.message.role,
47
- content=cmd_msg.message.content,
48
- timestamp=int(cmd_msg.timestamp)
49
- )
50
- else:
51
- return Message(
52
- role=cmd_msg.role,
53
- content=cmd_msg.content
54
- )
55
-
56
-
57
- def message_to_command_message(msg: Message) -> ExtendedCommandMessage:
58
- """Convert a Message to an ExtendedCommandMessage."""
59
- return ExtendedCommandMessage(
60
- message=CommandMessage(
61
- role=msg.role,
62
- content=msg.content or ""
63
- ),
64
- timestamp=str(msg.timestamp or int(time.time()))
65
- )
66
-
67
-
68
- def load_command_conversation(args: AutoCoderArgs, conv_id: str = "command") -> CommandConversation:
69
- """
70
- Load a command conversation in the old format.
71
-
72
- Args:
73
- args: AutoCoderArgs object
74
- conv_id: Conversation ID (defaults to "command")
75
-
76
- Returns:
77
- A CommandConversation object compatible with auto_command.py
78
- """
79
- manager = get_conversation_manager(args)
80
- conversation = manager.get_conversation(
81
- conv_id=conv_id,
82
- conv_type=ConversationType.COMMAND,
83
- create_if_not_exists=True
84
- )
85
-
86
- # Convert to old format
87
- current_conversation = [
88
- message_to_command_message(msg)
89
- for msg in conversation.messages
90
- ]
91
-
92
- # Convert archived conversations
93
- history = {}
94
- if conversation.archived_conversations:
95
- for timestamp, messages in conversation.archived_conversations.items():
96
- history[timestamp] = [
97
- message_to_command_message(msg)
98
- for msg in messages
99
- ]
100
-
101
- return CommandConversation(
102
- history=history,
103
- current_conversation=current_conversation
104
- )
105
-
106
-
107
- def save_command_conversation(
108
- args: AutoCoderArgs,
109
- conv: CommandConversation,
110
- conv_id: str = "command"
111
- ) -> None:
112
- """
113
- Save a command conversation from the old format.
114
-
115
- Args:
116
- args: AutoCoderArgs object
117
- conv: CommandConversation object
118
- conv_id: Conversation ID (defaults to "command")
119
- """
120
- manager = get_conversation_manager(args)
121
- conversation = manager.get_conversation(
122
- conv_id=conv_id,
123
- conv_type=ConversationType.COMMAND,
124
- create_if_not_exists=True
125
- )
126
-
127
- # Convert messages
128
- conversation.messages = [
129
- command_message_to_message(msg)
130
- for msg in conv.current_conversation
131
- ]
132
-
133
- # Convert archived conversations
134
- conversation.archived_conversations = {}
135
- for timestamp, messages in conv.history.items():
136
- conversation.archived_conversations[timestamp] = [
137
- command_message_to_message(msg)
138
- for msg in messages
139
- ]
140
-
141
- # Save
142
- manager._save_conversation(conversation)
143
-
144
-
145
- def save_to_command_memory_file(
146
- args: AutoCoderArgs,
147
- query: str,
148
- response: str,
149
- conv_id: str = "command"
150
- ) -> None:
151
- """
152
- Save a command conversation message pair.
153
-
154
- Args:
155
- args: AutoCoderArgs object
156
- query: User query
157
- response: Assistant response
158
- conv_id: Conversation ID
159
- """
160
- manager = get_conversation_manager(args)
161
- conversation = manager.get_conversation(
162
- conv_id=conv_id,
163
- conv_type=ConversationType.COMMAND,
164
- create_if_not_exists=True
165
- )
166
-
167
- # Add the messages
168
- manager.add_user_message(conv_id, query)
169
- manager.add_assistant_message(conv_id, response)
170
-
171
-
172
- # ======= AgenticConversation (agentic_edit_conversation.py) Compatibility =======
173
-
174
- def get_agentic_conversation(
175
- args: AutoCoderArgs,
176
- conversation_name: Optional[str] = None,
177
- event_id: Optional[str] = None
178
- ) -> 'AgenticConversationWrapper':
179
- """
180
- Get an AgenticConversation wrapper that mimics the original class.
181
-
182
- Args:
183
- args: AutoCoderArgs object
184
- conversation_name: Optional conversation name
185
- event_id: Optional event ID
186
-
187
- Returns:
188
- An AgenticConversationWrapper object compatible with agentic_edit_conversation.py
189
- """
190
- return AgenticConversationWrapper(args, conversation_name, event_id)
191
-
192
-
193
- class AgenticConversationWrapper:
194
- """Wrapper that mimics the AgenticConversation class from agentic_edit_conversation.py."""
195
-
196
- def __init__(
197
- self,
198
- args: AutoCoderArgs,
199
- conversation_name: Optional[str] = None,
200
- event_id: Optional[str] = None,
201
- initial_history: Optional[List[Dict[str, Any]]] = None
202
- ):
203
- """
204
- Initialize the AgenticConversation wrapper.
205
-
206
- Args:
207
- args: AutoCoderArgs object
208
- conversation_name: Optional conversation name, used as conv_id
209
- event_id: Optional event ID to associate with this conversation
210
- initial_history: Optional initial conversation history
211
- """
212
- self.args = args
213
- self.project_path = args.source_dir
214
- self.conversation_name = conversation_name or "agentic_edit"
215
- self.event_id = event_id
216
-
217
- # Get the conversation manager
218
- self.manager = get_conversation_manager(args)
219
-
220
- # Get or create the conversation
221
- self.conversation = self.manager.get_conversation(
222
- conv_id=self.conversation_name,
223
- event_id=self.event_id,
224
- conv_type=ConversationType.AGENTIC_EDIT,
225
- create_if_not_exists=True
226
- )
227
-
228
- # Add initial history if provided
229
- if initial_history:
230
- self._add_initial_history(initial_history)
231
-
232
- def _add_initial_history(self, history: List[Dict[str, Any]]) -> None:
233
- """Add initial history to the conversation."""
234
- for msg in history:
235
- role = msg.get("role", "")
236
- content = msg.get("content", "")
237
- tool_calls = msg.get("tool_calls", None)
238
- tool_call_id = msg.get("tool_call_id", None)
239
-
240
- self.manager.add_message(
241
- self.conversation.id,
242
- role,
243
- content,
244
- tool_calls=tool_calls,
245
- tool_call_id=tool_call_id
246
- )
247
-
248
- def add_message(self, role: str, content: Any, **kwargs) -> None:
249
- """Add a message to the conversation."""
250
- self.manager.add_message(
251
- self.conversation.id,
252
- role,
253
- content,
254
- **kwargs
255
- )
256
-
257
- def add_user_message(self, content: str) -> None:
258
- """Add a user message to the conversation."""
259
- self.manager.add_user_message(self.conversation.id, content)
260
-
261
- def add_assistant_message(self, content: str) -> None:
262
- """Add an assistant message to the conversation."""
263
- self.manager.add_assistant_message(self.conversation.id, content)
264
-
265
- def append_to_last_message(self, content: str, role: str = "assistant") -> None:
266
- """Append content to the last message."""
267
- self.manager.append_to_last_message(
268
- self.conversation.id,
269
- content,
270
- role
271
- )
272
-
273
- def add_assistant_tool_call_message(self, tool_calls: List[Dict[str, Any]], content: Optional[str] = None) -> None:
274
- """Add a tool call message from the assistant."""
275
- self.manager.add_tool_call_message(
276
- self.conversation.id,
277
- tool_calls,
278
- content
279
- )
280
-
281
- def add_tool_result_message(self, tool_call_id: str, content: Any) -> None:
282
- """Add a tool result message."""
283
- self.manager.add_tool_result_message(
284
- self.conversation.id,
285
- tool_call_id,
286
- content
287
- )
288
-
289
- def get_history(self) -> List[Dict[str, Any]]:
290
- """Get the conversation history in the format expected by agentic_edit."""
291
- return self.manager.get_history_as_dict_list(self.conversation.id)
292
-
293
- def clear_history(self) -> None:
294
- """Clear the conversation history."""
295
- self.manager.clear_conversation(self.conversation.id)
296
-
297
- def __len__(self) -> int:
298
- """Return the number of messages in the conversation."""
299
- return len(self.conversation.messages)
300
-
301
- def __str__(self) -> str:
302
- """Return a string representation of the conversation."""
303
- return str(self.get_history())