auto-coder 0.1.353__py3-none-any.whl → 0.1.355__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 (60) hide show
  1. {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/METADATA +1 -1
  2. {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/RECORD +60 -45
  3. autocoder/agent/agentic_filter.py +1 -1
  4. autocoder/auto_coder.py +8 -0
  5. autocoder/auto_coder_rag.py +37 -1
  6. autocoder/auto_coder_runner.py +58 -77
  7. autocoder/chat/conf_command.py +270 -0
  8. autocoder/chat/models_command.py +485 -0
  9. autocoder/chat_auto_coder.py +29 -24
  10. autocoder/chat_auto_coder_lang.py +26 -2
  11. autocoder/commands/auto_command.py +60 -132
  12. autocoder/commands/auto_web.py +1 -1
  13. autocoder/commands/tools.py +1 -1
  14. autocoder/common/__init__.py +3 -1
  15. autocoder/common/command_completer.py +58 -12
  16. autocoder/common/command_completer_v2.py +576 -0
  17. autocoder/common/conversations/__init__.py +52 -0
  18. autocoder/common/conversations/compatibility.py +303 -0
  19. autocoder/common/conversations/conversation_manager.py +502 -0
  20. autocoder/common/conversations/example.py +152 -0
  21. autocoder/common/file_monitor/__init__.py +5 -0
  22. autocoder/common/file_monitor/monitor.py +383 -0
  23. autocoder/common/global_cancel.py +53 -16
  24. autocoder/common/ignorefiles/__init__.py +4 -0
  25. autocoder/common/ignorefiles/ignore_file_utils.py +103 -0
  26. autocoder/common/ignorefiles/test_ignore_file_utils.py +91 -0
  27. autocoder/common/rulefiles/__init__.py +15 -0
  28. autocoder/common/rulefiles/autocoderrules_utils.py +173 -0
  29. autocoder/common/save_formatted_log.py +54 -0
  30. autocoder/common/v2/agent/agentic_edit.py +10 -39
  31. autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +1 -1
  32. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +73 -43
  33. autocoder/common/v2/code_agentic_editblock_manager.py +9 -9
  34. autocoder/common/v2/code_diff_manager.py +2 -2
  35. autocoder/common/v2/code_editblock_manager.py +31 -18
  36. autocoder/common/v2/code_strict_diff_manager.py +3 -2
  37. autocoder/dispacher/actions/action.py +6 -6
  38. autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
  39. autocoder/events/event_manager_singleton.py +1 -1
  40. autocoder/index/index.py +3 -3
  41. autocoder/models.py +22 -9
  42. autocoder/rag/api_server.py +14 -2
  43. autocoder/rag/cache/local_byzer_storage_cache.py +1 -1
  44. autocoder/rag/cache/local_duckdb_storage_cache.py +8 -0
  45. autocoder/rag/cache/simple_cache.py +63 -33
  46. autocoder/rag/loaders/docx_loader.py +1 -1
  47. autocoder/rag/loaders/filter_utils.py +133 -76
  48. autocoder/rag/loaders/image_loader.py +15 -3
  49. autocoder/rag/loaders/pdf_loader.py +2 -2
  50. autocoder/rag/long_context_rag.py +11 -0
  51. autocoder/rag/qa_conversation_strategy.py +5 -31
  52. autocoder/rag/utils.py +21 -2
  53. autocoder/utils/_markitdown.py +66 -25
  54. autocoder/utils/auto_coder_utils/chat_stream_out.py +4 -4
  55. autocoder/utils/thread_utils.py +9 -27
  56. autocoder/version.py +1 -1
  57. {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/LICENSE +0 -0
  58. {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/WHEEL +0 -0
  59. {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/entry_points.txt +0 -0
  60. {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,270 @@
1
+
2
+ import os
3
+ import io
4
+ import contextlib
5
+ import fnmatch
6
+ import json
7
+ from typing import Dict, Any, List, Callable, Optional
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+ from rich.table import Table
11
+ from rich.text import Text
12
+ from autocoder.auto_coder_runner import save_memory # Import save_memory
13
+ from autocoder.common.conf_validator import ConfigValidator
14
+ from autocoder.common.auto_coder_lang import get_message, get_message_with_format
15
+
16
+ # Helper function to print the configuration table (internal implementation)
17
+ def _print_conf_table(content: Dict[str, Any], title: str = "Configuration Settings"):
18
+ """Display configuration dictionary in a Rich table format."""
19
+ console = Console(file=io.StringIO(), force_terminal=True, color_system="truecolor") # Capture output
20
+
21
+ # Create a styled table with rounded borders
22
+ table = Table(
23
+ show_header=True,
24
+ header_style="bold magenta",
25
+ title=title,
26
+ title_style="bold blue",
27
+ border_style="blue",
28
+ show_lines=True
29
+ )
30
+
31
+ # Add columns with explicit width and alignment
32
+ table.add_column(get_message("conf_key"), style="cyan", justify="right", width=30, no_wrap=False)
33
+ table.add_column(get_message("conf_value"), style="green", justify="left", width=50, no_wrap=False)
34
+
35
+ # Sort keys for consistent display
36
+ for key in sorted(content.keys()):
37
+ value = content[key]
38
+ # Format value based on type
39
+ if isinstance(value, (dict, list)):
40
+ formatted_value = Text(json.dumps(value, indent=2), style="yellow")
41
+ elif isinstance(value, bool):
42
+ formatted_value = Text(str(value), style="bright_green" if value else "red")
43
+ elif isinstance(value, (int, float)):
44
+ formatted_value = Text(str(value), style="bright_cyan")
45
+ else:
46
+ formatted_value = Text(str(value), style="green")
47
+
48
+ table.add_row(str(key), formatted_value)
49
+
50
+ # Add padding and print with a panel
51
+ console.print(Panel(
52
+ table,
53
+ padding=(1, 2),
54
+ subtitle=f"[italic]{get_message('conf_subtitle')}[/italic]",
55
+ border_style="blue"
56
+ ))
57
+ return console.file.getvalue() # Return captured string
58
+
59
+ # --- Command Handlers ---
60
+
61
+ def _handle_list_conf(memory: Dict[str, Any], args: List[str]) -> str:
62
+ """Handles listing configuration settings, supports wildcard filtering."""
63
+ conf = memory.get("conf", {})
64
+ pattern = args[0] if args else "*" # Default to all if no pattern
65
+
66
+ if pattern == "*":
67
+ title = get_message("conf_title")
68
+ filtered_conf = conf
69
+ else:
70
+ title = f"Filtered Configuration (Pattern: {pattern})"
71
+ filtered_conf = {k: v for k, v in conf.items() if fnmatch.fnmatch(k, pattern)}
72
+ if not filtered_conf:
73
+ return f"No configuration keys found matching pattern: {pattern}"
74
+
75
+ if not filtered_conf and pattern == "*":
76
+ return "No configurations set."
77
+
78
+ return _print_conf_table(filtered_conf, title)
79
+
80
+
81
+ def _handle_get_conf(memory: Dict[str, Any], args: List[str]) -> str:
82
+ """Handles getting a specific configuration setting."""
83
+ if len(args) != 1:
84
+ return "Error: 'get' command requires exactly one argument (the key). Usage: /conf get <key>"
85
+ key = args[0]
86
+ conf = memory.get("conf", {})
87
+ value = conf.get(key)
88
+ if value is None:
89
+ return f"Error: Configuration key '{key}' not found."
90
+ else:
91
+ # Format value for better readability
92
+ if isinstance(value, (list, dict)):
93
+ formatted_value = json.dumps(value, indent=2)
94
+ else:
95
+ formatted_value = repr(value)
96
+ return f"{key}: {formatted_value}"
97
+
98
+ def _parse_value(value_str: str) -> Any:
99
+ """Attempts to parse the value string into common types."""
100
+ value_str = value_str.strip()
101
+ if value_str.lower() == 'true':
102
+ return True
103
+ if value_str.lower() == 'false':
104
+ return False
105
+ if value_str.lower() == 'none' or value_str.lower() == 'null':
106
+ return None
107
+ # Keep quoted strings as strings without quotes
108
+ if (value_str.startswith('"') and value_str.endswith('"')) or \
109
+ (value_str.startswith("'") and value_str.endswith("'")):
110
+ return value_str[1:-1]
111
+
112
+ try:
113
+ # Try int first
114
+ return int(value_str)
115
+ except ValueError:
116
+ pass
117
+ try:
118
+ # Then try float
119
+ return float(value_str)
120
+ except ValueError:
121
+ pass
122
+ # If none of the above, return as string
123
+ return value_str
124
+
125
+ def _handle_set_conf(memory: Dict[str, Any], args: List[str]) -> str:
126
+ """Handles setting or updating a configuration setting."""
127
+ if len(args) < 2:
128
+ return "Error: 'set' command requires at least two arguments (key and value). Usage: /conf set <key> <value>"
129
+ key = args[0]
130
+ # Join the rest of the arguments to form the value string
131
+ value_str = " ".join(args[1:])
132
+ try:
133
+ parsed_value = _parse_value(value_str)
134
+
135
+ # Validate before setting
136
+ product_mode = memory.get("conf", {}).get("product_mode", "lite")
137
+ ConfigValidator.validate(key, str(parsed_value), product_mode) # Validate the parsed value as string initially if needed, or adjust validation
138
+
139
+ if "conf" not in memory:
140
+ memory["conf"] = {}
141
+ memory["conf"][key] = parsed_value
142
+ save_memory() # Save after modification
143
+ # Use repr for confirmation message for clarity
144
+ return f"Configuration updated: {key} = {repr(parsed_value)}"
145
+ except Exception as e:
146
+ return f"Error setting configuration for key '{key}': {e}"
147
+
148
+ def _handle_delete_conf(memory: Dict[str, Any], args: List[str]) -> str:
149
+ """Handles deleting a configuration setting."""
150
+ if len(args) != 1:
151
+ return "Error: 'delete' command requires exactly one argument (the key). Usage: /conf delete <key>"
152
+ key = args[0]
153
+ conf = memory.get("conf", {})
154
+ if key in conf:
155
+ try:
156
+ del memory["conf"][key]
157
+ save_memory() # Save after modification
158
+ return f"Configuration deleted: {key}"
159
+ except Exception as e:
160
+ return f"Error deleting key '{key}': {e}"
161
+ else:
162
+ return f"Error: Configuration key '{key}' not found."
163
+
164
+
165
+ def _handle_help(memory: Dict[str, Any], args: List[str]) -> str:
166
+ """Provides help text for the /conf command."""
167
+ if args:
168
+ return f"Error: 'help' command takes no arguments. Usage: /conf help"
169
+
170
+ help_text = """
171
+ /conf command usage:
172
+ /conf [pattern] - Show configurations. Optional wildcard pattern (e.g., *_model, api*).
173
+ /conf get <key> - Get the value of a specific configuration key.
174
+ /conf set <key>:<value> - Set or update a configuration key.
175
+ Value parsed (bool, int, float, None) or treated as string.
176
+ Use quotes ("value with spaces") for explicit strings.
177
+ /conf /drop <key> - Delete a configuration key.
178
+ /conf /export <path> - Export current configuration to a file.
179
+ /conf /import <path> - Import configuration from a file.
180
+ /conf help - Show this help message.
181
+ """
182
+ return help_text.strip()
183
+
184
+ # Command dispatch table
185
+ COMMAND_HANDLERS: Dict[str, Callable[[Dict[str, Any], List[str]], str]] = {
186
+ "list": _handle_list_conf,
187
+ "show": _handle_list_conf, # Alias
188
+ "get": _handle_get_conf,
189
+ "set": _handle_set_conf,
190
+ "delete": _handle_delete_conf,
191
+ "del": _handle_delete_conf, # Alias
192
+ "rm": _handle_delete_conf, # Alias
193
+ "help": _handle_help,
194
+ }
195
+
196
+ def handle_conf_command(command_args: str, memory: Dict[str, Any]) -> str:
197
+ """
198
+ Handles the /conf command, its subcommands, and wildcard listing.
199
+
200
+ Args:
201
+ command_args: The arguments string following the /conf command.
202
+ Example: "key:value", "get key", "set key value", "*_model", "/export path"
203
+ memory: The current session memory dictionary.
204
+
205
+ Returns:
206
+ A string response to be displayed to the user.
207
+ """
208
+ conf_str = command_args.strip()
209
+
210
+ # Handle special subcommands first
211
+ if conf_str.startswith("/export"):
212
+ from autocoder.common.conf_import_export import export_conf
213
+ export_path = conf_str[len("/export"):].strip()
214
+ if not export_path:
215
+ return "Error: Please specify a path for export. Usage: /conf /export <path>"
216
+ try:
217
+ export_conf(os.getcwd(), export_path)
218
+ return f"Configuration exported successfully to {export_path}"
219
+ except Exception as e:
220
+ return f"Error exporting configuration: {e}"
221
+ elif conf_str.startswith("/import"):
222
+ from autocoder.common.conf_import_export import import_conf
223
+ import_path = conf_str[len("/import"):].strip()
224
+ if not import_path:
225
+ return "Error: Please specify a path for import. Usage: /conf /import <path>"
226
+ try:
227
+ import_conf(os.getcwd(), import_path)
228
+ # Reload memory after import might be needed depending on import_conf implementation
229
+ # load_memory() # Consider if import_conf modifies the passed memory or global state
230
+ return f"Configuration imported successfully from {import_path}. Use '/conf' to see changes."
231
+ except Exception as e:
232
+ return f"Error importing configuration: {e}"
233
+
234
+ # Handle regular commands and listing/filtering
235
+ args = conf_str.split()
236
+
237
+ if not args:
238
+ # Default action: list all configurations
239
+ return _handle_list_conf(memory, [])
240
+ else:
241
+ command = args[0].lower()
242
+ command_args_list = args[1:]
243
+
244
+ # Check if the first argument is a known command or potentially a pattern
245
+ handler = COMMAND_HANDLERS.get(command)
246
+
247
+ if handler:
248
+ # It's a known command (list, get, set, delete, help)
249
+ try:
250
+ return handler(memory, command_args_list)
251
+ except Exception as e:
252
+ return f"An unexpected error occurred while executing '/conf {command}': {e}"
253
+ elif "*" in command or "?" in command:
254
+ # Treat as a list/filter pattern if it contains wildcards and is not a known command
255
+ return _handle_list_conf(memory, [command]) # Pass the pattern as the argument to list
256
+ else:
257
+ # Handle legacy key:value format for setting (optional, can be removed if only set command is preferred)
258
+ if ":" in conf_str and len(args) == 1: # Check if it looks like key:value and is a single "word"
259
+ parts = conf_str.split(":", 1)
260
+ if len(parts) == 2:
261
+ key, value_str = parts[0].strip(), parts[1].strip()
262
+ if key and value_str:
263
+ return _handle_set_conf(memory, [key, value_str])
264
+ else:
265
+ return f"Error: Invalid key:value format in '{conf_str}'. Use '/conf set {key} {value_str}' or '/conf help'."
266
+ else:
267
+ return f"Error: Unknown command or invalid format '{conf_str}'. Type '/conf help' for available commands."
268
+ else:
269
+ # If it's not a known command, not a wildcard, and not key:value format
270
+ return f"Error: Unknown command '/conf {command}'. Type '/conf help' for available commands."