mirror of
https://github.com/Aider-AI/aider.git
synced 2025-06-02 18:54:59 +00:00
feat: use 'cp:' prefix in model args to toggle copy-paste mode
This commit is contained in:
parent
8bc7e32fa7
commit
d2dc533de7
4 changed files with 34 additions and 28 deletions
|
@ -647,12 +647,6 @@ def get_parser(default_config_files, git_root):
|
||||||
default=False,
|
default=False,
|
||||||
help="Enable automatic copy/paste of chat between aider and web UI (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(
|
group.add_argument(
|
||||||
"--apply",
|
"--apply",
|
||||||
metavar="FILE",
|
metavar="FILE",
|
||||||
|
|
|
@ -211,9 +211,6 @@ class Coder:
|
||||||
main_model = self.main_model
|
main_model = self.main_model
|
||||||
weak_model = main_model.weak_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:
|
if weak_model is not main_model:
|
||||||
prefix = "Main model"
|
prefix = "Main model"
|
||||||
else:
|
else:
|
||||||
|
@ -221,6 +218,10 @@ class Coder:
|
||||||
|
|
||||||
output = f"{prefix}: {main_model.name} with {self.edit_format} edit format"
|
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
|
# Check for thinking token budget
|
||||||
thinking_tokens = main_model.get_thinking_tokens()
|
thinking_tokens = main_model.get_thinking_tokens()
|
||||||
if thinking_tokens:
|
if thinking_tokens:
|
||||||
|
@ -243,10 +244,18 @@ class Coder:
|
||||||
f"Editor model: {main_model.editor_model.name} with"
|
f"Editor model: {main_model.editor_model.name} with"
|
||||||
f" {main_model.editor_edit_format} edit format"
|
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)
|
lines.append(output)
|
||||||
|
|
||||||
if weak_model is not main_model:
|
if weak_model is not main_model:
|
||||||
output = f"Weak model: {weak_model.name}"
|
output = f"Weak model: {weak_model.name}"
|
||||||
|
|
||||||
|
if main_model.weak_model.copy_paste_instead_of_api:
|
||||||
|
output += ", copy paste mode"
|
||||||
|
|
||||||
lines.append(output)
|
lines.append(output)
|
||||||
|
|
||||||
# Repo
|
# Repo
|
||||||
|
@ -419,7 +428,7 @@ class Coder:
|
||||||
self.main_model.reasoning_tag if self.main_model.reasoning_tag else REASONING_TAG
|
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:
|
if cache_prompts and self.main_model.cache_control:
|
||||||
self.add_cache_headers = True
|
self.add_cache_headers = True
|
||||||
|
|
|
@ -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_model=args.editor_model,
|
||||||
editor_edit_format=args.editor_edit_format,
|
editor_edit_format=args.editor_edit_format,
|
||||||
verbose=args.verbose,
|
verbose=args.verbose,
|
||||||
copy_paste_no_api=args.copy_paste_no_api,
|
|
||||||
io=io,
|
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":
|
if args.cache_prompts and args.map_refresh == "auto":
|
||||||
args.map_refresh = "files"
|
args.map_refresh = "files"
|
||||||
|
|
||||||
if args.copy_paste_no_api:
|
|
||||||
args.stream = False
|
|
||||||
|
|
||||||
if not main_model.streaming:
|
if not main_model.streaming:
|
||||||
if args.stream:
|
if args.stream:
|
||||||
|
|
|
@ -306,7 +306,13 @@ model_info_manager = ModelInfoManager()
|
||||||
|
|
||||||
|
|
||||||
class Model(ModelSettings):
|
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
|
# Map any alias to its canonical name
|
||||||
model = MODEL_ALIASES.get(model, model)
|
model = MODEL_ALIASES.get(model, model)
|
||||||
|
|
||||||
|
@ -317,9 +323,6 @@ class Model(ModelSettings):
|
||||||
self.weak_model = None
|
self.weak_model = None
|
||||||
self.editor_model = None
|
self.editor_model = None
|
||||||
|
|
||||||
self.io = io
|
|
||||||
self.copy_paste_no_api=copy_paste_no_api
|
|
||||||
|
|
||||||
# Find the extra settings
|
# Find the extra settings
|
||||||
self.extra_model_settings = next(
|
self.extra_model_settings = next(
|
||||||
(ms for ms in MODEL_SETTINGS if ms.name == "aider/extra_params"), None
|
(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
|
# with minimum 1k and maximum 8k
|
||||||
self.max_chat_history_tokens = min(max(max_input_tokens / 16, 1024), 8192)
|
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:
|
if weak_model is False:
|
||||||
self.weak_model_name = None
|
self.weak_model_name = None
|
||||||
else:
|
else:
|
||||||
|
@ -348,10 +351,6 @@ class Model(ModelSettings):
|
||||||
else:
|
else:
|
||||||
self.get_editor_model(editor_model, editor_edit_format)
|
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):
|
def get_model_info(self, model):
|
||||||
return model_info_manager.get_model_info(model)
|
return model_info_manager.get_model_info(model)
|
||||||
|
|
||||||
|
@ -385,7 +384,7 @@ class Model(ModelSettings):
|
||||||
# If no exact match, try generic settings
|
# If no exact match, try generic settings
|
||||||
if not exact_match:
|
if not exact_match:
|
||||||
self.apply_generic_model_settings(model)
|
self.apply_generic_model_settings(model)
|
||||||
|
|
||||||
# Apply override settings last if they exist
|
# Apply override settings last if they exist
|
||||||
if (
|
if (
|
||||||
self.extra_model_settings
|
self.extra_model_settings
|
||||||
|
@ -562,6 +561,9 @@ class Model(ModelSettings):
|
||||||
# If weak_model_name is provided, override the model settings
|
# If weak_model_name is provided, override the model settings
|
||||||
if provided_weak_model_name:
|
if provided_weak_model_name:
|
||||||
self.weak_model_name = 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:
|
if not self.weak_model_name:
|
||||||
self.weak_model = self
|
self.weak_model = self
|
||||||
|
@ -575,7 +577,7 @@ class Model(ModelSettings):
|
||||||
self.weak_model_name,
|
self.weak_model_name,
|
||||||
weak_model=False,
|
weak_model=False,
|
||||||
)
|
)
|
||||||
return self.weak_model
|
return
|
||||||
|
|
||||||
def commit_message_models(self):
|
def commit_message_models(self):
|
||||||
return [self.weak_model, self]
|
return [self.weak_model, self]
|
||||||
|
@ -584,6 +586,9 @@ class Model(ModelSettings):
|
||||||
# If editor_model_name is provided, override the model settings
|
# If editor_model_name is provided, override the model settings
|
||||||
if provided_editor_model_name:
|
if provided_editor_model_name:
|
||||||
self.editor_model_name = 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:
|
if editor_edit_format:
|
||||||
self.editor_edit_format = 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/")
|
return self.name.startswith("ollama/") or self.name.startswith("ollama_chat/")
|
||||||
|
|
||||||
def send_completion(self, messages, functions, stream, temperature=None):
|
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)
|
return self.copy_paste_completion(messages)
|
||||||
|
|
||||||
if os.environ.get("AIDER_SANITY_CHECK_TURNS"):
|
if os.environ.get("AIDER_SANITY_CHECK_TURNS"):
|
||||||
|
@ -939,7 +944,8 @@ class Model(ModelSettings):
|
||||||
"""✓ Request copied to clipboard
|
"""✓ Request copied to clipboard
|
||||||
→ Paste into LLM web UI
|
→ Paste into LLM web UI
|
||||||
← Copy response back to clipboard
|
← Copy response back to clipboard
|
||||||
Monitoring clipboard for changes..."""
|
|
||||||
|
Monitoring clipboard for changes (press Ctrl+C to cancel)..."""
|
||||||
)
|
)
|
||||||
|
|
||||||
last_clipboard = pyperclip.paste()
|
last_clipboard = pyperclip.paste()
|
||||||
|
@ -1108,7 +1114,8 @@ def sanity_check_models(io, main_model):
|
||||||
def sanity_check_model(io, model):
|
def sanity_check_model(io, model):
|
||||||
show = False
|
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
|
return show
|
||||||
|
|
||||||
if model.missing_keys:
|
if model.missing_keys:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue