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.

Files changed (66) hide show
  1. auto_coder-0.1.399.dist-info/METADATA +396 -0
  2. {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.dist-info}/RECORD +62 -28
  3. {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.dist-info}/WHEEL +1 -1
  4. {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.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 +510 -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} +1 -33
  21. autocoder/common/ac_style_command_parser/test_parser.py +516 -0
  22. autocoder/common/command_completer_v2.py +1 -1
  23. autocoder/common/command_file_manager/examples.py +22 -8
  24. autocoder/common/command_file_manager/manager.py +37 -6
  25. autocoder/common/conversations/get_conversation_manager.py +143 -0
  26. autocoder/common/conversations/manager.py +122 -11
  27. autocoder/common/conversations/storage/index_manager.py +89 -0
  28. autocoder/common/v2/agent/agentic_edit.py +131 -18
  29. autocoder/common/v2/agent/agentic_edit_types.py +10 -0
  30. autocoder/common/v2/code_auto_generate_editblock.py +10 -2
  31. autocoder/dispacher/__init__.py +10 -0
  32. autocoder/rags.py +0 -27
  33. autocoder/run_context.py +1 -0
  34. autocoder/sdk/__init__.py +188 -0
  35. autocoder/sdk/cli/__init__.py +15 -0
  36. autocoder/sdk/cli/__main__.py +26 -0
  37. autocoder/sdk/cli/completion_wrapper.py +38 -0
  38. autocoder/sdk/cli/formatters.py +211 -0
  39. autocoder/sdk/cli/handlers.py +174 -0
  40. autocoder/sdk/cli/install_completion.py +301 -0
  41. autocoder/sdk/cli/main.py +284 -0
  42. autocoder/sdk/cli/options.py +72 -0
  43. autocoder/sdk/constants.py +102 -0
  44. autocoder/sdk/core/__init__.py +20 -0
  45. autocoder/sdk/core/auto_coder_core.py +867 -0
  46. autocoder/sdk/core/bridge.py +497 -0
  47. autocoder/sdk/example.py +0 -0
  48. autocoder/sdk/exceptions.py +72 -0
  49. autocoder/sdk/models/__init__.py +19 -0
  50. autocoder/sdk/models/messages.py +209 -0
  51. autocoder/sdk/models/options.py +194 -0
  52. autocoder/sdk/models/responses.py +311 -0
  53. autocoder/sdk/session/__init__.py +32 -0
  54. autocoder/sdk/session/session.py +106 -0
  55. autocoder/sdk/session/session_manager.py +56 -0
  56. autocoder/sdk/utils/__init__.py +24 -0
  57. autocoder/sdk/utils/formatters.py +216 -0
  58. autocoder/sdk/utils/io_utils.py +302 -0
  59. autocoder/sdk/utils/validators.py +287 -0
  60. autocoder/version.py +2 -1
  61. auto_coder-0.1.398.dist-info/METADATA +0 -111
  62. autocoder/common/conversations/compatibility.py +0 -303
  63. autocoder/common/conversations/conversation_manager.py +0 -502
  64. autocoder/common/conversations/example.py +0 -152
  65. {auto_coder-0.1.398.dist-info → auto_coder-0.1.399.dist-info/licenses}/LICENSE +0 -0
  66. {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
- # yield LLMOutputEvent(text=tool_xml)
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
- else:
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
  ====
@@ -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
@@ -9,6 +9,7 @@ class RunMode(Enum):
9
9
  """Enum representing different run modes for Auto-Coder."""
10
10
  TERMINAL = auto()
11
11
  WEB = auto()
12
+ API = auto()
12
13
 
13
14
 
14
15
  class RunContext:
@@ -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
+