diff --git a/aider/args.py b/aider/args.py index f9ca3c1ec..08c9bde76 100644 --- a/aider/args.py +++ b/aider/args.py @@ -647,12 +647,6 @@ def get_parser(default_config_files, git_root): default=False, help="Enable automatic copy/paste of chat between aider and web UI (default: False)", ) - group.add_argument( - "--copy-paste-no-api", - action=argparse.BooleanOptionalAction, - default=False, - help="Use automatic copy/paste of chat between aider and web UI instead of API (default: False)", - ) group.add_argument( "--apply", metavar="FILE", diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 6c7ea3586..6b43d17df 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -211,9 +211,6 @@ class Coder: main_model = self.main_model weak_model = main_model.weak_model - if main_model.copy_paste_no_api: - lines.append("Running in copy-paste mode instead of using API") - if weak_model is not main_model: prefix = "Main model" else: @@ -221,6 +218,10 @@ class Coder: output = f"{prefix}: {main_model.name} with {self.edit_format} edit format" + # Check for copy paste mode instead of api + if main_model.copy_paste_instead_of_api: + output += ", copy paste mode" + # Check for thinking token budget thinking_tokens = main_model.get_thinking_tokens() if thinking_tokens: @@ -243,10 +244,18 @@ class Coder: f"Editor model: {main_model.editor_model.name} with" f" {main_model.editor_edit_format} edit format" ) + + if main_model.editor_model.copy_paste_instead_of_api: + output += ", copy paste mode" + lines.append(output) if weak_model is not main_model: output = f"Weak model: {weak_model.name}" + + if main_model.weak_model.copy_paste_instead_of_api: + output += ", copy paste mode" + lines.append(output) # Repo @@ -419,7 +428,7 @@ class Coder: self.main_model.reasoning_tag if self.main_model.reasoning_tag else REASONING_TAG ) - self.stream = stream and main_model.streaming + self.stream = stream and main_model.streaming and not main_model.copy_paste_instead_of_api if cache_prompts and self.main_model.cache_control: self.add_cache_headers = True diff --git a/aider/main.py b/aider/main.py index c53e4cf9b..08cf0bc4e 100644 --- a/aider/main.py +++ b/aider/main.py @@ -820,7 +820,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F editor_model=args.editor_model, editor_edit_format=args.editor_edit_format, verbose=args.verbose, - copy_paste_no_api=args.copy_paste_no_api, io=io, ) @@ -949,9 +948,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.cache_prompts and args.map_refresh == "auto": args.map_refresh = "files" - - if args.copy_paste_no_api: - args.stream = False if not main_model.streaming: if args.stream: diff --git a/aider/models.py b/aider/models.py index ec01fb087..fd9972004 100644 --- a/aider/models.py +++ b/aider/models.py @@ -306,7 +306,13 @@ model_info_manager = ModelInfoManager() class Model(ModelSettings): - def __init__(self, model, weak_model=None, editor_model=None, editor_edit_format=None, verbose=False, copy_paste_no_api=False, io=None): + COPY_PASTE_PREFIX = "cp:" + + def __init__(self, model, weak_model=None, editor_model=None, editor_edit_format=None, verbose=False, io=None): + self.io = io + self.copy_paste_instead_of_api = model.startswith(self.COPY_PASTE_PREFIX) + model = model.removeprefix(self.COPY_PASTE_PREFIX) + # Map any alias to its canonical name model = MODEL_ALIASES.get(model, model) @@ -317,9 +323,6 @@ class Model(ModelSettings): self.weak_model = None self.editor_model = None - self.io = io - self.copy_paste_no_api=copy_paste_no_api - # Find the extra settings self.extra_model_settings = next( (ms for ms in MODEL_SETTINGS if ms.name == "aider/extra_params"), None @@ -337,7 +340,7 @@ class Model(ModelSettings): # with minimum 1k and maximum 8k self.max_chat_history_tokens = min(max(max_input_tokens / 16, 1024), 8192) - self.configure_model_settings(model) + self.configure_model_settings(model) if weak_model is False: self.weak_model_name = None else: @@ -348,10 +351,6 @@ class Model(ModelSettings): else: self.get_editor_model(editor_model, editor_edit_format) - if self.copy_paste_no_api: - self.weak_model = self - self.editor_model = self - def get_model_info(self, model): return model_info_manager.get_model_info(model) @@ -385,7 +384,7 @@ class Model(ModelSettings): # If no exact match, try generic settings if not exact_match: self.apply_generic_model_settings(model) - + # Apply override settings last if they exist if ( self.extra_model_settings @@ -562,6 +561,9 @@ class Model(ModelSettings): # If weak_model_name is provided, override the model settings if provided_weak_model_name: self.weak_model_name = provided_weak_model_name + elif self.copy_paste_instead_of_api: + self.weak_model = self + return if not self.weak_model_name: self.weak_model = self @@ -575,7 +577,7 @@ class Model(ModelSettings): self.weak_model_name, weak_model=False, ) - return self.weak_model + return def commit_message_models(self): return [self.weak_model, self] @@ -584,6 +586,9 @@ class Model(ModelSettings): # If editor_model_name is provided, override the model settings if provided_editor_model_name: self.editor_model_name = provided_editor_model_name + elif self.copy_paste_instead_of_api: + self.editor_model_name = self.name + if editor_edit_format: self.editor_edit_format = editor_edit_format @@ -881,7 +886,7 @@ class Model(ModelSettings): return self.name.startswith("ollama/") or self.name.startswith("ollama_chat/") def send_completion(self, messages, functions, stream, temperature=None): - if self.copy_paste_no_api: + if self.copy_paste_instead_of_api: return self.copy_paste_completion(messages) if os.environ.get("AIDER_SANITY_CHECK_TURNS"): @@ -939,7 +944,8 @@ class Model(ModelSettings): """✓ Request copied to clipboard → Paste into LLM web UI ← Copy response back to clipboard -Monitoring clipboard for changes...""" + +Monitoring clipboard for changes (press Ctrl+C to cancel)...""" ) last_clipboard = pyperclip.paste() @@ -1108,7 +1114,8 @@ def sanity_check_models(io, main_model): def sanity_check_model(io, model): show = False - if model.copy_paste_no_api: + # Skip sanity check if using copy paste mode instead of api + if model.copy_paste_instead_of_api: return show if model.missing_keys: