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.
- {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/METADATA +1 -1
- {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/RECORD +60 -45
- autocoder/agent/agentic_filter.py +1 -1
- autocoder/auto_coder.py +8 -0
- autocoder/auto_coder_rag.py +37 -1
- autocoder/auto_coder_runner.py +58 -77
- autocoder/chat/conf_command.py +270 -0
- autocoder/chat/models_command.py +485 -0
- autocoder/chat_auto_coder.py +29 -24
- autocoder/chat_auto_coder_lang.py +26 -2
- autocoder/commands/auto_command.py +60 -132
- autocoder/commands/auto_web.py +1 -1
- autocoder/commands/tools.py +1 -1
- autocoder/common/__init__.py +3 -1
- autocoder/common/command_completer.py +58 -12
- autocoder/common/command_completer_v2.py +576 -0
- autocoder/common/conversations/__init__.py +52 -0
- autocoder/common/conversations/compatibility.py +303 -0
- autocoder/common/conversations/conversation_manager.py +502 -0
- autocoder/common/conversations/example.py +152 -0
- autocoder/common/file_monitor/__init__.py +5 -0
- autocoder/common/file_monitor/monitor.py +383 -0
- autocoder/common/global_cancel.py +53 -16
- autocoder/common/ignorefiles/__init__.py +4 -0
- autocoder/common/ignorefiles/ignore_file_utils.py +103 -0
- autocoder/common/ignorefiles/test_ignore_file_utils.py +91 -0
- autocoder/common/rulefiles/__init__.py +15 -0
- autocoder/common/rulefiles/autocoderrules_utils.py +173 -0
- autocoder/common/save_formatted_log.py +54 -0
- autocoder/common/v2/agent/agentic_edit.py +10 -39
- autocoder/common/v2/agent/agentic_edit_tools/list_files_tool_resolver.py +1 -1
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +73 -43
- autocoder/common/v2/code_agentic_editblock_manager.py +9 -9
- autocoder/common/v2/code_diff_manager.py +2 -2
- autocoder/common/v2/code_editblock_manager.py +31 -18
- autocoder/common/v2/code_strict_diff_manager.py +3 -2
- autocoder/dispacher/actions/action.py +6 -6
- autocoder/dispacher/actions/plugins/action_regex_project.py +2 -2
- autocoder/events/event_manager_singleton.py +1 -1
- autocoder/index/index.py +3 -3
- autocoder/models.py +22 -9
- autocoder/rag/api_server.py +14 -2
- autocoder/rag/cache/local_byzer_storage_cache.py +1 -1
- autocoder/rag/cache/local_duckdb_storage_cache.py +8 -0
- autocoder/rag/cache/simple_cache.py +63 -33
- autocoder/rag/loaders/docx_loader.py +1 -1
- autocoder/rag/loaders/filter_utils.py +133 -76
- autocoder/rag/loaders/image_loader.py +15 -3
- autocoder/rag/loaders/pdf_loader.py +2 -2
- autocoder/rag/long_context_rag.py +11 -0
- autocoder/rag/qa_conversation_strategy.py +5 -31
- autocoder/rag/utils.py +21 -2
- autocoder/utils/_markitdown.py +66 -25
- autocoder/utils/auto_coder_utils/chat_stream_out.py +4 -4
- autocoder/utils/thread_utils.py +9 -27
- autocoder/version.py +1 -1
- {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.353.dist-info → auto_coder-0.1.355.dist-info}/entry_points.txt +0 -0
- {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."
|