auto-coder 0.1.398__py3-none-any.whl → 0.1.399__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.399.dist-info/METADATA +396 -0
- {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.dist-info}/RECORD +62 -28
- {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.dist-info}/WHEEL +1 -1
- {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.dist-info}/entry_points.txt +2 -0
- autocoder/agent/base_agentic/base_agent.py +2 -2
- autocoder/agent/base_agentic/tools/replace_in_file_tool_resolver.py +1 -1
- autocoder/agent/entry_command_agent/__init__.py +29 -0
- autocoder/agent/entry_command_agent/auto_tool.py +61 -0
- autocoder/agent/entry_command_agent/chat.py +475 -0
- autocoder/agent/entry_command_agent/designer.py +53 -0
- autocoder/agent/entry_command_agent/generate_command.py +50 -0
- autocoder/agent/entry_command_agent/project_reader.py +58 -0
- autocoder/agent/entry_command_agent/voice2text.py +71 -0
- autocoder/auto_coder.py +23 -548
- autocoder/auto_coder_runner.py +510 -8
- autocoder/chat/rules_command.py +1 -1
- autocoder/chat_auto_coder.py +6 -1
- autocoder/common/ac_style_command_parser/__init__.py +15 -0
- autocoder/common/ac_style_command_parser/example.py +7 -0
- autocoder/{command_parser.py → common/ac_style_command_parser/parser.py} +1 -33
- autocoder/common/ac_style_command_parser/test_parser.py +516 -0
- autocoder/common/command_completer_v2.py +1 -1
- autocoder/common/command_file_manager/examples.py +22 -8
- autocoder/common/command_file_manager/manager.py +37 -6
- autocoder/common/conversations/get_conversation_manager.py +143 -0
- autocoder/common/conversations/manager.py +122 -11
- autocoder/common/conversations/storage/index_manager.py +89 -0
- autocoder/common/v2/agent/agentic_edit.py +131 -18
- autocoder/common/v2/agent/agentic_edit_types.py +10 -0
- autocoder/common/v2/code_auto_generate_editblock.py +10 -2
- autocoder/dispacher/__init__.py +10 -0
- autocoder/rags.py +0 -27
- autocoder/run_context.py +1 -0
- autocoder/sdk/__init__.py +188 -0
- autocoder/sdk/cli/__init__.py +15 -0
- autocoder/sdk/cli/__main__.py +26 -0
- autocoder/sdk/cli/completion_wrapper.py +38 -0
- autocoder/sdk/cli/formatters.py +211 -0
- autocoder/sdk/cli/handlers.py +174 -0
- autocoder/sdk/cli/install_completion.py +301 -0
- autocoder/sdk/cli/main.py +284 -0
- autocoder/sdk/cli/options.py +72 -0
- autocoder/sdk/constants.py +102 -0
- autocoder/sdk/core/__init__.py +20 -0
- autocoder/sdk/core/auto_coder_core.py +867 -0
- autocoder/sdk/core/bridge.py +497 -0
- autocoder/sdk/example.py +0 -0
- autocoder/sdk/exceptions.py +72 -0
- autocoder/sdk/models/__init__.py +19 -0
- autocoder/sdk/models/messages.py +209 -0
- autocoder/sdk/models/options.py +194 -0
- autocoder/sdk/models/responses.py +311 -0
- autocoder/sdk/session/__init__.py +32 -0
- autocoder/sdk/session/session.py +106 -0
- autocoder/sdk/session/session_manager.py +56 -0
- autocoder/sdk/utils/__init__.py +24 -0
- autocoder/sdk/utils/formatters.py +216 -0
- autocoder/sdk/utils/io_utils.py +302 -0
- autocoder/sdk/utils/validators.py +287 -0
- autocoder/version.py +2 -1
- auto_coder-0.1.398.dist-info/METADATA +0 -111
- autocoder/common/conversations/compatibility.py +0 -303
- autocoder/common/conversations/conversation_manager.py +0 -502
- autocoder/common/conversations/example.py +0 -152
- {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.dist-info/licenses}/LICENSE +0 -0
- {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.dist-info}/top_level.txt +0 -0
|
@@ -79,10 +79,12 @@ from autocoder.common.v2.agent.agentic_edit_types import (AgenticEditRequest, To
|
|
|
79
79
|
LLMOutputEvent, LLMThinkingEvent, ToolCallEvent,
|
|
80
80
|
ToolResultEvent, CompletionEvent, PlanModeRespondEvent, ErrorEvent, TokenUsageEvent,
|
|
81
81
|
WindowLengthChangeEvent,
|
|
82
|
+
ConversationIdEvent,
|
|
82
83
|
# Import specific tool types for display mapping
|
|
83
84
|
ReadFileTool, WriteToFileTool, ReplaceInFileTool, ExecuteCommandTool,
|
|
84
85
|
ListFilesTool, SearchFilesTool, ListCodeDefinitionNamesTool,
|
|
85
|
-
AskFollowupQuestionTool, UseMcpTool, AttemptCompletionTool
|
|
86
|
+
AskFollowupQuestionTool, UseMcpTool, AttemptCompletionTool,
|
|
87
|
+
AgenticEditConversationConfig
|
|
86
88
|
)
|
|
87
89
|
from autocoder.common.rag_manager import RAGManager
|
|
88
90
|
from autocoder.rag.token_counter import count_tokens
|
|
@@ -103,6 +105,12 @@ TOOL_RESOLVER_MAP: Dict[Type[BaseTool], Type[BaseToolResolver]] = {
|
|
|
103
105
|
UseMcpTool: UseMcpToolResolver,
|
|
104
106
|
UseRAGTool: UseRAGToolResolver
|
|
105
107
|
}
|
|
108
|
+
from autocoder.common.conversations.get_conversation_manager import (
|
|
109
|
+
get_conversation_manager,
|
|
110
|
+
get_conversation_manager_config,
|
|
111
|
+
reset_conversation_manager
|
|
112
|
+
)
|
|
113
|
+
from autocoder.common.conversations import ConversationManagerConfig
|
|
106
114
|
|
|
107
115
|
|
|
108
116
|
# --- Tool Display Customization is now handled by agentic_tool_display.py ---
|
|
@@ -117,7 +125,8 @@ class AgenticEdit:
|
|
|
117
125
|
args: AutoCoderArgs,
|
|
118
126
|
memory_config: MemoryConfig,
|
|
119
127
|
command_config: Optional[CommandConfig] = None,
|
|
120
|
-
conversation_name:Optional[str] = "current"
|
|
128
|
+
conversation_name:Optional[str] = "current",
|
|
129
|
+
conversation_config:Optional[AgenticEditConversationConfig] = None
|
|
121
130
|
):
|
|
122
131
|
self.llm = llm
|
|
123
132
|
self.context_prune_llm = get_single_llm(args.context_prune_model or args.model,product_mode=args.product_mode)
|
|
@@ -127,7 +136,7 @@ class AgenticEdit:
|
|
|
127
136
|
self.files = files
|
|
128
137
|
# Removed self.max_iterations
|
|
129
138
|
# Note: This might need updating based on the new flow
|
|
130
|
-
self.conversation_history = conversation_history
|
|
139
|
+
self.conversation_history = conversation_history
|
|
131
140
|
|
|
132
141
|
self.current_conversations = []
|
|
133
142
|
self.memory_config = memory_config
|
|
@@ -183,6 +192,19 @@ class AgenticEdit:
|
|
|
183
192
|
# 格式: { file_path: FileChangeEntry(...) }
|
|
184
193
|
self.file_changes: Dict[str, FileChangeEntry] = {}
|
|
185
194
|
|
|
195
|
+
# 对话管理器
|
|
196
|
+
self.conversation_config =conversation_config
|
|
197
|
+
self.conversation_manager = get_conversation_manager()
|
|
198
|
+
|
|
199
|
+
if self.conversation_config.action == "new":
|
|
200
|
+
conversation_id = self.conversation_manager.create_conversation(name=self.conversation_config.query or "New Conversation",
|
|
201
|
+
description=self.conversation_config.query or "New Conversation")
|
|
202
|
+
self.conversation_manager.set_current_conversation(conversation_id)
|
|
203
|
+
|
|
204
|
+
if self.conversation_config.action == "resume" and self.conversation_config.conversation_id:
|
|
205
|
+
self.conversation_manager.set_current_conversation(self.conversation_config.conversation_id)
|
|
206
|
+
|
|
207
|
+
|
|
186
208
|
@byzerllm.prompt()
|
|
187
209
|
def generate_library_docs_prompt(self, libraries_with_paths: List[Dict[str, str]], docs_content: str) -> Dict[str, Any]:
|
|
188
210
|
"""
|
|
@@ -419,7 +441,7 @@ class AgenticEdit:
|
|
|
419
441
|
<list_code_definition_names>
|
|
420
442
|
<path>Directory path here</path>
|
|
421
443
|
</list_code_definition_names>
|
|
422
|
-
|
|
444
|
+
|
|
423
445
|
## ask_followup_question
|
|
424
446
|
Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth.
|
|
425
447
|
Parameters:
|
|
@@ -431,7 +453,7 @@ class AgenticEdit:
|
|
|
431
453
|
<options>
|
|
432
454
|
Array of options here (optional), e.g. ["Option 1", "Option 2", "Option 3"]
|
|
433
455
|
</options>
|
|
434
|
-
</ask_followup_question>
|
|
456
|
+
</ask_followup_question>
|
|
435
457
|
|
|
436
458
|
## attempt_completion
|
|
437
459
|
Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. Optionally you may provide a CLI command to showcase the result of your work. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again.
|
|
@@ -1096,6 +1118,7 @@ class AgenticEdit:
|
|
|
1096
1118
|
"enable_active_context_in_generate": self.args.enable_active_context_in_generate,
|
|
1097
1119
|
"extra_docs": extra_docs,
|
|
1098
1120
|
"file_paths_str": file_paths_str,
|
|
1121
|
+
"agentic_auto_approve": self.args.enable_agentic_auto_approve,
|
|
1099
1122
|
}
|
|
1100
1123
|
|
|
1101
1124
|
# Removed _execute_command_result and execute_auto_command methods
|
|
@@ -1144,7 +1167,7 @@ class AgenticEdit:
|
|
|
1144
1167
|
"""
|
|
1145
1168
|
Analyzes the user request, interacts with the LLM, parses responses,
|
|
1146
1169
|
executes tools, and yields structured events for visualization until completion or error.
|
|
1147
|
-
"""
|
|
1170
|
+
"""
|
|
1148
1171
|
logger.info(f"Starting analyze method with user input: {request.user_input[:50]}...")
|
|
1149
1172
|
system_prompt = self._analyze.prompt(request)
|
|
1150
1173
|
logger.info(f"Generated system prompt with length: {len(system_prompt)}")
|
|
@@ -1154,7 +1177,7 @@ class AgenticEdit:
|
|
|
1154
1177
|
conversations = [
|
|
1155
1178
|
{"role": "system", "content": system_prompt},
|
|
1156
1179
|
]
|
|
1157
|
-
|
|
1180
|
+
|
|
1158
1181
|
# Add third-party library documentation information
|
|
1159
1182
|
try:
|
|
1160
1183
|
package_manager = LLMFriendlyPackageManager(
|
|
@@ -1199,12 +1222,36 @@ class AgenticEdit:
|
|
|
1199
1222
|
})
|
|
1200
1223
|
|
|
1201
1224
|
except Exception as e:
|
|
1202
|
-
logger.warning(f"Failed to load library documentation: {str(e)}")
|
|
1203
|
-
|
|
1225
|
+
logger.warning(f"Failed to load library documentation: {str(e)}")
|
|
1226
|
+
|
|
1227
|
+
if self.conversation_config.action == "resume":
|
|
1228
|
+
current_conversation = self.conversation_manager.get_current_conversation()
|
|
1229
|
+
# 如果继续的是当前的对话,将其消息加入到 conversations 中
|
|
1230
|
+
if current_conversation and current_conversation.get('messages'):
|
|
1231
|
+
for message in current_conversation['messages']:
|
|
1232
|
+
# 确保消息格式正确(包含 role 和 content 字段)
|
|
1233
|
+
if isinstance(message, dict) and 'role' in message and 'content' in message:
|
|
1234
|
+
conversations.append({
|
|
1235
|
+
"role": message['role'],
|
|
1236
|
+
"content": message['content']
|
|
1237
|
+
})
|
|
1238
|
+
logger.info(f"Resumed conversation with {len(current_conversation['messages'])} existing messages")
|
|
1239
|
+
|
|
1240
|
+
if self.conversation_manager.get_current_conversation_id() is None:
|
|
1241
|
+
conv_id = self.conversation_manager.create_conversation(name=self.conversation_config.query,description=self.conversation_config.query)
|
|
1242
|
+
self.conversation_manager.set_current_conversation(conv_id)
|
|
1243
|
+
|
|
1244
|
+
self.conversation_manager.set_current_conversation(self.conversation_manager.get_current_conversation_id())
|
|
1245
|
+
yield ConversationIdEvent(conversation_id=self.conversation_manager.get_current_conversation_id())
|
|
1246
|
+
|
|
1204
1247
|
conversations.append({
|
|
1205
1248
|
"role": "user", "content": request.user_input
|
|
1206
|
-
})
|
|
1249
|
+
})
|
|
1207
1250
|
|
|
1251
|
+
self.conversation_manager.append_message_to_current(
|
|
1252
|
+
role="user",
|
|
1253
|
+
content=request.user_input,
|
|
1254
|
+
metadata={})
|
|
1208
1255
|
|
|
1209
1256
|
self.current_conversations = conversations
|
|
1210
1257
|
|
|
@@ -1292,7 +1339,12 @@ class AgenticEdit:
|
|
|
1292
1339
|
conversations.append({
|
|
1293
1340
|
"role": "assistant",
|
|
1294
1341
|
"content": assistant_buffer + tool_xml
|
|
1295
|
-
})
|
|
1342
|
+
})
|
|
1343
|
+
self.conversation_manager.append_message_to_current(
|
|
1344
|
+
role="assistant",
|
|
1345
|
+
content=assistant_buffer + tool_xml,
|
|
1346
|
+
metadata={})
|
|
1347
|
+
|
|
1296
1348
|
assistant_buffer = "" # Reset buffer after tool call
|
|
1297
1349
|
|
|
1298
1350
|
# 计算当前对话的总 token 数量并触发事件
|
|
@@ -1311,7 +1363,7 @@ class AgenticEdit:
|
|
|
1311
1363
|
completion_event = CompletionEvent(completion=tool_obj, completion_xml=tool_xml)
|
|
1312
1364
|
logger.info(
|
|
1313
1365
|
"AgenticEdit analyze loop finished due to AttemptCompletion.")
|
|
1314
|
-
save_formatted_log(self.args.source_dir, json.dumps(conversations, ensure_ascii=False), "agentic_conversation")
|
|
1366
|
+
save_formatted_log(self.args.source_dir, json.dumps(conversations, ensure_ascii=False), "agentic_conversation")
|
|
1315
1367
|
mark_event_should_finish = True
|
|
1316
1368
|
should_yield_completion_event = True
|
|
1317
1369
|
continue
|
|
@@ -1387,6 +1439,10 @@ class AgenticEdit:
|
|
|
1387
1439
|
"role": "user", # Simulating the user providing the tool result
|
|
1388
1440
|
"content": error_xml
|
|
1389
1441
|
})
|
|
1442
|
+
self.conversation_manager.append_message_to_current(
|
|
1443
|
+
role="user",
|
|
1444
|
+
content=error_xml,
|
|
1445
|
+
metadata={})
|
|
1390
1446
|
|
|
1391
1447
|
# 计算当前对话的总 token 数量并触发事件
|
|
1392
1448
|
current_conversation_str = json.dumps(conversations, ensure_ascii=False)
|
|
@@ -1425,6 +1481,9 @@ class AgenticEdit:
|
|
|
1425
1481
|
logger.info("Adding new assistant message")
|
|
1426
1482
|
conversations.append(
|
|
1427
1483
|
{"role": "assistant", "content": assistant_buffer})
|
|
1484
|
+
self.conversation_manager.append_message_to_current(
|
|
1485
|
+
role="assistant", content=assistant_buffer,metadata={})
|
|
1486
|
+
|
|
1428
1487
|
elif last_message["role"] == "assistant":
|
|
1429
1488
|
logger.info("Appending to existing assistant message")
|
|
1430
1489
|
last_message["content"] += assistant_buffer
|
|
@@ -1441,6 +1500,11 @@ class AgenticEdit:
|
|
|
1441
1500
|
"role": "user",
|
|
1442
1501
|
"content": "NOTE: You must use an appropriate tool (such as read_file, write_to_file, execute_command, etc.) or explicitly complete the task (using attempt_completion). Do not provide text responses without taking concrete actions. Please select a suitable tool to continue based on the user's task."
|
|
1443
1502
|
})
|
|
1503
|
+
|
|
1504
|
+
self.conversation_manager.append_message_to_current(
|
|
1505
|
+
role="user",
|
|
1506
|
+
content="NOTE: You must use an appropriate tool (such as read_file, write_to_file, execute_command, etc.) or explicitly complete the task (using attempt_completion). Do not provide text responses without taking concrete actions. Please select a suitable tool to continue based on the user's task.",
|
|
1507
|
+
metadata={})
|
|
1444
1508
|
|
|
1445
1509
|
# 计算当前对话的总 token 数量并触发事件
|
|
1446
1510
|
current_conversation_str = json.dumps(conversations, ensure_ascii=False)
|
|
@@ -1580,9 +1644,9 @@ class AgenticEdit:
|
|
|
1580
1644
|
else:
|
|
1581
1645
|
yield ToolCallEvent(tool=tool_obj, tool_xml=reconstructed_xml)
|
|
1582
1646
|
else:
|
|
1583
|
-
yield ErrorEvent(message=f"Failed to parse tool: <{current_tool_tag}>")
|
|
1647
|
+
# yield ErrorEvent(message=f"Failed to parse tool: <{current_tool_tag}>")
|
|
1584
1648
|
# Optionally yield the raw XML as plain text?
|
|
1585
|
-
|
|
1649
|
+
yield LLMOutputEvent(text=f"Failed to parse tool: <{current_tool_tag}> {tool_xml}")
|
|
1586
1650
|
|
|
1587
1651
|
buffer = buffer[tool_block_end_index:]
|
|
1588
1652
|
in_tool_block = False
|
|
@@ -1924,17 +1988,41 @@ class AgenticEdit:
|
|
|
1924
1988
|
self.git_require_msg(
|
|
1925
1989
|
source_dir=self.args.source_dir, error=str(e)),
|
|
1926
1990
|
style="red"
|
|
1927
|
-
)
|
|
1928
|
-
|
|
1929
|
-
self.printer.print_in_terminal("no_changes_made")
|
|
1991
|
+
)
|
|
1992
|
+
|
|
1930
1993
|
|
|
1931
1994
|
def run_in_terminal(self, request: AgenticEditRequest):
|
|
1932
1995
|
"""
|
|
1933
1996
|
Runs the agentic edit process based on the request and displays
|
|
1934
1997
|
the interaction streamingly in the terminal using Rich.
|
|
1935
1998
|
"""
|
|
1999
|
+
import json
|
|
1936
2000
|
console = Console()
|
|
1937
2001
|
project_name = os.path.basename(os.path.abspath(self.args.source_dir))
|
|
2002
|
+
|
|
2003
|
+
if self.conversation_config.action == "list":
|
|
2004
|
+
conversations = self.conversation_manager.list_conversations()
|
|
2005
|
+
# 只保留 conversation_id 和 name 字段
|
|
2006
|
+
filtered_conversations = []
|
|
2007
|
+
for conv in conversations:
|
|
2008
|
+
filtered_conv = {
|
|
2009
|
+
"conversation_id": conv.get("conversation_id"),
|
|
2010
|
+
"name": conv.get("name")
|
|
2011
|
+
}
|
|
2012
|
+
filtered_conversations.append(filtered_conv)
|
|
2013
|
+
|
|
2014
|
+
# 格式化 JSON 输出,使用 JSON 格式渲染而不是 Markdown
|
|
2015
|
+
json_str = json.dumps(filtered_conversations, ensure_ascii=False, indent=4)
|
|
2016
|
+
console.print(Panel(json_str,
|
|
2017
|
+
title="🏁 Task Completion", border_style="green", title_align="left"))
|
|
2018
|
+
return
|
|
2019
|
+
|
|
2020
|
+
|
|
2021
|
+
if self.conversation_config.action == "new" and not request.user_input.strip():
|
|
2022
|
+
console.print(Panel(Markdown(f"New conversation created: {self.conversation_manager.get_current_conversation_id()}"),
|
|
2023
|
+
title="🏁 Task Completion", border_style="green", title_align="left"))
|
|
2024
|
+
return
|
|
2025
|
+
|
|
1938
2026
|
console.rule(f"[bold cyan]Starting Agentic Edit: {project_name}[/]")
|
|
1939
2027
|
console.print(Panel(
|
|
1940
2028
|
f"[bold]{get_message('/agent/edit/user_query')}:[/bold]\n{request.user_input}", title=get_message("/agent/edit/objective"), border_style="blue"))
|
|
@@ -1952,6 +2040,9 @@ class AgenticEdit:
|
|
|
1952
2040
|
self.apply_pre_changes()
|
|
1953
2041
|
event_stream = self.analyze(request)
|
|
1954
2042
|
for event in event_stream:
|
|
2043
|
+
if isinstance(event, ConversationIdEvent):
|
|
2044
|
+
console.print(f"[dim]Conversation ID: {event.conversation_id}[/dim]")
|
|
2045
|
+
continue
|
|
1955
2046
|
if isinstance(event, TokenUsageEvent):
|
|
1956
2047
|
last_meta: SingleOutputMeta = event.usage
|
|
1957
2048
|
# Get model info for pricing
|
|
@@ -2144,6 +2235,18 @@ class AgenticEdit:
|
|
|
2144
2235
|
finally:
|
|
2145
2236
|
console.rule("[bold cyan]Agentic Edit Finished[/]")
|
|
2146
2237
|
|
|
2238
|
+
def run(self, request: AgenticEditRequest):
|
|
2239
|
+
try:
|
|
2240
|
+
event_stream = self.analyze(request)
|
|
2241
|
+
for agent_event in event_stream:
|
|
2242
|
+
yield agent_event
|
|
2243
|
+
|
|
2244
|
+
except Exception as e:
|
|
2245
|
+
logger.exception(
|
|
2246
|
+
"An unexpected error occurred during agent execution: {e}")
|
|
2247
|
+
raise e
|
|
2248
|
+
|
|
2249
|
+
|
|
2147
2250
|
def run_with_events(self, request: AgenticEditRequest):
|
|
2148
2251
|
"""
|
|
2149
2252
|
Runs the agentic edit process, converting internal events to the
|
|
@@ -2275,6 +2378,16 @@ class AgenticEdit:
|
|
|
2275
2378
|
|
|
2276
2379
|
# 记录日志
|
|
2277
2380
|
logger.info(f"当前会话总 tokens: {agent_event.tokens_used}")
|
|
2381
|
+
|
|
2382
|
+
elif isinstance(agent_event, ConversationIdEvent):
|
|
2383
|
+
metadata.path = "/agent/edit/conversation_id"
|
|
2384
|
+
content = EventContentCreator.create_result(
|
|
2385
|
+
content={
|
|
2386
|
+
"conversation_id": agent_event.conversation_id
|
|
2387
|
+
},
|
|
2388
|
+
metadata={}
|
|
2389
|
+
)
|
|
2390
|
+
event_manager.write_result(content=content.to_dict(), metadata=metadata.to_dict())
|
|
2278
2391
|
|
|
2279
2392
|
elif isinstance(agent_event, ErrorEvent):
|
|
2280
2393
|
metadata.path = "/agent/edit/error"
|
|
@@ -2284,7 +2397,7 @@ class AgenticEdit:
|
|
|
2284
2397
|
details={"agent_event_type": "ErrorEvent"}
|
|
2285
2398
|
)
|
|
2286
2399
|
event_manager.write_error(
|
|
2287
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2400
|
+
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2288
2401
|
else:
|
|
2289
2402
|
metadata.path = "/agent/edit/error"
|
|
2290
2403
|
logger.warning(
|
|
@@ -86,6 +86,11 @@ class TokenUsageEvent(BaseModel):
|
|
|
86
86
|
"""Represents the result of executing a tool."""
|
|
87
87
|
usage: Any
|
|
88
88
|
|
|
89
|
+
|
|
90
|
+
class ConversationIdEvent(BaseModel):
|
|
91
|
+
"""Represents the conversation id."""
|
|
92
|
+
conversation_id: str
|
|
93
|
+
|
|
89
94
|
class PlanModeRespondEvent(BaseModel):
|
|
90
95
|
"""Represents the LLM attempting to complete the task."""
|
|
91
96
|
completion: SkipValidation[PlanModeRespondTool] # Skip validation
|
|
@@ -177,3 +182,8 @@ class CommandConfig(BaseModel):
|
|
|
177
182
|
index_import: SkipValidation[Callable]
|
|
178
183
|
exclude_files: SkipValidation[Callable]
|
|
179
184
|
|
|
185
|
+
class AgenticEditConversationConfig(BaseModel):
|
|
186
|
+
conversation_name: Optional[str] = "current"
|
|
187
|
+
conversation_id: Optional[str] = None
|
|
188
|
+
action: Optional[str] = None
|
|
189
|
+
query: Optional[str] = None
|
|
@@ -52,7 +52,7 @@ class CodeAutoGenerateEditBlock:
|
|
|
52
52
|
package_context: str = ""
|
|
53
53
|
) -> str:
|
|
54
54
|
"""
|
|
55
|
-
如果你需要生成代码,对于每个需要更改的文件,你需要按 *SEARCH/REPLACE block* 的格式进行生成。
|
|
55
|
+
如果你需要生成代码,对于每个需要更改的文件,你需要按 *SEARCH/REPLACE block* 的格式进行生成。
|
|
56
56
|
|
|
57
57
|
# *SEARCH/REPLACE block* Rules:
|
|
58
58
|
|
|
@@ -196,7 +196,15 @@ class CodeAutoGenerateEditBlock:
|
|
|
196
196
|
<extra_context>
|
|
197
197
|
{{ context }}
|
|
198
198
|
</extra_context>
|
|
199
|
-
{%- endif %}
|
|
199
|
+
{%- endif %}
|
|
200
|
+
|
|
201
|
+
====
|
|
202
|
+
|
|
203
|
+
RULES PROVIDED BY SYSTEM
|
|
204
|
+
|
|
205
|
+
Before outputting the *SEARCH/REPLACE block* format, you must carefully think through the user's question and make a complete design. These thoughts and designs should be placed within the <thinking></thinking> tags.
|
|
206
|
+
|
|
207
|
+
====
|
|
200
208
|
|
|
201
209
|
{%- if extra_docs %}
|
|
202
210
|
====
|
autocoder/dispacher/__init__.py
CHANGED
|
@@ -8,6 +8,11 @@ from autocoder.dispacher.actions.action import (
|
|
|
8
8
|
from autocoder.dispacher.actions.plugins.action_regex_project import ActionRegexProject
|
|
9
9
|
from typing import Optional
|
|
10
10
|
import byzerllm
|
|
11
|
+
# from autocoder.common.conversations.get_conversation_manager import (
|
|
12
|
+
# get_conversation_manager,
|
|
13
|
+
# get_conversation_manager_config,
|
|
14
|
+
# reset_conversation_manager
|
|
15
|
+
# )
|
|
11
16
|
|
|
12
17
|
|
|
13
18
|
class Dispacher:
|
|
@@ -16,6 +21,11 @@ class Dispacher:
|
|
|
16
21
|
self.llm = llm
|
|
17
22
|
|
|
18
23
|
def dispach(self):
|
|
24
|
+
# manager = get_conversation_manager()
|
|
25
|
+
# if not manager.get_current_conversation():
|
|
26
|
+
# manager.create_conversation(name="New Conversation", description="New Conversation")
|
|
27
|
+
# manager.set_current_conversation(manager.get_current_conversation_id())
|
|
28
|
+
|
|
19
29
|
args = self.args
|
|
20
30
|
actions = [
|
|
21
31
|
ActionTSProject(args=args, llm=self.llm),
|
autocoder/rags.py
CHANGED
|
@@ -369,30 +369,3 @@ def update_rag_status(name: str, status: str, **kwargs) -> bool:
|
|
|
369
369
|
return rag_manager.update_status(name, status, **kwargs)
|
|
370
370
|
|
|
371
371
|
|
|
372
|
-
# 使用示例
|
|
373
|
-
if __name__ == "__main__":
|
|
374
|
-
# 创建配置
|
|
375
|
-
config = {
|
|
376
|
-
"model": "deepseek_chat",
|
|
377
|
-
"tokenizer_path": "/Users/allwefantasy/Downloads/tokenizer.json",
|
|
378
|
-
"doc_dir": "/path/to/docs",
|
|
379
|
-
"rag_doc_filter_relevance": 2.0,
|
|
380
|
-
"host": "0.0.0.0",
|
|
381
|
-
"port": 8000,
|
|
382
|
-
"enable_hybrid_index": False,
|
|
383
|
-
"required_exts": ".md,.rst",
|
|
384
|
-
"disable_inference_enhance": True
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
# 创建
|
|
388
|
-
create_rag_config("test_rag", config)
|
|
389
|
-
|
|
390
|
-
# 读取
|
|
391
|
-
all_configs = get_rag_config()
|
|
392
|
-
specific_config = get_rag_config("test_rag")
|
|
393
|
-
|
|
394
|
-
# 更新
|
|
395
|
-
update_rag_config("test_rag", {"status": "running", "port": 8001})
|
|
396
|
-
|
|
397
|
-
# 删除
|
|
398
|
-
delete_rag_config("test_rag")
|
autocoder/run_context.py
CHANGED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Auto-Coder SDK
|
|
3
|
+
|
|
4
|
+
为第三方开发者提供的 Python SDK,允许通过命令行工具和 Python API 两种方式使用 Auto-Coder 的核心功能。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import AsyncIterator, Optional, Dict, Any
|
|
8
|
+
|
|
9
|
+
from .core.auto_coder_core import AutoCoderCore
|
|
10
|
+
from .models.options import AutoCodeOptions
|
|
11
|
+
from .models.messages import Message
|
|
12
|
+
from .models.responses import StreamEvent, CodeModificationResult
|
|
13
|
+
from .session.session import Session
|
|
14
|
+
from .session.session_manager import SessionManager
|
|
15
|
+
from .exceptions import (
|
|
16
|
+
AutoCoderSDKError,
|
|
17
|
+
SessionNotFoundError,
|
|
18
|
+
InvalidOptionsError,
|
|
19
|
+
BridgeError,
|
|
20
|
+
ValidationError
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
__version__ = "1.0.0"
|
|
24
|
+
__all__ = [
|
|
25
|
+
# 核心功能
|
|
26
|
+
"query",
|
|
27
|
+
"query_sync",
|
|
28
|
+
"modify_code",
|
|
29
|
+
"modify_code_stream",
|
|
30
|
+
|
|
31
|
+
# 数据模型
|
|
32
|
+
"AutoCodeOptions",
|
|
33
|
+
"Message",
|
|
34
|
+
"StreamEvent",
|
|
35
|
+
"CodeModificationResult",
|
|
36
|
+
|
|
37
|
+
# 会话管理
|
|
38
|
+
"Session",
|
|
39
|
+
"SessionManager",
|
|
40
|
+
|
|
41
|
+
# 异常
|
|
42
|
+
"AutoCoderSDKError",
|
|
43
|
+
"SessionNotFoundError",
|
|
44
|
+
"InvalidOptionsError",
|
|
45
|
+
"BridgeError",
|
|
46
|
+
"ValidationError",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def query(
|
|
51
|
+
prompt: str,
|
|
52
|
+
options: Optional[AutoCodeOptions] = None,
|
|
53
|
+
show_terminal: bool = True
|
|
54
|
+
) -> AsyncIterator[Message]:
|
|
55
|
+
"""
|
|
56
|
+
异步流式查询接口
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
prompt: 查询提示
|
|
60
|
+
options: 配置选项
|
|
61
|
+
show_terminal: 是否在终端显示友好的渲染输出
|
|
62
|
+
|
|
63
|
+
Yields:
|
|
64
|
+
Message: 响应消息流
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
>>> import asyncio
|
|
68
|
+
>>> from autocoder.sdk import query, AutoCodeOptions
|
|
69
|
+
>>>
|
|
70
|
+
>>> async def main():
|
|
71
|
+
... options = AutoCodeOptions(max_turns=3)
|
|
72
|
+
... async for message in query("Write a hello world function", options):
|
|
73
|
+
... print(f"[{message.role}] {message.content}")
|
|
74
|
+
>>>
|
|
75
|
+
>>> asyncio.run(main())
|
|
76
|
+
"""
|
|
77
|
+
if options is None:
|
|
78
|
+
options = AutoCodeOptions()
|
|
79
|
+
core = AutoCoderCore(options)
|
|
80
|
+
async for message in core.query_stream(f"/new {prompt}", show_terminal):
|
|
81
|
+
yield message
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def query_sync(
|
|
85
|
+
prompt: str,
|
|
86
|
+
options: Optional[AutoCodeOptions] = None,
|
|
87
|
+
show_terminal: bool = True
|
|
88
|
+
) -> str:
|
|
89
|
+
"""
|
|
90
|
+
同步查询接口
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
prompt: 查询提示
|
|
94
|
+
options: 配置选项
|
|
95
|
+
show_terminal: 是否在终端显示友好的渲染输出
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
str: 响应内容
|
|
99
|
+
|
|
100
|
+
Example:
|
|
101
|
+
>>> from autocoder.sdk import query_sync, AutoCodeOptions
|
|
102
|
+
>>>
|
|
103
|
+
>>> options = AutoCodeOptions(max_turns=1)
|
|
104
|
+
>>> response = query_sync("Write a simple calculator function", options)
|
|
105
|
+
>>> print(response)
|
|
106
|
+
"""
|
|
107
|
+
if options is None:
|
|
108
|
+
options = AutoCodeOptions()
|
|
109
|
+
core = AutoCoderCore(options)
|
|
110
|
+
return core.query_sync(f"/new {prompt}", show_terminal)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def modify_code(
|
|
114
|
+
prompt: str,
|
|
115
|
+
pre_commit: bool = False,
|
|
116
|
+
extra_args: Optional[Dict[str, Any]] = None,
|
|
117
|
+
options: Optional[AutoCodeOptions] = None,
|
|
118
|
+
show_terminal: bool = True
|
|
119
|
+
) -> CodeModificationResult:
|
|
120
|
+
"""
|
|
121
|
+
代码修改接口
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
prompt: 修改提示
|
|
125
|
+
pre_commit: 是否预提交
|
|
126
|
+
extra_args: 额外参数
|
|
127
|
+
options: 配置选项
|
|
128
|
+
show_terminal: 是否在终端显示友好的渲染输出
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
CodeModificationResult: 修改结果
|
|
132
|
+
|
|
133
|
+
Example:
|
|
134
|
+
>>> from autocoder.sdk import modify_code, AutoCodeOptions
|
|
135
|
+
>>>
|
|
136
|
+
>>> options = AutoCodeOptions(cwd="/path/to/project")
|
|
137
|
+
>>> result = modify_code(
|
|
138
|
+
... "Add error handling to the main function",
|
|
139
|
+
... pre_commit=False,
|
|
140
|
+
... options=options
|
|
141
|
+
... )
|
|
142
|
+
>>>
|
|
143
|
+
>>> if result.success:
|
|
144
|
+
... print(f"Modified files: {result.modified_files}")
|
|
145
|
+
... else:
|
|
146
|
+
... print(f"Error: {result.error_details}")
|
|
147
|
+
"""
|
|
148
|
+
core = AutoCoderCore(options or AutoCodeOptions())
|
|
149
|
+
return core.modify_code(prompt, pre_commit, extra_args, show_terminal)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
async def modify_code_stream(
|
|
153
|
+
prompt: str,
|
|
154
|
+
pre_commit: bool = False,
|
|
155
|
+
extra_args: Optional[Dict[str, Any]] = None,
|
|
156
|
+
options: Optional[AutoCodeOptions] = None,
|
|
157
|
+
show_terminal: bool = True
|
|
158
|
+
) -> AsyncIterator[StreamEvent]:
|
|
159
|
+
"""
|
|
160
|
+
异步流式代码修改接口
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
prompt: 修改提示
|
|
164
|
+
pre_commit: 是否预提交
|
|
165
|
+
extra_args: 额外参数
|
|
166
|
+
options: 配置选项
|
|
167
|
+
show_terminal: 是否在终端显示友好的渲染输出
|
|
168
|
+
|
|
169
|
+
Yields:
|
|
170
|
+
StreamEvent: 修改事件流
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
>>> import asyncio
|
|
174
|
+
>>> from autocoder.sdk import modify_code_stream, AutoCodeOptions
|
|
175
|
+
>>>
|
|
176
|
+
>>> async def main():
|
|
177
|
+
... options = AutoCodeOptions(cwd="/path/to/project")
|
|
178
|
+
... async for event in modify_code_stream(
|
|
179
|
+
... "Refactor the user authentication module",
|
|
180
|
+
... options=options
|
|
181
|
+
... ):
|
|
182
|
+
... print(f"[{event.event_type}] {event.data}")
|
|
183
|
+
>>>
|
|
184
|
+
>>> asyncio.run(main())
|
|
185
|
+
"""
|
|
186
|
+
core = AutoCoderCore(options or AutoCodeOptions())
|
|
187
|
+
async for event in core.modify_code_stream(prompt, pre_commit, extra_args, show_terminal):
|
|
188
|
+
yield event
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Auto-Coder CLI 模块
|
|
3
|
+
|
|
4
|
+
提供命令行接口,允许用户通过终端使用 Auto-Coder 的核心功能。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .main import AutoCoderCLI
|
|
8
|
+
from .options import CLIOptions, CLIResult
|
|
9
|
+
|
|
10
|
+
# 导出main函数作为入口点
|
|
11
|
+
def main():
|
|
12
|
+
"""CLI主入口点函数"""
|
|
13
|
+
return AutoCoderCLI.main()
|
|
14
|
+
|
|
15
|
+
__all__ = ["AutoCoderCLI", "CLIOptions", "CLIResult", "main"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
CLI 模块主入口点
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
import argparse
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
"""主入口点,路由到不同的 CLI 功能"""
|
|
12
|
+
|
|
13
|
+
# 检查是否是自动补全相关的命令
|
|
14
|
+
if len(sys.argv) > 1 and sys.argv[1] in ["install", "uninstall", "test"]:
|
|
15
|
+
# 路由到自动补全安装工具
|
|
16
|
+
from .install_completion import main as install_main
|
|
17
|
+
install_main()
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
# 默认显示自动补全工具的帮助
|
|
21
|
+
from .install_completion import main as install_main
|
|
22
|
+
install_main()
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
main()
|
|
26
|
+
|