auto-coder 0.1.286__py3-none-any.whl → 0.1.288__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.

@@ -0,0 +1,148 @@
1
+ """
2
+ Dynamic Completion Example Plugin for Chat Auto Coder.
3
+ """
4
+
5
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
6
+ from autocoder.plugins import Plugin, PluginManager
7
+
8
+
9
+ class DynamicCompletionExamplePlugin(Plugin):
10
+ """A sample plugin demonstrating dynamic completion functionality."""
11
+
12
+ name = "dynamic_completion_example"
13
+ description = "Demonstrates the dynamic completion feature"
14
+ version = "0.1.0"
15
+
16
+ def __init__(self, manager: PluginManager, config: Optional[Dict[str, Any]] = None, config_path: Optional[str] = None):
17
+ """Initialize the plugin.
18
+
19
+ Args:
20
+ manager: The plugin manager instance
21
+ config: Optional configuration dictionary for the plugin
22
+ config_path: Optional path to the configuration file
23
+ """
24
+ super().__init__(manager, config, config_path)
25
+ self.items = ["item1", "item2", "item3", "custom_item"]
26
+
27
+ def initialize(self) -> bool:
28
+ """Initialize the plugin.
29
+
30
+ Returns:
31
+ True if initialization was successful, False otherwise
32
+ """
33
+ # Register for function interception if needed
34
+ # self.manager.register_function_interception(self.name, "ask")
35
+
36
+ # Register as a dynamic completion provider
37
+ self.manager.register_dynamic_completion_provider(self.name, ["/example"])
38
+
39
+ return True
40
+
41
+ def get_commands(self) -> Dict[str, Tuple[Callable, str]]:
42
+ """Get commands provided by this plugin.
43
+
44
+ Returns:
45
+ A dictionary of command name to handler and description
46
+ """
47
+ return {
48
+ "example": (
49
+ self.example_command,
50
+ "Example command with dynamic completion",
51
+ ),
52
+ "example/add": (self.add_item, "Add a new item to the example list"),
53
+ "example/list": (self.list_items, "List all available items"),
54
+ }
55
+
56
+ def get_completions(self) -> Dict[str, List[str]]:
57
+ """Get completions provided by this plugin.
58
+
59
+ Returns:
60
+ A dictionary mapping command prefixes to completion options
61
+ """
62
+ # 基本的静态补全选项
63
+ return {
64
+ "/example": ["add", "list", "select"],
65
+ }
66
+
67
+ def get_dynamic_completions(
68
+ self, command: str, current_input: str
69
+ ) -> List[Tuple[str, str]]:
70
+ """Get dynamic completions based on the current command context.
71
+
72
+ Args:
73
+ command: The base command (e.g., "/example select")
74
+ current_input: The full current input including the command
75
+
76
+ Returns:
77
+ A list of tuples containing (completion_text, display_text)
78
+ """
79
+ # 如果是 /example select 命令,提供动态项目列表
80
+ if current_input.startswith("/example select"):
81
+ # 提取已输入的部分项目名
82
+ parts = current_input.split(maxsplit=2)
83
+ item_prefix = ""
84
+ if len(parts) > 2:
85
+ item_prefix = parts[2]
86
+
87
+ # 返回匹配的项目
88
+ return [
89
+ (item, f"{item} (example item)")
90
+ for item in self.items
91
+ if item.startswith(item_prefix)
92
+ ]
93
+
94
+ return []
95
+
96
+ def example_command(self, args: str) -> None:
97
+ """Handle the example command.
98
+
99
+ Args:
100
+ args: Command arguments
101
+ """
102
+ if not args:
103
+ print("Usage: /example [add|list|select]")
104
+ return
105
+
106
+ parts = args.split(maxsplit=1)
107
+ subcommand = parts[0]
108
+
109
+ if subcommand == "select" and len(parts) > 1:
110
+ item = parts[1]
111
+ if item in self.items:
112
+ print(f"Selected item: {item}")
113
+ else:
114
+ print(
115
+ f"Item '{item}' not found. Use /example list to see available items."
116
+ )
117
+ else:
118
+ print(f"Unknown subcommand: {subcommand}. Use add, list, or select.")
119
+
120
+ def add_item(self, args: str) -> None:
121
+ """Add a new item to the list.
122
+
123
+ Args:
124
+ args: The item name to add
125
+ """
126
+ if not args:
127
+ print("Please specify an item name to add.")
128
+ return
129
+
130
+ if args in self.items:
131
+ print(f"Item '{args}' already exists.")
132
+ else:
133
+ self.items.append(args)
134
+ print(f"Added item: {args}")
135
+
136
+ def list_items(self, args: str) -> None:
137
+ """List all available items.
138
+
139
+ Args:
140
+ args: Ignored
141
+ """
142
+ print("Available items:")
143
+ for item in self.items:
144
+ print(f" - {item}")
145
+
146
+ def shutdown(self) -> None:
147
+ """Shutdown the plugin."""
148
+ pass
@@ -0,0 +1,252 @@
1
+ """
2
+ Git Helper Plugin for Chat Auto Coder.
3
+ Provides convenient Git commands and information display.
4
+ """
5
+
6
+ import os
7
+ import subprocess
8
+ from typing import Any, Callable, Dict, List, Optional, Tuple
9
+
10
+ from autocoder.plugins import Plugin, PluginManager
11
+
12
+
13
+ class GitHelperPlugin(Plugin):
14
+ """Git helper plugin for the Chat Auto Coder."""
15
+
16
+ name = "git_helper"
17
+ description = "Git helper plugin providing Git commands and status"
18
+ version = "0.1.0"
19
+
20
+ def __init__(self, manager: PluginManager, config: Optional[Dict[str, Any]] = None, config_path: Optional[str] = None):
21
+ """Initialize the Git helper plugin."""
22
+ super().__init__(manager, config, config_path)
23
+ self.git_available = self._check_git_available()
24
+ self.default_branch = self.config.get("default_branch", "main")
25
+
26
+ def _check_git_available(self) -> bool:
27
+ """Check if Git is available."""
28
+ try:
29
+ subprocess.run(
30
+ ["git", "--version"],
31
+ stdout=subprocess.PIPE,
32
+ stderr=subprocess.PIPE,
33
+ check=True,
34
+ )
35
+ return True
36
+ except Exception:
37
+ return False
38
+
39
+ def initialize(self) -> bool:
40
+ """Initialize the plugin.
41
+
42
+ Returns:
43
+ True if initialization was successful
44
+ """
45
+ if not self.git_available:
46
+ print(f"[{self.name}] 警告: Git不可用,某些功能受限")
47
+ return True
48
+
49
+ print(f"[{self.name}] Git助手插件已初始化")
50
+ return True
51
+
52
+ def get_commands(self) -> Dict[str, Tuple[Callable, str]]:
53
+ """Get commands provided by this plugin.
54
+
55
+ Returns:
56
+ A dictionary of command name to handler and description
57
+ """
58
+ return {
59
+ "git/status": (self.git_status, "显示Git仓库状态"),
60
+ "git/commit": (self.git_commit, "提交更改"),
61
+ "git/branch": (self.git_branch, "显示或创建分支"),
62
+ "git/checkout": (self.git_checkout, "切换分支"),
63
+ "git/diff": (self.git_diff, "显示更改差异"),
64
+ "git/log": (self.git_log, "显示提交历史"),
65
+ "git/pull": (self.git_pull, "拉取远程更改"),
66
+ "git/push": (self.git_push, "推送本地更改到远程"),
67
+ "git/reset": (self.handle_reset, "重置当前分支到指定状态 (hard/soft/mixed)"),
68
+ }
69
+
70
+ def get_completions(self) -> Dict[str, List[str]]:
71
+ """Get completions provided by this plugin.
72
+
73
+ Returns:
74
+ A dictionary mapping command prefixes to completion options
75
+ """
76
+ completions = {
77
+ "/git/status": [],
78
+ "/git/commit": [],
79
+ "/git/branch": [],
80
+ "/git/checkout": [],
81
+ "/git/diff": [],
82
+ "/git/log": [],
83
+ "/git/pull": [],
84
+ "/git/push": [],
85
+ "/git/reset": ["hard", "soft", "mixed"],
86
+ }
87
+
88
+ # 添加分支补全
89
+ if self.git_available:
90
+ try:
91
+ branches = self._get_git_branches()
92
+ completions["/git/checkout"] = branches
93
+ completions["/git/branch"] = branches + [
94
+ "--delete",
95
+ "--all",
96
+ "--remote",
97
+ "new",
98
+ ]
99
+ except Exception:
100
+ pass
101
+
102
+ return completions
103
+
104
+ def _run_git_command(self, args: List[str]) -> Tuple[int, str, str]:
105
+ """Run a Git command.
106
+
107
+ Args:
108
+ args: The command arguments
109
+
110
+ Returns:
111
+ A tuple of (return_code, stdout, stderr)
112
+ """
113
+ if not self.git_available:
114
+ return 1, "", "Git不可用"
115
+
116
+ try:
117
+ process = subprocess.run(
118
+ ["git"] + args,
119
+ stdout=subprocess.PIPE,
120
+ stderr=subprocess.PIPE,
121
+ text=True,
122
+ )
123
+ return process.returncode, process.stdout, process.stderr
124
+ except Exception as e:
125
+ return 1, "", str(e)
126
+
127
+ def _get_git_branches(self) -> List[str]:
128
+ """Get Git branches.
129
+
130
+ Returns:
131
+ A list of branch names
132
+ """
133
+ code, stdout, _ = self._run_git_command(
134
+ ["branch", "--list", "--format=%(refname:short)"]
135
+ )
136
+ if code == 0:
137
+ return [b.strip() for b in stdout.splitlines() if b.strip()]
138
+ return []
139
+
140
+ def git_status(self, args: str) -> None:
141
+ """Handle the git/status command."""
142
+ code, stdout, stderr = self._run_git_command(["status"])
143
+ if code == 0:
144
+ print(f"\n{stdout}")
145
+ else:
146
+ print(f"Error: {stderr}")
147
+
148
+ def git_commit(self, args: str) -> None:
149
+ """Handle the git/commit command."""
150
+ if not args:
151
+ print("请提供提交信息,例如: /git/commit 'Fix bug in login'")
152
+ return
153
+
154
+ # 首先执行添加所有更改 (git add .)
155
+ self._run_git_command(["add", "."])
156
+
157
+ # 执行提交
158
+ code, stdout, stderr = self._run_git_command(["commit", "-m", args])
159
+ if code == 0:
160
+ print(f"\n{stdout}")
161
+ else:
162
+ print(f"Error: {stderr}")
163
+
164
+ def git_branch(self, args: str) -> None:
165
+ """Handle the git/branch command."""
166
+ args_list = args.split() if args else []
167
+ code, stdout, stderr = self._run_git_command(["branch"] + args_list)
168
+ if code == 0:
169
+ print(f"\n{stdout}")
170
+ else:
171
+ print(f"Error: {stderr}")
172
+
173
+ def git_checkout(self, args: str) -> None:
174
+ """Handle the git/checkout command."""
175
+ if not args:
176
+ print("请提供分支名称,例如: /git/checkout main")
177
+ return
178
+
179
+ args_list = args.split()
180
+ code, stdout, stderr = self._run_git_command(["checkout"] + args_list)
181
+ if code == 0:
182
+ print(f"\n{stdout}")
183
+ else:
184
+ print(f"Error: {stderr}")
185
+
186
+ def git_diff(self, args: str) -> None:
187
+ """Handle the git/diff command."""
188
+ args_list = args.split() if args else []
189
+ code, stdout, stderr = self._run_git_command(["diff"] + args_list)
190
+ if code == 0:
191
+ if stdout:
192
+ print(f"\n{stdout}")
193
+ else:
194
+ print("没有差异")
195
+ else:
196
+ print(f"Error: {stderr}")
197
+
198
+ def git_log(self, args: str) -> None:
199
+ """Handle the git/log command."""
200
+ args_list = args.split() if args else ["--oneline", "-n", "10"]
201
+ code, stdout, stderr = self._run_git_command(["log"] + args_list)
202
+ if code == 0:
203
+ print(f"\n{stdout}")
204
+ else:
205
+ print(f"Error: {stderr}")
206
+
207
+ def git_pull(self, args: str) -> None:
208
+ """Handle the git/pull command."""
209
+ args_list = args.split() if args else []
210
+ code, stdout, stderr = self._run_git_command(["pull"] + args_list)
211
+ if code == 0:
212
+ print(f"\n{stdout}")
213
+ else:
214
+ print(f"Error: {stderr}")
215
+
216
+ def git_push(self, args: str) -> None:
217
+ """Handle the git/push command."""
218
+ args_list = args.split() if args else []
219
+ code, stdout, stderr = self._run_git_command(["push"] + args_list)
220
+ if code == 0:
221
+ print(f"\n{stdout}")
222
+ else:
223
+ print(f"Error: {stderr}")
224
+
225
+ def handle_reset(self, args: str) -> None:
226
+ """Handle the git/reset command.
227
+
228
+ Args:
229
+ args: The reset mode (hard/soft/mixed) and optional commit hash
230
+ """
231
+ if not args:
232
+ print("请提供重置模式 (hard/soft/mixed) 和可选的提交哈希")
233
+ return
234
+
235
+ args_list = args.split()
236
+ mode = args_list[0]
237
+ commit = args_list[1] if len(args_list) > 1 else "HEAD"
238
+
239
+ if mode not in ["hard", "soft", "mixed"]:
240
+ print(f"错误: 无效的重置模式 '{mode}',必须是 hard/soft/mixed 之一")
241
+ return
242
+
243
+ code, stdout, stderr = self._run_git_command(["reset", f"--{mode}", commit])
244
+ if code == 0:
245
+ print(f"\n{stdout}")
246
+ print(f"成功将仓库重置为 {mode} 模式到 {commit}")
247
+ else:
248
+ print(f"Error: {stderr}")
249
+
250
+ def shutdown(self) -> None:
251
+ """Shutdown the plugin."""
252
+ print(f"[{self.name}] Git助手插件已关闭")
@@ -0,0 +1,160 @@
1
+ """
2
+ Sample plugin demonstrating the plugin system functionality.
3
+ """
4
+
5
+ from typing import Any, Callable, Dict, List, Optional, Tuple
6
+
7
+ from prompt_toolkit.key_binding import KeyBindings
8
+ from prompt_toolkit.formatted_text import FormattedText
9
+
10
+ from autocoder.plugins import Plugin, PluginManager
11
+
12
+
13
+ class SamplePlugin(Plugin):
14
+ """A sample plugin demonstrating the plugin system functionality."""
15
+
16
+ name = "sample_plugin"
17
+ description = "A sample plugin demonstrating the plugin system features"
18
+ version = "0.1.0"
19
+
20
+ def __init__(self, manager: PluginManager, config: Optional[Dict[str, Any]] = None, config_path: Optional[str] = None):
21
+ """Initialize the sample plugin."""
22
+ super().__init__(manager, config, config_path)
23
+ self.counter = 0
24
+
25
+ def initialize(self) -> bool:
26
+ """Initialize the plugin.
27
+
28
+ Returns:
29
+ True if initialization was successful
30
+ """
31
+ print(f"[{self.name}] Initializing sample plugin")
32
+
33
+ # Register interest in intercepting functions
34
+ self.manager.register_function_interception(self.name, "ask")
35
+ self.manager.register_function_interception(self.name, "coding")
36
+
37
+ return True
38
+
39
+ def get_commands(self) -> Dict[str, Tuple[Callable, str]]:
40
+ """Get commands provided by this plugin.
41
+
42
+ Returns:
43
+ A dictionary of command name to handler and description
44
+ """
45
+ return {
46
+ "sample": (self.sample_command, "Sample plugin command"),
47
+ "counter": (self.counter_command, "Show the plugin counter"),
48
+ }
49
+
50
+ def get_keybindings(self) -> List[Tuple[str, Callable, str]]:
51
+ """Get keybindings provided by this plugin.
52
+
53
+ Returns:
54
+ A list of (key_combination, handler, description) tuples
55
+ """
56
+
57
+ def increment_counter(event):
58
+ self.counter += 1
59
+ print(f"[{self.name}] Counter incremented to {self.counter}")
60
+
61
+ return [
62
+ ("c-p", increment_counter, "Increment plugin counter"),
63
+ ]
64
+
65
+ def get_completions(self) -> Dict[str, List[str]]:
66
+ """Get completions provided by this plugin.
67
+
68
+ Returns:
69
+ A dictionary mapping command prefixes to completion options
70
+ """
71
+ return {
72
+ "/sample": ["option1", "option2", "option3"],
73
+ "/counter": ["show", "reset", "increment"],
74
+ }
75
+
76
+ def sample_command(self, args: str) -> None:
77
+ """Handle the sample command.
78
+
79
+ Args:
80
+ args: Command arguments
81
+ """
82
+ print(f"[{self.name}] Sample command executed with args: {args}")
83
+ self.counter += 1
84
+ print(f"[{self.name}] Counter incremented to {self.counter}")
85
+
86
+ def counter_command(self, args: str) -> None:
87
+ """Handle the counter command.
88
+
89
+ Args:
90
+ args: Command arguments
91
+ """
92
+ if args == "reset":
93
+ self.counter = 0
94
+ print(f"[{self.name}] Counter reset to {self.counter}")
95
+ elif args == "increment":
96
+ self.counter += 1
97
+ print(f"[{self.name}] Counter incremented to {self.counter}")
98
+ else:
99
+ print(f"[{self.name}] Current counter value: {self.counter}")
100
+
101
+ def intercept_command(
102
+ self, command: str, args: str
103
+ ) -> Tuple[bool, Optional[str], Optional[str]]:
104
+ """Intercept commands.
105
+
106
+ Args:
107
+ command: The command name (without the /)
108
+ args: The command arguments
109
+
110
+ Returns:
111
+ A tuple of (should_continue, modified_command, modified_args)
112
+ """
113
+ # Log all commands
114
+ print(f"[{self.name}] Command intercepted: /{command} {args}")
115
+
116
+ # Example: modify the 'ask' command to add a prefix
117
+ if command == "ask" and args:
118
+ return True, command, f"[From Sample Plugin] {args}"
119
+
120
+ return True, command, args
121
+
122
+ def intercept_function(
123
+ self, func_name: str, args: List[Any], kwargs: Dict[str, Any]
124
+ ) -> Tuple[bool, List[Any], Dict[str, Any]]:
125
+ """Intercept function calls.
126
+
127
+ Args:
128
+ func_name: The function name
129
+ args: The positional arguments
130
+ kwargs: The keyword arguments
131
+
132
+ Returns:
133
+ A tuple of (should_continue, modified_args, modified_kwargs)
134
+ """
135
+ print(f"[{self.name}] Function intercepted: {func_name}")
136
+
137
+ # Example: modify the 'coding' function to add a prefix to the query
138
+ if func_name == "coding" and args:
139
+ args = list(args) # Convert tuple to list for modification
140
+ if isinstance(args[0], str):
141
+ args[0] = f"[Enhanced by Sample Plugin] {args[0]}"
142
+
143
+ return True, args, kwargs
144
+
145
+ def post_function(self, func_name: str, result: Any) -> Any:
146
+ """Process function results.
147
+
148
+ Args:
149
+ func_name: The function name
150
+ result: The function result
151
+
152
+ Returns:
153
+ The possibly modified result
154
+ """
155
+ print(f"[{self.name}] Function completed: {func_name}")
156
+ return result
157
+
158
+ def shutdown(self) -> None:
159
+ """Shutdown the plugin."""
160
+ print(f"[{self.name}] Shutting down sample plugin (counter: {self.counter})")